WooCommerce Multilingual – run WooCommerce with WPML - Version 3.8.3

Version Description

  • Added improvements to the Translation Editor for translating custom fields for products and variations
  • Added access for translator subscribers to translate content
  • Fixed compatibility issues with WooCommerce Visual Products Configurator (wrong amount in cart)
  • Fixed a compatibility issue with WooCommerce Product Addons (untranslated labels)
  • Fixed compatibility issues with WooCommerce Composite products
  • Fixed some new compatibility issues with WooCommerce Bookings
  • Bug fix: when using language as parameter and the 'dropdown' option was used for the product categories widget, translated urls were not working
  • Bug fix: shipping costs were not showing on the secondary languages in some cases
  • Bug fix: the shipping costs were not calculated correctly for currencies using less decimals than the default currency
  • Bug fix: adding a product to the cart and then adding its translation too could lead to a fatal error
  • Bug fix: switching the language on the cart page when using different domains for different languages was emptying the cart
  • Bug fix: minimum required amount was not calculated correctly for secondary currencies
  • Bug fix: incorrect currency symbol was displayed on the 'Filter by Price' widget
Download this release

Release Info

Developer mihaimihai
Plugin Icon 128x128 WooCommerce Multilingual – run WooCommerce with WPML
Version 3.8.3
Comparing to
See all releases

Code changes from version 3.8.2 to 3.8.3

Files changed (128) hide show
  1. compatibility/class-wcml-accommodation-bookings.php +22 -12
  2. compatibility/class-wcml-bookings.php +90 -50
  3. compatibility/class-wcml-composite-products.php +155 -22
  4. compatibility/class-wcml-dynamic-pricing.php +113 -78
  5. compatibility/class-wcml-product-addons.php +244 -205
  6. compatibility/class-wcml-product-bundles.php +166 -121
  7. compatibility/class-wcml-table-rate-shipping.php +118 -62
  8. compatibility/class-wcml-vpc.php +20 -0
  9. compatibility/res/css/wcml-bookings.css +10 -9
  10. embedded/autoload.php +1 -1
  11. embedded/autoload_52.php +1 -1
  12. embedded/composer/LICENSE +1 -1
  13. embedded/composer/autoload_classmap.php +1 -0
  14. embedded/composer/autoload_real.php +24 -17
  15. embedded/composer/autoload_real_52.php +3 -3
  16. embedded/composer/autoload_static.php +158 -0
  17. embedded/composer/installed.json +37 -37
  18. embedded/composer/installers/.gitignore +3 -0
  19. embedded/composer/installers/composer.json +2 -0
  20. embedded/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php +61 -0
  21. embedded/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php +115 -0
  22. embedded/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php +83 -0
  23. embedded/composer/installers/tests/Composer/Installers/Test/DokuWikiInstallerTest.php +89 -0
  24. embedded/composer/installers/tests/Composer/Installers/Test/GravInstallerTest.php +63 -0
  25. embedded/composer/installers/tests/Composer/Installers/Test/InstallerTest.php +476 -0
  26. embedded/composer/installers/tests/Composer/Installers/Test/MediaWikiInstallerTest.php +66 -0
  27. embedded/composer/installers/tests/Composer/Installers/Test/OctoberInstallerTest.php +66 -0
  28. embedded/composer/installers/tests/Composer/Installers/Test/PimcoreInstallerTest.php +44 -0
  29. embedded/composer/installers/tests/Composer/Installers/Test/PiwikInstallerTest.php +63 -0
  30. embedded/composer/installers/tests/Composer/Installers/Test/TestCase.php +64 -0
  31. embedded/composer/installers/tests/bootstrap.php +4 -0
  32. embedded/installer/changelog.txt +0 -133
  33. embedded/installer/composer.json +0 -31
  34. embedded/installer/includes/class-installer-dependencies.php +0 -278
  35. embedded/installer/includes/class-installer-theme.php +0 -979
  36. embedded/installer/includes/installer-api.php +0 -81
  37. embedded/installer/includes/installer-upgrader-skins.php +0 -37
  38. embedded/installer/includes/installer.class.php +0 -2559
  39. embedded/installer/includes/translation-service-info.class.php +0 -35
  40. embedded/installer/installer.php +0 -22
  41. embedded/installer/loader.php +0 -151
  42. embedded/installer/locale/installer-ar.mo +0 -0
  43. embedded/installer/locale/installer-de_DE.mo +0 -0
  44. embedded/installer/locale/installer-el.mo +0 -0
  45. embedded/installer/locale/installer-es_ES.mo +0 -0
  46. embedded/installer/locale/installer-fr_FR.mo +0 -0
  47. embedded/installer/locale/installer-he_IL.mo +0 -0
  48. embedded/installer/locale/installer-it_IT.mo +0 -0
  49. embedded/installer/locale/installer-ja.mo +0 -0
  50. embedded/installer/locale/installer-ko_KR.mo +0 -0
  51. embedded/installer/locale/installer-nl_NL.mo +0 -0
  52. embedded/installer/locale/installer-pl_PL.mo +0 -0
  53. embedded/installer/locale/installer-pt_BR.mo +0 -0
  54. embedded/installer/locale/installer-pt_PT.mo +0 -0
  55. embedded/installer/locale/installer-ru_RU.mo +0 -0
  56. embedded/installer/locale/installer-sv_SE.mo +0 -0
  57. embedded/installer/locale/installer-uk_UA.mo +0 -0
  58. embedded/installer/locale/installer-vi.mo +0 -0
  59. embedded/installer/locale/installer-zh_CN.mo +0 -0
  60. embedded/installer/locale/installer-zh_TW.mo +0 -0
  61. embedded/installer/locale/orig/installer.po +0 -230
  62. embedded/installer/repositories.xml +0 -13
  63. embedded/installer/res/css/admin.css +0 -186
  64. embedded/installer/res/img/complete.png +0 -0
  65. embedded/installer/res/img/computer.png +0 -0
  66. embedded/installer/res/img/dn.gif +0 -0
  67. embedded/installer/res/img/dn2.gif +0 -0
  68. embedded/installer/res/img/globe.png +0 -0
  69. embedded/installer/res/img/icon_error.gif +0 -0
  70. embedded/installer/res/img/on.png +0 -0
  71. embedded/installer/res/img/spinner.gif +0 -0
  72. embedded/installer/res/js/admin.js +0 -403
  73. embedded/installer/res/js/iframeResizer.min.js +0 -10
  74. embedded/installer/res/js/installer_theme_install.js +0 -97
  75. embedded/installer/templates/downloads-list-compact.php +0 -80
  76. embedded/installer/templates/downloads-list.php +0 -85
  77. embedded/installer/templates/products-compact.php +0 -129
  78. embedded/installer/templates/repository-listing.php +0 -179
  79. embedded/otgs/installer/changelog.txt +139 -136
  80. embedded/otgs/installer/includes/class-installer-dependencies.php +278 -278
  81. embedded/otgs/installer/includes/class-installer-theme.php +978 -978
  82. embedded/otgs/installer/includes/installer-api.php +115 -115
  83. embedded/otgs/installer/includes/installer-upgrader-skins.php +36 -36
  84. embedded/otgs/installer/includes/installer.class.php +2560 -2559
  85. embedded/otgs/installer/includes/translation-service-info.class.php +39 -39
  86. embedded/otgs/installer/installer.php +21 -21
  87. embedded/otgs/installer/loader.php +150 -150
  88. embedded/otgs/installer/locale/orig/installer.po +230 -230
  89. embedded/otgs/installer/repositories.xml +13 -13
  90. embedded/otgs/installer/res/css/admin.css +185 -185
  91. embedded/otgs/installer/res/js/admin.js +402 -402
  92. embedded/otgs/installer/res/js/iframeResizer.min.js +10 -10
  93. embedded/otgs/installer/res/js/installer_theme_install.js +96 -96
  94. embedded/otgs/installer/templates/downloads-list-compact.php +80 -80
  95. embedded/otgs/installer/templates/downloads-list.php +85 -85
  96. embedded/otgs/installer/templates/products-compact.php +128 -128
  97. embedded/otgs/installer/templates/repository-listing.php +178 -178
  98. embedded/xrstf/composer-php52/LICENSE +19 -0
  99. embedded/xrstf/composer-php52/README.md +37 -0
  100. embedded/xrstf/composer-php52/lib/xrstf/Composer52/AutoloadGenerator.php +346 -0
  101. embedded/xrstf/composer-php52/lib/xrstf/Composer52/ClassLoader.php +271 -0
  102. embedded/xrstf/composer-php52/lib/xrstf/Composer52/Generator.php +39 -0
  103. inc/admin-menus/class-wcml-admin-menus.php +21 -6
  104. inc/admin-menus/class-wcml-setup.php +1 -0
  105. inc/class-wcml-autoloader.php +0 -72
  106. inc/class-wcml-cart.php +3 -3
  107. inc/class-wcml-compatibility.php +12 -7
  108. inc/class-wcml-emails.php +120 -35
  109. inc/class-wcml-products.php +11 -0
  110. inc/class-wcml-terms.php +1 -1
  111. inc/class-wcml-url-translation.php +22 -1
  112. inc/class-wcml-wc-gateways.php +2 -2
  113. inc/class-wcml-wc-shipping.php +2 -2
  114. inc/class-wcml-xdomain-data.php +4 -1
  115. inc/class-woocommerce-wpml.php +4 -3
  116. inc/currencies/class-wcml-multi-currency-configuration.php +4 -4
  117. inc/currencies/class-wcml-multi-currency-prices.php +5 -0
  118. inc/currencies/class-wcml-multi-currency-resources.php +6 -2
  119. inc/currencies/class-wcml-multi-currency-shipping.php +11 -38
  120. inc/currencies/class-wcml-multi-currency-ui.php +0 -5
  121. inc/installer-loader.php +3 -3
  122. inc/missing-php-functions.php +24 -0
  123. inc/translation-editor/class-wcml-editor-ui-product-job.php +82 -20
  124. inc/translation-editor/class-wcml-synchronize-product-data.php +52 -12
  125. inc/translation-editor/class-wcml-synchronize-variations-data.php +23 -14
  126. inc/wcml-core-functions.php +16 -0
  127. locale/woocommerce-multilingual-ar.po +0 -1214
  128. locale/woocommerce-multilingual-de_DE.po +0 -1034
compatibility/class-wcml-accommodation-bookings.php CHANGED
@@ -2,7 +2,14 @@
2
 
3
  class WCML_Accommodation_Bookings{
4
 
5
- function __construct(){
 
 
 
 
 
 
 
6
 
7
  add_action( 'woocommerce_accommodation_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
8
  add_action( 'woocommerce_accommodation_bookings_after_booking_pricing_override_block_cost' , array( $this, 'wcml_price_field_after_booking_pricing_override_block_cost' ), 10, 2 );
@@ -10,6 +17,8 @@ class WCML_Accommodation_Bookings{
10
 
11
  add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 2 );
12
  add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
 
 
13
  }
14
 
15
  function wcml_price_field_after_booking_base_cost( $post_id ){
@@ -25,9 +34,8 @@ class WCML_Accommodation_Bookings{
25
  }
26
 
27
  function after_bookings_pricing( $post_id ){
28
- global $woocommerce_wpml;
29
 
30
- if( $woocommerce_wpml->products->is_original_product( $post_id ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
31
 
32
  $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
33
 
@@ -51,11 +59,10 @@ class WCML_Accommodation_Bookings{
51
  }
52
 
53
  function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
54
- global $woocommerce_wpml;
55
 
56
- if( ( !$check || $woocommerce_wpml->products->is_original_product( $post_id ) ) && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
57
 
58
- $currencies = $woocommerce_wpml->multi_currency->get_currencies();
59
 
60
  $wc_currencies = get_woocommerce_currencies();
61
 
@@ -99,7 +106,6 @@ class WCML_Accommodation_Bookings{
99
  }
100
 
101
  function save_custom_costs( $post_id, $post ){
102
- global $woocommerce_wpml;
103
 
104
  $nonce = filter_input( INPUT_POST, '_wcml_custom_costs_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
105
 
@@ -109,7 +115,7 @@ class WCML_Accommodation_Bookings{
109
 
110
  if( $_POST['_wcml_custom_costs'] == 1 ){
111
 
112
- $currencies = $woocommerce_wpml->multi_currency->get_currencies();
113
 
114
  foreach( $currencies as $code => $currency ){
115
 
@@ -142,19 +148,18 @@ class WCML_Accommodation_Bookings{
142
  }
143
 
144
  function product_price_filter( $value, $object_id, $meta_key, $single ){
145
- global $woocommerce_wpml;
146
 
147
  if(
148
  get_post_type( $object_id ) == 'product' &&
149
  $meta_key == '_price' &&
150
- $woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
151
  !is_admin() &&
152
- ( $currency = $woocommerce_wpml->multi_currency->get_client_currency() ) != get_option( 'woocommerce_currency' )
153
  ) {
154
 
155
  remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
156
 
157
- $original_language = $woocommerce_wpml->products->get_original_product_language( $object_id );
158
  $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
159
 
160
  if ( get_post_meta( $original_product, '_wcml_custom_costs_status' ) ) {
@@ -168,4 +173,9 @@ class WCML_Accommodation_Bookings{
168
  return isset( $price) ? $price : $value;
169
  }
170
 
 
 
 
 
 
171
  }
2
 
3
  class WCML_Accommodation_Bookings{
4
 
5
+ /**
6
+ * @var woocommerce_wpml
7
+ */
8
+ private $woocommerce_wpml;
9
+
10
+ function __construct( &$woocommerce_wpml ){
11
+
12
+ $this->woocommerce_wpml = $woocommerce_wpml;
13
 
14
  add_action( 'woocommerce_accommodation_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
15
  add_action( 'woocommerce_accommodation_bookings_after_booking_pricing_override_block_cost' , array( $this, 'wcml_price_field_after_booking_pricing_override_block_cost' ), 10, 2 );
17
 
18
  add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 2 );
19
  add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
20
+
21
+ add_action( 'init', array( $this, 'load_assets' ), 100 );
22
  }
23
 
24
  function wcml_price_field_after_booking_base_cost( $post_id ){
34
  }
35
 
36
  function after_bookings_pricing( $post_id ){
 
37
 
38
+ if( $this->woocommerce_wpml->products->is_original_product( $post_id ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
39
 
40
  $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
41
 
59
  }
60
 
61
  function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
 
62
 
63
+ if( ( !$check || $this->woocommerce_wpml->products->is_original_product( $post_id ) ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
64
 
65
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
66
 
67
  $wc_currencies = get_woocommerce_currencies();
68
 
106
  }
107
 
108
  function save_custom_costs( $post_id, $post ){
 
109
 
110
  $nonce = filter_input( INPUT_POST, '_wcml_custom_costs_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
111
 
115
 
116
  if( $_POST['_wcml_custom_costs'] == 1 ){
117
 
118
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
119
 
120
  foreach( $currencies as $code => $currency ){
121
 
148
  }
149
 
150
  function product_price_filter( $value, $object_id, $meta_key, $single ){
 
151
 
152
  if(
153
  get_post_type( $object_id ) == 'product' &&
154
  $meta_key == '_price' &&
155
+ $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
156
  !is_admin() &&
157
+ ( $currency = $this->woocommerce_wpml->multi_currency->get_client_currency() ) != get_option( 'woocommerce_currency' )
158
  ) {
159
 
160
  remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
161
 
162
+ $original_language = $this->woocommerce_wpml->products->get_original_product_language( $object_id );
163
  $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
164
 
165
  if ( get_post_meta( $original_product, '_wcml_custom_costs_status' ) ) {
173
  return isset( $price) ? $price : $value;
174
  }
175
 
176
+ public function load_assets(){
177
+
178
+ $this->woocommerce_wpml->compatibility->bookings->load_assets( 'accommodation-booking' );
179
+ }
180
+
181
  }
compatibility/class-wcml-bookings.php CHANGED
@@ -101,6 +101,9 @@ class WCML_Bookings {
101
  //lock fields on translations pages
102
  add_filter( 'wcml_js_lock_fields_ids', array( $this, 'wcml_js_lock_fields_ids' ) );
103
  add_filter( 'wcml_after_load_lock_fields_js', array( $this, 'localize_lock_fields_js' ) );
 
 
 
104
  }
105
 
106
  if( !is_admin() || isset( $_POST['action'] ) && $_POST['action'] == 'wc_bookings_calculate_costs' ){
@@ -418,70 +421,44 @@ class WCML_Bookings {
418
 
419
  }
420
 
421
- function sync_resources( $original_product_id, $trnsl_product_id, $lang_code, $duplicate = true ){
422
- $orig_resources = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT resource_id, sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d", $original_product_id ) );
423
-
424
- $trnsl_product_resources = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT resource_id FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d", $trnsl_product_id ) );
425
-
426
- foreach ($orig_resources as $resource) {
427
 
428
- $trns_resource_id = apply_filters( 'translate_object_id', $resource->resource_id, 'bookable_resource', false, $lang_code );
 
 
429
 
430
- if ( !is_null( $trns_resource_id ) && in_array( $trns_resource_id, $trnsl_product_resources ) ) {
 
 
431
 
432
- if ( ( $key = array_search( $trns_resource_id, $trnsl_product_resources ) ) !== false ) {
433
 
434
- unset($trnsl_product_resources[$key]);
435
 
436
- $this->wpdb->update(
437
- $this->wpdb->prefix . 'wc_booking_relationships',
438
- array(
439
- 'sort_order' => $resource->sort_order
440
- ),
441
- array(
442
- 'product_id' => $trnsl_product_id,
443
- 'resource_id' => $trns_resource_id
444
- )
445
- );
446
-
447
- update_post_meta( $trns_resource_id, 'qty', get_post_meta( $resource->resource_id, 'qty', true ) );
448
- update_post_meta( $trns_resource_id, '_wc_booking_availability', get_post_meta( $resource->resource_id, '_wc_booking_availability', true ) );
449
 
 
 
 
 
450
  }
451
-
452
  } else {
453
-
454
  if( $duplicate ){
455
-
456
- $trns_resource_id = $this->duplicate_resource( $trnsl_product_id, $resource, $lang_code );
457
-
458
- }else{
459
-
460
- continue;
461
-
462
  }
463
-
464
-
465
  }
466
 
467
  }
468
 
469
- foreach ($trnsl_product_resources as $trnsl_product_resource) {
470
-
471
- $this->wpdb->delete(
472
- $this->wpdb->prefix . 'wc_booking_relationships',
473
- array(
474
- 'product_id' => $trnsl_product_id,
475
- 'resource_id' => $trnsl_product_resource
476
- )
477
- );
478
-
479
- wp_delete_post( $trnsl_product_resource );
480
-
481
  }
482
 
483
- $this->sync_resource_costs( $original_product_id, $trnsl_product_id, '_resource_base_costs', $lang_code );
484
- $this->sync_resource_costs( $original_product_id, $trnsl_product_id, '_resource_block_costs', $lang_code );
485
 
486
  }
487
 
@@ -516,6 +493,53 @@ class WCML_Bookings {
516
  return $trns_resource_id;
517
  }
518
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  function sync_persons( $original_product_id, $tr_product_id, $lang_code, $duplicate = true ){
520
  $orig_persons = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->posts} WHERE post_parent = %d AND post_type = 'bookable_person'", $original_product_id ) );
521
 
@@ -847,12 +871,12 @@ class WCML_Bookings {
847
 
848
  }
849
 
850
- function load_assets( ){
851
  global $pagenow;
852
 
853
  $product = $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ? wc_get_product( $_GET[ 'post' ] ) : false;
854
 
855
- if( ( $product && $product->product_type == 'booking' ) || $pagenow == 'post-new.php' ){
856
 
857
  wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', array(), WCML_VERSION );
858
  wp_enqueue_style( 'wcml-bookings-css' );
@@ -1842,6 +1866,22 @@ class WCML_Bookings {
1842
  return $ids;
1843
  }
1844
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1845
  /**
1846
  * @param array $currencies
1847
  * @param int $post_id
101
  //lock fields on translations pages
102
  add_filter( 'wcml_js_lock_fields_ids', array( $this, 'wcml_js_lock_fields_ids' ) );
103
  add_filter( 'wcml_after_load_lock_fields_js', array( $this, 'localize_lock_fields_js' ) );
104
+
105
+ //allow filtering resources by language
106
+ add_filter( 'get_booking_resources_args', array( $this, 'filter_get_booking_resources_args' ) );
107
  }
108
 
109
  if( !is_admin() || isset( $_POST['action'] ) && $_POST['action'] == 'wc_bookings_calculate_costs' ){
421
 
422
  }
423
 
424
+ function sync_resources( $original_product_id, $translated_product_id, $lang_code, $duplicate = true ){
 
 
 
 
 
425
 
426
+ $original_resources = $this->wpdb->get_results( $this->wpdb->prepare(
427
+ "SELECT resource_id, sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
428
+ $original_product_id ) );
429
 
430
+ $translated_resources = $this->wpdb->get_col( $this->wpdb->prepare(
431
+ "SELECT resource_id FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
432
+ $translated_product_id ) );
433
 
434
+ $used_translated_resources = array();
435
 
436
+ foreach ($original_resources as $resource) {
437
 
438
+ $translated_resource_id = apply_filters( 'translate_object_id', $resource->resource_id, 'bookable_resource', false, $lang_code );
439
+ if( !is_null( $translated_resource_id ) ){
 
 
 
 
 
 
 
 
 
 
 
440
 
441
+ if( in_array( $translated_resource_id, $translated_resources ) ){
442
+ $this->update_product_resource( $translated_product_id, $translated_resource_id, $resource );
443
+ }else{
444
+ $this->add_product_resource( $translated_product_id, $translated_resource_id, $resource );
445
  }
446
+ $used_translated_resources[] = $translated_resource_id;
447
  } else {
 
448
  if( $duplicate ){
449
+ $this->duplicate_resource( $translated_product_id, $resource, $lang_code );
 
 
 
 
 
 
450
  }
 
 
451
  }
452
 
453
  }
454
 
455
+ $removed_translated_resources_id = array_diff( $translated_resources, $used_translated_resources);
456
+ foreach ( $removed_translated_resources_id as $resource_id ){
457
+ $this->remove_resource_from_product( $translated_product_id, $resource_id );
 
 
 
 
 
 
 
 
 
458
  }
459
 
460
+ $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_base_costs', $lang_code );
461
+ $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_block_costs', $lang_code );
462
 
463
  }
464
 
493
  return $trns_resource_id;
494
  }
495
 
496
+ public function add_product_resource( $product_id, $resource_id, $resource_data ){
497
+
498
+ $this->wpdb->insert(
499
+ $this->wpdb->prefix . 'wc_booking_relationships',
500
+ array(
501
+ 'sort_order' => $resource_data->sort_order,
502
+ 'product_id' => $product_id,
503
+ 'resource_id' => $resource_id
504
+ )
505
+ );
506
+
507
+ update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
508
+ update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
509
+
510
+ }
511
+
512
+ public function remove_resource_from_product( $product_id, $resource_id ){
513
+
514
+ $this->wpdb->delete(
515
+ $this->wpdb->prefix . 'wc_booking_relationships',
516
+ array(
517
+ 'product_id' => $product_id,
518
+ 'resource_id' => $resource_id
519
+ )
520
+ );
521
+
522
+ }
523
+
524
+ public function update_product_resource( $product_id, $resource_id, $resource_data ){
525
+
526
+ $this->wpdb->update(
527
+ $this->wpdb->prefix . 'wc_booking_relationships',
528
+ array(
529
+ 'sort_order' => $resource_data->sort_order
530
+ ),
531
+ array(
532
+ 'product_id' => $product_id,
533
+ 'resource_id' => $resource_id
534
+ )
535
+ );
536
+
537
+ update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
538
+ update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
539
+
540
+
541
+ }
542
+
543
  function sync_persons( $original_product_id, $tr_product_id, $lang_code, $duplicate = true ){
544
  $orig_persons = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->posts} WHERE post_parent = %d AND post_type = 'bookable_person'", $original_product_id ) );
545
 
871
 
872
  }
873
 
874
+ function load_assets( $external_product_type = false ){
875
  global $pagenow;
876
 
877
  $product = $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ? wc_get_product( $_GET[ 'post' ] ) : false;
878
 
879
+ if( ( $product && ( $product->product_type == 'booking' || $product->product_type == $external_product_type ) ) || $pagenow == 'post-new.php' ){
880
 
881
  wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', array(), WCML_VERSION );
882
  wp_enqueue_style( 'wcml-bookings-css' );
1866
  return $ids;
1867
  }
1868
 
1869
+ /**
1870
+ * @param array $args
1871
+ *
1872
+ * @return array
1873
+ */
1874
+ public function filter_get_booking_resources_args( $args ){
1875
+
1876
+ $screen = get_current_screen();
1877
+ if( $screen->id == 'product' ){
1878
+ $args['suppress_filters'] = false;
1879
+ }
1880
+
1881
+ return $args;
1882
+
1883
+ }
1884
+
1885
  /**
1886
  * @param array $currencies
1887
  * @param int $post_id
compatibility/class-wcml-composite-products.php CHANGED
@@ -3,9 +3,22 @@
3
 
4
  class WCML_Composite_Products extends WCML_Compatibility_Helper{
5
 
 
 
 
 
 
 
 
 
 
 
6
  private $tp;
7
 
8
- function __construct() {
 
 
 
9
  add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
10
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
11
  add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
@@ -15,7 +28,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
15
 
16
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
17
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
18
- add_action( 'wcml_update_extra_fields', array( $this, 'components_update' ), 10, 3 );
19
  add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
20
 
21
  $this->tp = new WPML_Element_Translation_Package();
@@ -61,22 +74,19 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
61
  }
62
 
63
  function sync_composite_data_across_translations( $original_product_id, $current_product_id ){
64
- global $woocommerce_wpml, $sitepress;
65
 
66
  if( $this->get_product_type( $original_product_id ) == 'composite' ){
67
 
68
- $product = new WC_Product_Composite( $original_product_id );
69
- $composite_data = $product->get_composite_data();
70
 
71
- $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
72
- $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
73
 
74
  foreach ( $product_translations as $product_translation ) {
75
 
76
  if ( empty($product_translation->original) ) {
77
 
78
- $translated_product = new WC_Product_Composite( $product_translation->element_id );
79
- $translated_composite_data = $translated_product->get_composite_data();
80
 
81
  foreach ( $composite_data as $component_id => $component ) {
82
 
@@ -120,10 +130,9 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
120
 
121
  if( $this->get_product_type( $product_id ) == 'composite' ){
122
 
123
- $product = new WC_Product_Composite( $product_id );
124
- $composite_data = $product->get_composite_data();
125
 
126
- $composite_section = new WPML_Editor_UI_Field_Section( __( 'Composite Products', 'woocommerce-multilingual' ) );
127
  end( $composite_data );
128
  $last_key = key( $composite_data );
129
  $divider = true;
@@ -144,6 +153,30 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
144
  $obj->add_field( $composite_section );
145
  }
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
 
149
  }
@@ -152,8 +185,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
152
 
153
  if( $this->get_product_type( $product_id ) == 'composite' ){
154
 
155
- $product = new WC_Product_Composite( $product_id );
156
- $composite_data = $product->get_composite_data();
157
 
158
  foreach( $composite_data as $component_id => $component ) {
159
 
@@ -165,9 +197,23 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
165
 
166
  }
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  if( $translation ){
169
- $translated_product = new WC_Product_Composite( $translation->ID );
170
- $translated_composite_data = $translated_product->get_composite_data();
171
 
172
  foreach( $composite_data as $component_id => $component ){
173
 
@@ -178,6 +224,18 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
178
  isset( $translated_composite_data[$component_id]['description'] ) ? $translated_composite_data[$component_id]['description'] : '';
179
 
180
  }
 
 
 
 
 
 
 
 
 
 
 
 
181
  }
182
 
183
  }
@@ -185,11 +243,9 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
185
  return $data;
186
  }
187
 
188
- function components_update( $original_product_id, $product_id, $data ){
189
-
190
- $product = new WC_Product_Composite( $original_product_id );
191
 
192
- $composite_data = $product->get_composite_data();
193
 
194
  foreach( $composite_data as $component_id => $component ) {
195
 
@@ -201,11 +257,79 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
201
  $composite_data[$component_id]['description'] = $data[ md5( 'composite_'.$component_id.'_description' ) ];
202
  }
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  }
205
 
206
  update_post_meta( $product_id, '_bto_data', $composite_data );
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
 
 
 
 
 
209
  }
210
 
211
  function append_composite_data_translation_package( $package, $post ){
@@ -333,14 +457,23 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
333
  }
334
 
335
  function woocommerce_json_search_found_products( $found_products ){
336
- global $wpml_post_translations, $sitepress;
337
 
338
  foreach( $found_products as $id => $product_name ){
339
- if( $wpml_post_translations->get_element_lang_code ( $id ) != $sitepress->get_current_language() ){
340
  unset( $found_products[ $id ] );
341
  }
342
  }
343
 
344
  return $found_products;
345
  }
 
 
 
 
 
 
 
 
 
346
  }
3
 
4
  class WCML_Composite_Products extends WCML_Compatibility_Helper{
5
 
6
+ /**
7
+ * @var SitePress
8
+ */
9
+ public $sitepress;
10
+
11
+ /**
12
+ * @var woocommerce_wpml
13
+ */
14
+ public $woocommerce_wpml;
15
+
16
  private $tp;
17
 
18
+ function __construct( &$sitepress, &$woocommerce_wpml ) {
19
+ $this->sitepress = $sitepress;
20
+ $this->woocommerce_wpml = $woocommerce_wpml;
21
+
22
  add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
23
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
24
  add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
28
 
29
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
30
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
31
+ add_action( 'wcml_update_extra_fields', array( $this, 'components_update' ), 10, 4 );
32
  add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
33
 
34
  $this->tp = new WPML_Element_Translation_Package();
74
  }
75
 
76
  function sync_composite_data_across_translations( $original_product_id, $current_product_id ){
 
77
 
78
  if( $this->get_product_type( $original_product_id ) == 'composite' ){
79
 
80
+ $composite_data = $this->get_composite_data( $original_product_id );
 
81
 
82
+ $product_trid = $this->sitepress->get_element_trid( $original_product_id, 'post_product' );
83
+ $product_translations = $this->sitepress->get_element_translations( $product_trid, 'post_product' );
84
 
85
  foreach ( $product_translations as $product_translation ) {
86
 
87
  if ( empty($product_translation->original) ) {
88
 
89
+ $translated_composite_data = $this->get_composite_data( $product_translation->element_id );
 
90
 
91
  foreach ( $composite_data as $component_id => $component ) {
92
 
130
 
131
  if( $this->get_product_type( $product_id ) == 'composite' ){
132
 
133
+ $composite_data = $this->get_composite_data( $product_id );
 
134
 
135
+ $composite_section = new WPML_Editor_UI_Field_Section( __( 'Composite Products ( Components )', 'woocommerce-multilingual' ) );
136
  end( $composite_data );
137
  $last_key = key( $composite_data );
138
  $divider = true;
153
  $obj->add_field( $composite_section );
154
  }
155
 
156
+ $composite_scenarios_meta = $this->get_composite_scenarios_meta( $product_id );
157
+ if( $composite_scenarios_meta ){
158
+
159
+ $composite_scenarios = new WPML_Editor_UI_Field_Section( __( 'Composite Products ( Scenarios )', 'woocommerce-multilingual' ) );
160
+ end( $composite_scenarios_meta );
161
+ $last_key = key( $composite_scenarios_meta );
162
+ $divider = true;
163
+ foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ) {
164
+ if( $scenario_key == $last_key ){
165
+ $divider = false;
166
+ }
167
+ $group = new WPML_Editor_UI_Field_Group( '', $divider );
168
+ $composite_scenario_field = new WPML_Editor_UI_Single_Line_Field( 'composite_scenario_'.$scenario_key.'_title', __( 'Name', 'woocommerce-multilingual' ), $data, false );
169
+ $group->add_field( $composite_scenario_field );
170
+ $composite_scenario_field = new WPML_Editor_UI_Single_Line_Field( 'composite_scenario_'.$scenario_key.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
171
+ $group->add_field( $composite_scenario_field );
172
+ $composite_scenarios->add_field( $group );
173
+
174
+ }
175
+
176
+ $obj->add_field( $composite_scenarios );
177
+
178
+ }
179
+
180
  }
181
 
182
  }
185
 
186
  if( $this->get_product_type( $product_id ) == 'composite' ){
187
 
188
+ $composite_data = $this->get_composite_data( $product_id );
 
189
 
190
  foreach( $composite_data as $component_id => $component ) {
191
 
197
 
198
  }
199
 
200
+ $composite_scenarios_meta = $this->get_composite_scenarios_meta( $product_id );
201
+ if( $composite_scenarios_meta ){
202
+ foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ){
203
+ $data[ 'composite_scenario_'.$scenario_key.'_title' ] = array(
204
+ 'original' => isset( $scenario_meta['title'] ) ? $scenario_meta['title'] : '',
205
+ 'translation' => ''
206
+ );
207
+
208
+ $data[ 'composite_scenario_'.$scenario_key.'_description' ] = array(
209
+ 'original' => isset( $scenario_meta['description'] ) ? $scenario_meta['description'] : '',
210
+ 'translation' => ''
211
+ );
212
+ }
213
+ }
214
+
215
  if( $translation ){
216
+ $translated_composite_data = $this->get_composite_data( $translation->ID );
 
217
 
218
  foreach( $composite_data as $component_id => $component ){
219
 
224
  isset( $translated_composite_data[$component_id]['description'] ) ? $translated_composite_data[$component_id]['description'] : '';
225
 
226
  }
227
+
228
+ $translated_composite_scenarios_meta = $this->get_composite_scenarios_meta( $translation->ID );
229
+ if( $translated_composite_scenarios_meta ){
230
+ foreach( $translated_composite_scenarios_meta as $scenario_key => $translated_scenario_meta ){
231
+ $data[ 'composite_scenario_'.$scenario_key.'_title' ][ 'translation' ] =
232
+ isset( $translated_scenario_meta['title'] ) ? $translated_scenario_meta['title'] : '';
233
+
234
+ $data[ 'composite_scenario_'.$scenario_key.'_description' ][ 'translation' ] =
235
+ isset( $translated_scenario_meta['description'] ) ? $translated_scenario_meta['description'] : '';
236
+ }
237
+ }
238
+
239
  }
240
 
241
  }
243
  return $data;
244
  }
245
 
246
+ function components_update( $original_product_id, $product_id, $data, $language ){
 
 
247
 
248
+ $composite_data = $this->get_composite_data( $original_product_id );
249
 
250
  foreach( $composite_data as $component_id => $component ) {
251
 
257
  $composite_data[$component_id]['description'] = $data[ md5( 'composite_'.$component_id.'_description' ) ];
258
  }
259
 
260
+ //sync product ids
261
+ if( $component[ 'query_type' ] == 'product_ids' ){
262
+ foreach( $component[ 'assigned_ids' ] as $key => $assigned_id ){
263
+ $assigned_id_current_language = apply_filters( 'translate_object_id', $assigned_id, get_post_type( $assigned_id ), false, $language );
264
+ if( $assigned_id_current_language ){
265
+ $composite_data[ $component_id ][ 'assigned_ids' ][ $key ] = $assigned_id_current_language;
266
+ }
267
+ }
268
+ //sync default
269
+ if( $component[ 'default_id' ] ){
270
+ $trnsl_default_id = apply_filters( 'translate_object_id', $component[ 'default_id' ], get_post_type( $component[ 'default_id' ] ), false, $language );
271
+ if( $trnsl_default_id ){
272
+ $composite_data[ $component_id ][ 'default_id' ] = $trnsl_default_id;
273
+ }
274
+ }
275
+
276
+ }elseif( $component[ 'query_type' ] == 'category_ids' ){
277
+ foreach( $component[ 'assigned_category_ids' ] as $key => $assigned_id ){
278
+ $trsl_term_id = apply_filters( 'translate_object_id', $assigned_id, 'product_cat', false, $language );
279
+ if( $trsl_term_id ){
280
+ $composite_data[ $component_id ][ 'assigned_category_ids' ][ $key ] = $trsl_term_id;
281
+ }
282
+ }
283
+ //sync default
284
+ if( $component[ 'default_id' ] ){
285
+ $trnsl_default_id = apply_filters( 'translate_object_id', $component[ 'default_id' ], 'product_cat', false, $language );
286
+ if( $trnsl_default_id ){
287
+ $composite_data[ $component_id ][ 'default_id' ] = $trnsl_default_id;
288
+ }
289
+ }
290
+ }
291
  }
292
 
293
  update_post_meta( $product_id, '_bto_data', $composite_data );
294
 
295
+ $composite_scenarios_meta = $this->get_composite_scenarios_meta( $original_product_id );
296
+ if( $composite_scenarios_meta ){
297
+ foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ){
298
+ if( !empty( $data[ md5( 'composite_scenario_'.$scenario_key.'_title' ) ] ) ){
299
+ $composite_scenarios_meta[ $scenario_key ][ 'title' ] = $data[ md5( 'composite_scenario_'.$scenario_key.'_title' ) ];
300
+ }
301
+
302
+ if( !empty( $data[ md5( 'composite_scenario_'.$scenario_key.'_description' ) ])) {
303
+ $composite_scenarios_meta[ $scenario_key ][ 'description' ] = $data[ md5( 'composite_scenario_'.$scenario_key.'_description' ) ];
304
+ }
305
+
306
+ //sync product ids
307
+ foreach( $scenario_meta[ 'component_data' ] as $compon_id => $component_data ){
308
+ if( isset( $composite_data[ $compon_id ] ) && $composite_data[ $compon_id ][ 'query_type' ] == 'product_ids' ){
309
+ foreach( $component_data as $key => $assigned_prod_id ){
310
+ $trnsl_assigned_prod_id = apply_filters( 'translate_object_id', $assigned_prod_id, get_post_type( $assigned_prod_id ), false, $language );
311
+ if( $trnsl_assigned_prod_id ){
312
+ $composite_scenarios_meta[ $scenario_key ][ 'component_data' ][ $compon_id ][ $key ] = $trnsl_assigned_prod_id;
313
+ }
314
+ }
315
+ }elseif( isset( $composite_data[ $compon_id ] ) && $composite_data[ $compon_id ][ 'query_type' ] == 'category_ids' ){
316
+ foreach( $component_data as $key => $assigned_cat_id ){
317
+ $trslt_assigned_cat_id = apply_filters( 'translate_object_id', $assigned_cat_id, 'product_cat', false, $language );
318
+ if( $trslt_assigned_cat_id ){
319
+ $composite_scenarios_meta[ $scenario_key ][ 'component_data' ][ $compon_id ][ $key ] = $trslt_assigned_cat_id;
320
+ }
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+
327
+ update_post_meta( $product_id, '_bto_scenario_data', $composite_scenarios_meta );
328
 
329
+ return array(
330
+ 'components' => $composite_data,
331
+ 'scenarios' => $composite_scenarios_meta,
332
+ );
333
  }
334
 
335
  function append_composite_data_translation_package( $package, $post ){
457
  }
458
 
459
  function woocommerce_json_search_found_products( $found_products ){
460
+ global $wpml_post_translations;
461
 
462
  foreach( $found_products as $id => $product_name ){
463
+ if( $wpml_post_translations->get_element_lang_code ( $id ) != $this->sitepress->get_current_language() ){
464
  unset( $found_products[ $id ] );
465
  }
466
  }
467
 
468
  return $found_products;
469
  }
470
+
471
+ public function get_composite_scenarios_meta( $product_id ){
472
+ return get_post_meta( $product_id, '_bto_scenario_data', true );
473
+ }
474
+
475
+ public function get_composite_data( $product_id ){
476
+ return get_post_meta( $product_id, '_bto_data', true );
477
+ }
478
+
479
  }
compatibility/class-wcml-dynamic-pricing.php CHANGED
@@ -1,81 +1,116 @@
1
  <?php
2
 
3
- class WCML_Dynamic_Pricing{
4
-
5
- function __construct(){
6
- if(!is_admin()){
7
- add_filter('wc_dynamic_pricing_load_modules', array($this, 'filter_price'));
8
- add_filter('woocommerce_dynamic_pricing_is_applied_to', array($this, 'woocommerce_dynamic_pricing_is_applied_to'),10,5);
9
- add_filter('woocommerce_dynamic_pricing_get_rule_amount',array($this,'woocommerce_dynamic_pricing_get_rule_amount'),10,4);
10
- add_filter('dynamic_pricing_product_rules',array($this,'dynamic_pricing_product_rules'));
11
- add_filter('wcml_calculate_totals_exception', array($this, 'calculate_totals_exception'));
12
-
13
- }
14
- }
15
-
16
- function filter_price($modules){
17
-
18
- foreach($modules as $mod_key=>$module){
19
- if(isset($module->available_rulesets)){
20
- $available_rulesets = $module->available_rulesets;
21
- foreach($available_rulesets as $rule_key=>$available_ruleset){
22
- $rules = $available_ruleset['rules'];
23
-
24
- if($rules){
25
- foreach($rules as $r_key=>$rule){
26
- if($rule['type'] == 'fixed_product'){
27
- $rules[$r_key]['amount'] = apply_filters('wcml_raw_price_amount', $rule['amount']);
28
- }
29
- }
30
- $modules[$mod_key]->available_rulesets[$rule_key]['rules'] = $rules;
31
-
32
- }
33
- }
34
-
35
- }
36
- }
37
-
38
- return $modules;
39
- }
40
-
41
-
42
- function woocommerce_dynamic_pricing_is_applied_to($process_discounts, $_product, $module_id, $obj,$cat_id){
43
- if($cat_id && isset($obj->available_rulesets) && count($obj->available_rulesets) > 0){
44
- global $sitepress;
45
- $cat_id = apply_filters( 'translate_object_id',$cat_id,'product_cat',true,$sitepress->get_current_language());
46
- $process_discounts = is_object_in_term($_product->id, 'product_cat', $cat_id);
47
- }
48
-
49
- return $process_discounts;
50
- }
51
-
52
-
53
- function woocommerce_dynamic_pricing_get_rule_amount($amount, $rule, $cart_item, $obj){
54
-
55
- if($rule['type'] == 'price_discount' || $rule['type'] == 'fixed_price'){
56
- $amount = apply_filters('wcml_raw_price_amount',$amount);
57
- }
58
-
59
- return $amount;
60
-
61
- }
62
-
63
-
64
- function dynamic_pricing_product_rules($rules){
65
- if(is_array($rules)){
66
- foreach($rules as $r_key=>$rule){
67
- foreach($rule['rules'] as $key=>$product_rule){
68
- if($product_rule['type'] == 'price_discount' || $product_rule['type'] == 'fixed_price'){
69
- $rules[$r_key]['rules'][$key]['amount'] = apply_filters('wcml_raw_price_amount', $product_rule['amount']);
70
- }
71
- }
72
- }
73
- }
74
- return $rules;
75
- }
76
-
77
- function calculate_totals_exception( ){
78
- return false;
79
- }
80
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
1
  <?php
2
 
3
+ /**
4
+ * Class WCML_Dynamic_Pricing
5
+ */
6
+ class WCML_Dynamic_Pricing {
7
+
8
+ /**
9
+ * @var SitePress
10
+ */
11
+ public $sitepress;
12
+
13
+ /**
14
+ * WCML_Dynamic_Pricing constructor.
15
+ *
16
+ * @param $sitepress
17
+ */
18
+ function __construct( &$sitepress ) {
19
+ if ( ! is_admin() ) {
20
+ $this->sitepress = $sitepress;
21
+ add_filter( 'wc_dynamic_pricing_load_modules', array( $this, 'filter_price' ) );
22
+ add_filter( 'woocommerce_dynamic_pricing_is_applied_to', array( $this, 'woocommerce_dynamic_pricing_is_applied_to' ), 10, 5 );
23
+ add_filter( 'woocommerce_dynamic_pricing_get_rule_amount', array( $this, 'woocommerce_dynamic_pricing_get_rule_amount' ), 10, 2 );
24
+ add_filter( 'dynamic_pricing_product_rules', array( $this, 'dynamic_pricing_product_rules' ) );
25
+ add_filter( 'wcml_calculate_totals_exception', array( $this, 'calculate_totals_exception' ) );
26
+ }
27
+ }
28
+
29
+ /**
30
+ * @param $modules
31
+ *
32
+ * @return mixed
33
+ */
34
+ function filter_price( $modules ) {
35
+
36
+ foreach ( $modules as $mod_key => $module ) {
37
+ if ( isset( $module->available_rulesets ) ) {
38
+ $available_rulesets = $module->available_rulesets;
39
+ foreach ( $available_rulesets as $rule_key => $available_ruleset ) {
40
+ $rules = $available_ruleset['rules'];
41
+ if ( $rules ) {
42
+ foreach ( $rules as $r_key => $rule ) {
43
+ if ( 'fixed_product' === $rule['type'] ) {
44
+ $rules[ $r_key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $rule['amount'] );
45
+ }
46
+ }
47
+ $modules[ $mod_key ]->available_rulesets[ $rule_key ]['rules'] = $rules;
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ return $modules;
54
+ }
55
+
56
+
57
+ /**
58
+ * @param $process_discounts
59
+ * @param $_product
60
+ * @param $module_id
61
+ * @param $obj
62
+ * @param $cat_id
63
+ *
64
+ * @return bool|WP_Error
65
+ */
66
+ function woocommerce_dynamic_pricing_is_applied_to( $process_discounts, $_product, $module_id, $obj, $cat_id ) {
67
+ if ( $cat_id && isset( $obj->available_rulesets ) && count( $obj->available_rulesets ) > 0 ) {
68
+ $cat_id = apply_filters( 'translate_object_id', $cat_id, 'product_cat', true, $this->sitepress->get_current_language() );
69
+ $process_discounts = is_object_in_term( $_product->id, 'product_cat', $cat_id );
70
+ }
71
+
72
+ return $process_discounts;
73
+ }
74
+
75
+
76
+ /**
77
+ * @param $amount
78
+ * @param $rule
79
+ *
80
+ * @return mixed|void
81
+ */
82
+ function woocommerce_dynamic_pricing_get_rule_amount( $amount, $rule ) {
83
+
84
+ if ( 'price_discount' === $rule['type'] || 'fixed_price' === $rule['type'] ) {
85
+ $amount = apply_filters( 'wcml_raw_price_amount', $amount );
86
+ }
87
+
88
+ return $amount;
89
+ }
90
+
91
+
92
+ /**
93
+ * @param $rules
94
+ *
95
+ * @return array
96
+ */
97
+ function dynamic_pricing_product_rules( $rules ) {
98
+ if ( is_array( $rules ) ) {
99
+ foreach ( $rules as $r_key => $rule ) {
100
+ foreach ( $rule['rules'] as $key => $product_rule ) {
101
+ if ( 'price_discount' === $product_rule['type'] || 'fixed_price' === $product_rule['type'] ) {
102
+ $rules[ $r_key ]['rules'][ $key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $product_rule['amount'] );
103
+ }
104
+ }
105
+ }
106
+ }
107
+ return $rules;
108
+ }
109
+
110
+ /**
111
+ * @return bool
112
+ */
113
+ function calculate_totals_exception() {
114
+ return false;
115
+ }
116
  }
compatibility/class-wcml-product-addons.php CHANGED
@@ -1,208 +1,247 @@
1
  <?php
2
 
3
- class WCML_Product_Addons{
4
-
5
- function __construct(){
6
-
7
- add_filter( 'get_product_addons_product_terms', array( $this, 'addons_product_terms' ) );
8
- add_filter( 'get_product_addons_fields', array( $this, 'product_addons_filter'), 10, 2 );
9
-
10
- add_action( 'updated_post_meta', array( $this, 'register_addons_strings' ), 10 ,4 );
11
- add_action( 'added_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
12
- add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
13
-
14
- global $pagenow;
15
- if( $pagenow == 'edit.php' &&
16
- isset( $_GET[ 'post_type' ] ) &&
17
- $_GET[ 'post_type' ]=='product' &&
18
- isset( $_GET[ 'page' ] ) &&
19
- $_GET[ 'page' ]=='global_addons' &&
20
- !isset( $_GET[ 'edit' ] )
21
- ){
22
- add_action( 'admin_notices', array( $this, 'inf_translate_strings' ) );
23
- }
24
-
25
- add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
26
-
27
- if( is_admin() ) {
28
-
29
- add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
30
- add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
31
- add_action( 'wcml_update_extra_fields', array( $this,'addons_update' ), 10, 3 );
32
- }
33
- }
34
-
35
- function register_addons_strings( $meta_id, $id, $meta_key, $addons){
36
- if( $meta_key == '_product_addons' && get_post_type( $id ) == 'global_product_addon') {
37
- foreach ($addons as $addon) {
38
- //register name
39
- do_action('wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name', $addon['name']);
40
- //register description
41
- do_action('wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_description', $addon['description']);
42
- //register options labels
43
- foreach ($addon['options'] as $key => $option) {
44
- do_action('wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_option_label_' . $key, $option['label']);
45
- }
46
- }
47
- }
48
- }
49
-
50
- function translate_addons_strings( $null, $object_id, $meta_key, $single ){
51
-
52
- if( $meta_key == '_product_addons' && get_post_type( $object_id ) == 'global_product_addon' ){
53
-
54
- remove_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
55
- $addons = get_post_meta( $object_id, $meta_key, true);
56
- add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
57
-
58
- foreach ($addons as $key => $addon) {
59
- //register name
60
- $addons[ $key ][ 'name' ] = apply_filters( 'wpml_translate_single_string', $addon['name'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name' );
61
- //register description
62
- $addons[ $key ][ 'description' ] = apply_filters( 'wpml_translate_single_string', $addon['description'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_description' );
63
- //register options labels
64
- foreach ($addon['options'] as $opt_key => $option) {
65
- $addons[ $key ][ 'options' ][ $opt_key ][ 'label' ] = apply_filters( 'wpml_translate_single_string', $option['label'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_option_label_' . $key );
66
- }
67
- }
68
-
69
- return array( 0 => $addons );
70
- }
71
-
72
- return $null;
73
-
74
- }
75
-
76
- function product_addons_filter($addons, $object_id){
77
-
78
- foreach($addons as $add_id => $addon){
79
- foreach($addon['options'] as $key=>$option){
80
- //price filter
81
- $addons[$add_id]['options'][$key]['price'] = apply_filters('wcml_raw_price_amount', $option['price']);
82
- }
83
- }
84
-
85
- return $addons;
86
- }
87
-
88
-
89
- function addons_product_terms($product_terms){
90
- global $sitepress;
91
-
92
- foreach($product_terms as $key => $product_term){
93
- $product_terms[$key] = apply_filters( 'translate_object_id',$product_term,'product_cat',true,$sitepress->get_default_language());
94
- }
95
-
96
- return $product_terms;
97
- }
98
-
99
- function inf_translate_strings(){
100
- $message = '<div><p class="icl_cyan_box">';
101
- $message .= sprintf(__('To translate Add-ons strings please save Add-ons and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_product_addons_strings'));
102
- $message .= '</p></div>';
103
-
104
- echo $message;
105
- }
106
-
107
- function custom_box_html( $obj, $product_id, $data ){
108
-
109
- $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
110
-
111
- if( !empty( $product_addons ) ){
112
-
113
- foreach( $product_addons as $addon_id => $product_addon ) {
114
-
115
- $addons_section = new WPML_Editor_UI_Field_Section( sprintf( __( 'Product Add-ons Group "%s"', 'woocommerce-multilingual' ), $product_addon['name'] ) );
116
-
117
- $group = new WPML_Editor_UI_Field_Group( '' , true );
118
- $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_name', __( 'Name', 'woocommerce-multilingual' ), $data, false );
119
- $group->add_field( $addon_field );
120
- $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
121
- $group->add_field( $addon_field );
122
-
123
- $addons_section->add_field( $group );
124
-
125
- if( !empty( $product_addon['options'] ) ){
126
-
127
- $labels_group = new WPML_Editor_UI_Field_Group( __( 'Options', 'woocommerce-multilingual' ) , true );
128
-
129
- foreach( $product_addon['options'] as $option_id => $option ){
130
-
131
- $option_label_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_option_'.$option_id.'_label', __( 'Label', 'woocommerce-multilingual' ), $data, false );
132
- $labels_group->add_field( $option_label_field );
133
-
134
- }
135
-
136
- $addons_section->add_field( $labels_group );
137
- }
138
-
139
- $obj->add_field( $addons_section );
140
-
141
- }
142
-
143
- }
144
-
145
- }
146
-
147
- function custom_box_html_data( $data, $product_id, $translation, $lang ){
148
-
149
- $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
150
-
151
- if( !empty( $product_addons ) ){
152
- foreach( $product_addons as $addon_id => $product_addon ) {
153
- $data[ 'addon_'.$addon_id.'_name' ] = array( 'original' => $product_addon[ 'name' ] );
154
- $data[ 'addon_'.$addon_id.'_description' ] = array( 'original' => $product_addon['description'] );
155
- if( !empty( $product_addon['options'] ) ){
156
- foreach( $product_addon['options'] as $option_id => $option ){
157
- $data[ 'addon_'.$addon_id.'_option_'.$option_id.'_label' ] = array( 'original' => $option[ 'label' ] );
158
- }
159
- }
160
- }
161
-
162
- if( $translation ){
163
- $transalted_product_addons = maybe_unserialize( get_post_meta( $translation->ID, '_product_addons', true ) );
164
- if( !empty( $transalted_product_addons ) ){
165
- foreach( $transalted_product_addons as $addon_id => $transalted_product_addon ) {
166
- $data[ 'addon_'.$addon_id.'_name' ][ 'translation' ] = $transalted_product_addon[ 'name' ];
167
- $data[ 'addon_'.$addon_id.'_description' ][ 'translation' ] = $transalted_product_addon['description'];
168
- if( !empty( $transalted_product_addon['options'] ) ){
169
- foreach( $transalted_product_addon['options'] as $option_id => $option ){
170
- $data[ 'addon_'.$addon_id.'_option_'.$option_id.'_label' ][ 'translation' ] = $option[ 'label' ];
171
- }
172
- }
173
- }
174
- }
175
- }
176
- }
177
-
178
- return $data;
179
- }
180
-
181
- function addons_update( $original_product_id, $product_id, $data ){
182
-
183
- $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
184
-
185
- if( !empty( $product_addons ) ){
186
-
187
- foreach( $product_addons as $addon_id => $product_addon ) {
188
-
189
- $product_addons[ $addon_id ][ 'name' ] = $data[ md5( 'addon_'.$addon_id.'_name' ) ];
190
- $product_addons[ $addon_id ][ 'description' ] = $data[ md5( 'addon_'.$addon_id.'_description' ) ];
191
-
192
- if( !empty( $product_addon['options'] ) ){
193
-
194
- foreach( $product_addon['options'] as $option_id => $option ){
195
- $product_addons[ $addon_id ]['options'][ $option_id ][ 'label' ] = $data[ md5( 'addon_'.$addon_id.'_option_'.$option_id.'_label' ) ];
196
- }
197
-
198
- }
199
-
200
- }
201
- }
202
-
203
- update_post_meta( $product_id, '_product_addons', $product_addons );
204
-
205
-
206
- }
207
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  }
1
  <?php
2
 
3
+ /**
4
+ * Class WCML_Product_Addons
5
+ */
6
+ class WCML_Product_Addons {
7
+
8
+ /**
9
+ * @var SitePress
10
+ */
11
+ public $sitepress;
12
+
13
+ /**
14
+ * WCML_Product_Addons constructor.
15
+ */
16
+ function __construct( &$sitepress ) {
17
+ $this->sitepress = $sitepress;
18
+ add_filter( 'get_product_addons_product_terms', array( $this, 'addons_product_terms' ) );
19
+ add_filter( 'get_product_addons_fields', array( $this, 'product_addons_filter' ), 10, 1 );
20
+
21
+ add_action( 'updated_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
22
+ add_action( 'added_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
23
+ add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
24
+
25
+ global $pagenow;
26
+ if ( 'edit.php' === $pagenow &&
27
+ isset( $_GET['post_type'] ) &&
28
+ 'product' === $_GET['post_type'] &&
29
+ isset( $_GET['page'] ) &&
30
+ 'global_addons' === $_GET['page'] &&
31
+ ! isset( $_GET['edit'] )
32
+ ) {
33
+ add_action( 'admin_notices', array( $this, 'inf_translate_strings' ) );
34
+ }
35
+
36
+ add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
37
+
38
+ if ( is_admin() ) {
39
+
40
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
41
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 3 );
42
+ add_action( 'wcml_update_extra_fields', array( $this, 'addons_update' ), 10, 3 );
43
+ }
44
+ }
45
+
46
+ /**
47
+ * @param $meta_id
48
+ * @param $id
49
+ * @param $meta_key
50
+ * @param $addons
51
+ */
52
+ function register_addons_strings( $meta_id, $id, $meta_key, $addons ) {
53
+ if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $id ) ) {
54
+ foreach ( $addons as $addon ) {
55
+ //register name
56
+ do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name', $addon['name'] );
57
+ //register description
58
+ do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_description', $addon['description'] );
59
+ //register options labels
60
+ foreach ( $addon['options'] as $key => $option ) {
61
+ do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_option_label_' . $key, $option['label'] );
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @param $null
69
+ * @param $object_id
70
+ * @param $meta_key
71
+ * @param $single
72
+ *
73
+ * @return array
74
+ */
75
+ function translate_addons_strings( $null, $object_id, $meta_key, $single ) {
76
+
77
+ if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $object_id ) ) {
78
+
79
+ remove_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
80
+ $addons = get_post_meta( $object_id, $meta_key, true );
81
+ add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
82
+
83
+ if ( is_array( $addons ) ) {
84
+ foreach ( $addons as $key => $addon ) {
85
+ //register name
86
+ $addons[ $key ]['name'] = apply_filters( 'wpml_translate_single_string', $addon['name'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name' );
87
+ //register description
88
+ $addons[ $key ]['description'] = apply_filters( 'wpml_translate_single_string', $addon['description'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_description' );
89
+ //register options labels
90
+ foreach ( $addon['options'] as $opt_key => $option ) {
91
+ $addons[ $key ]['options'][ $opt_key ]['label'] = apply_filters( 'wpml_translate_single_string', $option['label'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_option_label_' . $opt_key );
92
+ }
93
+ }
94
+ }
95
+
96
+ return array( 0 => $addons );
97
+ }
98
+
99
+ return $null;
100
+
101
+ }
102
+
103
+ /**
104
+ * @param $addons
105
+ *
106
+ * @return mixed
107
+ */
108
+ function product_addons_filter( $addons ) {
109
+
110
+ foreach ( $addons as $add_id => $addon ) {
111
+ foreach ( $addon['options'] as $key => $option ) {
112
+ //price filter
113
+ $addons[ $add_id ]['options'][ $key ]['price'] = apply_filters( 'wcml_raw_price_amount', $option['price'] );
114
+ }
115
+ }
116
+
117
+ return $addons;
118
+ }
119
+
120
+
121
+ /**
122
+ * @param $product_terms
123
+ *
124
+ * @return array
125
+ */
126
+ function addons_product_terms( $product_terms ) {
127
+ foreach ( $product_terms as $key => $product_term ) {
128
+ $product_terms[ $key ] = apply_filters( 'translate_object_id', $product_term, 'product_cat', true, $this->sitepress->get_default_language() );
129
+ }
130
+
131
+ return $product_terms;
132
+ }
133
+
134
+ function inf_translate_strings() {
135
+ $message = '<div><p class="icl_cyan_box">';
136
+ $message .= sprintf( __( 'To translate Add-ons strings please save Add-ons and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual' ), admin_url( 'admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_product_addons_strings' ) );
137
+ $message .= '</p></div>';
138
+
139
+ echo $message;
140
+ }
141
+
142
+ /**
143
+ * @param $obj
144
+ * @param $product_id
145
+ * @param $data
146
+ */
147
+ function custom_box_html( $obj, $product_id, $data ) {
148
+
149
+ $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
150
+
151
+ if ( ! empty( $product_addons ) ) {
152
+ foreach ( $product_addons as $addon_id => $product_addon ) {
153
+
154
+ $addons_section = new WPML_Editor_UI_Field_Section( sprintf( __( 'Product Add-ons Group "%s"', 'woocommerce-multilingual' ), $product_addon['name'] ) );
155
+
156
+ $group = new WPML_Editor_UI_Field_Group( '' , true );
157
+ $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_name', __( 'Name', 'woocommerce-multilingual' ), $data, false );
158
+ $group->add_field( $addon_field );
159
+ $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
160
+ $group->add_field( $addon_field );
161
+
162
+ $addons_section->add_field( $group );
163
+
164
+ if ( ! empty( $product_addon['options'] ) ) {
165
+
166
+ $labels_group = new WPML_Editor_UI_Field_Group( __( 'Options', 'woocommerce-multilingual' ) , true );
167
+
168
+ foreach ( $product_addon['options'] as $option_id => $option ) {
169
+ $option_label_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_option_'.$option_id.'_label', __( 'Label', 'woocommerce-multilingual' ), $data, false );
170
+ $labels_group->add_field( $option_label_field );
171
+ }
172
+ $addons_section->add_field( $labels_group );
173
+ }
174
+ $obj->add_field( $addons_section );
175
+ }
176
+ }
177
+ }
178
+
179
+ /**
180
+ * @param $data
181
+ * @param $product_id
182
+ * @param $translation
183
+ *
184
+ * @return mixed
185
+ */
186
+ function custom_box_html_data( $data, $product_id, $translation ) {
187
+
188
+ $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
189
+
190
+ if ( ! empty( $product_addons ) ) {
191
+ foreach ( $product_addons as $addon_id => $product_addon ) {
192
+ $data[ 'addon_' . $addon_id . '_name' ] = array( 'original' => $product_addon['name'] );
193
+ $data[ 'addon_' . $addon_id . '_description' ] = array( 'original' => $product_addon['description'] );
194
+ if ( ! empty( $product_addon['options'] ) ) {
195
+ foreach ( $product_addon['options'] as $option_id => $option ) {
196
+ $data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ] = array( 'original' => $option['label'] );
197
+ }
198
+ }
199
+ }
200
+
201
+ if ( $translation ) {
202
+ $transalted_product_addons = maybe_unserialize( get_post_meta( $translation->ID, '_product_addons', true ) );
203
+ if ( ! empty( $transalted_product_addons ) ) {
204
+ foreach ( $transalted_product_addons as $addon_id => $transalted_product_addon ) {
205
+ $data[ 'addon_' . $addon_id . '_name' ]['translation'] = $transalted_product_addon['name'];
206
+ $data[ 'addon_' . $addon_id . '_description' ]['translation'] = $transalted_product_addon['description'];
207
+ if ( ! empty( $transalted_product_addon['options'] ) ) {
208
+ foreach ( $transalted_product_addon['options'] as $option_id => $option ) {
209
+ $data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ]['translation'] = $option['label'];
210
+ }
211
+ }
212
+ }
213
+ }
214
+ }
215
+ }
216
+
217
+ return $data;
218
+ }
219
+
220
+ /**
221
+ * @param $original_product_id
222
+ * @param $product_id
223
+ * @param $data
224
+ */
225
+ function addons_update( $original_product_id, $product_id, $data ) {
226
+
227
+ $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
228
+
229
+ if ( ! empty( $product_addons ) ) {
230
+
231
+ foreach ( $product_addons as $addon_id => $product_addon ) {
232
+
233
+ $product_addons[ $addon_id ]['name'] = $data[ md5( 'addon_' . $addon_id . '_name' ) ];
234
+ $product_addons[ $addon_id ]['description'] = $data[ md5( 'addon_' . $addon_id . '_description' ) ];
235
+
236
+ if ( ! empty( $product_addon['options'] ) ) {
237
+
238
+ foreach ( $product_addon['options'] as $option_id => $option ) {
239
+ $product_addons[ $addon_id ]['options'][ $option_id ]['label'] = $data[ md5( 'addon_'.$addon_id.'_option_'.$option_id.'_label' ) ];
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ update_post_meta( $product_id, '_product_addons', $product_addons );
246
+ }
247
  }
compatibility/class-wcml-product-bundles.php CHANGED
@@ -1,19 +1,37 @@
1
  <?php
2
  class WCML_Product_Bundles{
3
 
 
 
 
4
  var $tp;
5
 
6
- function __construct(){
7
-
8
- add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html'), 10, 3 );
9
- add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data'), 10, 4 );
10
- add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
11
- add_action('wcml_update_extra_fields',array($this,'bundle_update'),10,4);
12
- add_action('woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle'),5,3);
13
- add_filter('woocommerce_cart_loaded_from_session', array($this, 'resync_bundle_clean'),10);
14
-
15
- if( version_compare( WCML_VERSION, '3.7.2', '>') ){
16
- add_filter( 'option_wpml_config_files_arr', array($this, 'make__bundle_data_not_translatable_by_default'), 0 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
  if( is_admin() ){
@@ -24,91 +42,109 @@ class WCML_Product_Bundles{
24
 
25
  }
26
 
 
27
  }
28
 
29
- function make__bundle_data_not_translatable_by_default($wpml_config_array){
30
 
31
- if( isset( $wpml_config_array->plugins['WooCommerce Product Bundles'] ) ){
32
- $wpml_config_array->plugins['WooCommerce Product Bundles'] =
33
- str_replace('<custom-field action="translate">_bundle_data</custom-field>', '<custom-field action="nothing">_bundle_data</custom-field>', $wpml_config_array->plugins['WooCommerce Product Bundles']);
 
 
 
34
  }
35
 
36
  return $wpml_config_array;
37
  }
38
 
39
  // Sync Bundled product '_bundle_data' with translated values when the product is duplicated
40
- function sync_bundled_ids($original_product_id, $trnsl_product_id, $data = false){
41
- global $sitepress;
42
- $atts = maybe_unserialize(get_post_meta($original_product_id, '_bundle_data', true));
43
- if( $atts ){
44
- $lang = $sitepress->get_language_for_element($trnsl_product_id,'post_product');
45
- $tr_bundle_meta = maybe_unserialize(get_post_meta($trnsl_product_id, '_bundle_data', true));
46
  $tr_ids = array();
47
  $i = 2;
48
- foreach($atts as $id=>$bundle_data){
49
- $tr_id = apply_filters( 'translate_object_id',$id,get_post_type($id),true,$lang);
50
- if(isset($tr_bundle[$tr_id])){
51
  $bundle_key = $tr_id.'_'.$i;
52
  $i++;
53
  }else{
54
  $bundle_key = $tr_id;
55
  }
56
- $tr_bundle[$bundle_key] = $bundle_data;
57
- $tr_bundle[$bundle_key]['product_id'] = $tr_id;
58
- if(isset($bundle_data['product_title'])){
59
- if($bundle_data['override_title'] == 'yes'){
60
- $tr_bundle[$bundle_key]['product_title'] = isset( $tr_bundle_meta[$bundle_key]['product_title'] ) ? $tr_bundle_meta[$bundle_key]['product_title'] : '';
 
 
 
61
  }else{
62
- $tr_title= get_the_title($tr_id);
63
- $tr_bundle[$bundle_key]['product_title'] = $tr_title;
64
  }
65
  }
66
- if(isset($bundle_data['product_description'])){
67
- if($bundle_data['override_description']=='yes'){
68
- $tr_bundle[$bundle_key]['product_description'] = isset( $tr_bundle_meta[$bundle_key]['product_description'] ) ? $tr_bundle_meta[$bundle_key]['product_description'] : '';
 
 
 
69
  }else{
70
- $tr_prod = get_post($tr_id);
71
  $tr_desc = $tr_prod->post_excerpt;
72
- $tr_bundle[$bundle_key]['product_description'] = $tr_desc;
73
  }
74
  }
75
- if(isset($bundle_data['filter_variations']) && $bundle_data['filter_variations']=='yes'){
76
- $allowed_var = $bundle_data['allowed_variations'];
77
- foreach($allowed_var as $key=>$var_id){
78
- $tr_var_id = apply_filters( 'translate_object_id',$var_id,get_post_type($var_id),true,$lang);
79
- $tr_bundle[$bundle_key]['allowed_variations'][$key] = $tr_var_id;
80
  }
81
  }
82
- if(isset($bundle_data['bundle_defaults']) && !empty($bundle_data['bundle_defaults'])){
83
- foreach($bundle_data['bundle_defaults'] as $tax=>$term_slug){
84
- global $woocommerce_wpml;
85
- $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug );
86
  if( $term_id ){
87
  // Global Attribute
88
- $tr_def_id = apply_filters( 'translate_object_id',$term_id,$tax,true,$lang);
89
- $tr_term = $woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax );
90
- $tr_bundle[$bundle_key]['bundle_defaults'][$tax] = $tr_term->slug;
91
  }else{
92
  // Custom Attribute
93
- $args = array( 'post_type' => 'product_variation', 'meta_key' => 'attribute_'.$tax, 'meta_value' => $term_slug, 'meta_compare' => '=');
 
 
 
 
 
94
  $variationloop = new WP_Query( $args );
95
  while ( $variationloop->have_posts() ) : $variationloop->the_post();
96
- $tr_var_id = apply_filters( 'translate_object_id',get_the_ID(),'product_variation',true,$lang);
97
- $tr_meta = get_post_meta($tr_var_id, 'attribute_'.$tax , true);
98
- $tr_bundle[$bundle_key]['bundle_defaults'][$tax] = $tr_meta;
99
  endwhile;
100
  }
101
  }
102
  }
103
  }
104
- update_post_meta($trnsl_product_id,'_bundle_data',$tr_bundle);
 
 
105
  }
 
106
  }
107
  // Update Bundled products title and descritpion after saving the translation
108
  function bundle_update( $original_product_id, $tr_id, $data, $lang ){
109
- global $sitepress;
110
  $tr_bundle_data = array();
111
- $tr_bundle_data = maybe_unserialize( get_post_meta($tr_id,'_bundle_data', true) );
112
 
113
  $bundle_data = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
114
 
@@ -120,13 +156,14 @@ class WCML_Product_Bundles{
120
 
121
  foreach ( $product_bundles as $key => $bundle_id ) {
122
  $bundle_product_tr_id = apply_filters( 'translate_object_id', $bundle_id, get_post_type( $bundle_id ), true, $lang );
123
- if(isset($tr_bundle_data[$bundle_product_tr_id])){
124
- $tr_bundle_data[$bundle_product_tr_id]['product_title'] = $data[ md5( 'bundle_'.$bundle_id.'_title' )];
125
- $tr_bundle_data[$bundle_product_tr_id]['product_description'] = $data[ md5( 'bundle_'.$bundle_id.'_desc' )];
126
  }
127
  }
128
  update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data );
129
 
 
130
  }
131
 
132
  // Add Bundles Box to WCML Translation GUI
@@ -152,14 +189,24 @@ class WCML_Product_Bundles{
152
 
153
  $group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_id ), $divider );
154
 
155
- if( $product_bundle['override_title'] == 'yes') {
156
- $bundle_field = new WPML_Editor_UI_Single_Line_Field('bundle_' . $bundle_id . '_title', __('Name', 'woocommerce-multilingual'), $data, false);
157
- $group->add_field($bundle_field);
 
 
 
 
 
158
  $add_group = true;
159
  }
160
 
161
- if( $product_bundle['override_description'] == 'yes'){
162
- $bundle_field = new WPML_Editor_UI_Single_Line_Field( 'bundle_'.$bundle_id.'_desc' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
 
 
 
 
 
163
  $group->add_field( $bundle_field );
164
  $add_group = true;
165
  }
@@ -168,13 +215,11 @@ class WCML_Product_Bundles{
168
  $bundles_section->add_field( $group );
169
  $flag = true;
170
  }
171
-
172
  }
173
 
174
  if( $flag ){
175
  $obj->add_field( $bundles_section );
176
  }
177
-
178
  }
179
 
180
 
@@ -192,27 +237,26 @@ class WCML_Product_Bundles{
192
 
193
  $product_bundles = array_keys( $bundle_data );
194
 
195
-
196
  foreach ( $product_bundles as $bundle_id ) {
197
 
198
- $bundles_texts = array();
199
- $bundle_name = get_the_title( $bundle_id );
200
-
201
- $data[ 'bundle_'.$bundle_id.'_title' ] = array( 'original' => $bundle_data[$bundle_id]['product_title'] );
202
- $data[ 'bundle_'.$bundle_id.'_desc' ] = array( 'original' => $bundle_data[$bundle_id]['product_description'] );
203
-
204
  $curr_bundle_id = apply_filters( 'translate_object_id', $bundle_id, 'product', false, $lang );
205
 
206
- if( isset($tr_bundle_data[$curr_bundle_id]['override_title']) && $tr_bundle_data[$curr_bundle_id]['override_title']=='yes' ){
207
- $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = $tr_bundle_data[$curr_bundle_id]['product_title'];
208
- }else {
209
- $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = '';
 
 
 
210
  }
211
 
212
- if( isset($tr_bundle_data[$curr_bundle_id]['override_description']) && $tr_bundle_data[$curr_bundle_id]['override_description']=='yes' ){
213
- $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = $tr_bundle_data[$curr_bundle_id]['product_description'];
214
- }else {
215
- $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = '';
 
 
 
216
  }
217
  }
218
 
@@ -225,24 +269,30 @@ class WCML_Product_Bundles{
225
  if ( $cart_item[ 'product_id' ] != $current_bundle_id ) {
226
  $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
227
  $cart_item[ 'data' ] = wc_get_product( $current_bundle_id );
228
- $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
229
- $remapped_bundled_item_ids = array();
230
- foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
231
- $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
232
- }
233
- $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids;
234
- if ( isset( $cart_item[ 'stamp' ] ) ) {
235
- $new_stamp = array();
236
- foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
237
- $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
238
- }
239
- $cart_item[ 'stamp' ] = $new_stamp;
240
- }
 
 
241
  }
242
  }
243
  if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) {
244
  $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ];
245
- if ( isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) && isset( $cart_item[ 'bundled_item_id' ] ) && isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] ) ) {
 
 
 
 
246
  $old_id = $cart_item[ 'bundled_item_id' ];
247
  $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ];
248
  $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ];
@@ -255,6 +305,7 @@ class WCML_Product_Bundles{
255
  }
256
  }
257
  }
 
258
  return $cart_item;
259
  }
260
 
@@ -281,21 +332,18 @@ class WCML_Product_Bundles{
281
  foreach( $bundle_data as $product ){
282
 
283
  foreach( $fields as $field ) {
284
- if ( $product['override_' . $field] == 'yes' && !empty($product['product_' . $field]) ) {
285
 
286
- $package['contents']['product_bundles:' . $product['product_id'] . ':' . $field] = array(
287
  'translate' => 1,
288
- 'data' => $this->tp->encode_field_data( $product['product_' . $field], 'base64' ),
289
  'format' => 'base64'
290
  );
291
 
292
  }
293
  }
294
-
295
  }
296
-
297
  }
298
-
299
  }
300
 
301
  return $package;
@@ -304,61 +352,58 @@ class WCML_Product_Bundles{
304
 
305
  function save_bundle_data_translation( $post_id, $data, $job ){
306
 
307
- remove_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
308
 
309
  $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
310
 
311
- $bundle_data_original = get_post_meta($job->original_doc_id , '_bundle_data', true);
312
 
313
  $translated_bundle_pieces = array();
314
 
315
  foreach( $data as $value){
316
 
317
- if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value['field_type'], $matches ) ){
318
 
319
  $product_id = $matches[1];
320
  $field = $matches[2];
321
 
322
  $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', true, $job->language_code );
323
 
324
- $products_translation_map[$translated_product_id] = $product_id;
325
 
326
  if( $translated_product_id ){
327
 
328
- $translated_bundle_pieces[$translated_product_id][$field] = $value['data'];
329
 
330
  }
331
-
332
  }
333
-
334
  }
335
 
336
  if( $translated_bundle_pieces ){
337
  foreach( $translated_bundle_pieces as $product_id => $piece ){
338
 
339
- if( isset($products_translation_map[$product_id]) ) {
340
 
341
- $bundle_data[$product_id] = array(
342
 
343
  'product_id' => $product_id,
344
- 'hide_thumbnail' => $bundle_data_original[$products_translation_map[$product_id]]['hide_thumbnail'],
345
- 'override_title' => $bundle_data_original[$products_translation_map[$product_id]]['override_title'],
346
- 'product_title' => isset( $piece['title'] ) ? $piece['title'] : '',
347
- 'override_description' => $bundle_data_original[$products_translation_map[$product_id]]['override_description'],
348
- 'product_description' => isset( $piece['description'] ) ? $piece['description'] : '',
349
- 'optional' => $bundle_data_original[$products_translation_map[$product_id]]['optional'],
350
- 'bundle_quantity' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_quantity'],
351
- 'bundle_quantity_max' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_quantity_max'],
352
- 'bundle_discount' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_discount'],
353
- 'visibility' => $bundle_data_original[$products_translation_map[$product_id]]['visibility'],
354
 
355
  );
356
  }
357
-
358
  }
359
  }
360
 
361
  update_post_meta( $post_id, '_bundle_data', $bundle_data );
362
 
363
  }
364
- }
1
  <?php
2
  class WCML_Product_Bundles{
3
 
4
+ /**
5
+ * @var WPML_Element_Translation_Package
6
+ */
7
  var $tp;
8
 
9
+ /**
10
+ * @var SitePress
11
+ */
12
+ private $sitepress;
13
+
14
+ /**
15
+ * @var woocommerce_wpml
16
+ */
17
+ private $woocommerce_wpml;
18
+
19
+ /**
20
+ * WCML_Product_Bundles constructor.
21
+ */
22
+ function __construct( &$sitepress, &$woocommerce_wpml ){
23
+ $this->sitepress = $sitepress;
24
+ $this->woocommerce_wpml = $woocommerce_wpml;
25
+
26
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
27
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
28
+ add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
29
+ add_action( 'wcml_update_extra_fields', array( $this, 'bundle_update' ), 10, 4 );
30
+ add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle' ), 5, 3 );
31
+ add_filter( 'woocommerce_cart_loaded_from_session', array( $this, 'resync_bundle_clean' ), 10 );
32
+
33
+ if( version_compare( WCML_VERSION, '3.7.2', '>' ) ){
34
+ add_filter( 'option_wpml_config_files_arr', array( $this, 'make__bundle_data_not_translatable_by_default' ), 0 );
35
  }
36
 
37
  if( is_admin() ){
42
 
43
  }
44
 
45
+
46
  }
47
 
48
+ function make__bundle_data_not_translatable_by_default( $wpml_config_array ){
49
 
50
+ if( isset( $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] ) ){
51
+ $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] =
52
+ str_replace(
53
+ '<custom-field action="translate">_bundle_data</custom-field>',
54
+ '<custom-field action="nothing">_bundle_data</custom-field>',
55
+ $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] );
56
  }
57
 
58
  return $wpml_config_array;
59
  }
60
 
61
  // Sync Bundled product '_bundle_data' with translated values when the product is duplicated
62
+ function sync_bundled_ids( $original_product_id, $trnsl_product_id ){
63
+
64
+ $bundle_data_array = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
65
+ if( $bundle_data_array ){
66
+ $lang = $this->sitepress->get_language_for_element( $trnsl_product_id, 'post_product' );
67
+ $tr_bundle_meta = maybe_unserialize( get_post_meta( $trnsl_product_id, '_bundle_data', true ) );
68
  $tr_ids = array();
69
  $i = 2;
70
+ foreach( $bundle_data_array as $id => $bundle_data ){
71
+ $tr_id = apply_filters( 'translate_object_id', $id, get_post_type( $id ), true, $lang );
72
+ if( isset( $tr_bundle_meta[ $tr_id ] ) ){
73
  $bundle_key = $tr_id.'_'.$i;
74
  $i++;
75
  }else{
76
  $bundle_key = $tr_id;
77
  }
78
+ $tr_bundle[ $bundle_key ] = $bundle_data;
79
+ $tr_bundle[ $bundle_key ][ 'product_id' ] = $tr_id;
80
+ if( isset( $bundle_data[ 'product_title' ] ) ){
81
+ if( $bundle_data[ 'override_title' ] == 'yes' ){
82
+ $tr_bundle[ $bundle_key ][ 'product_title' ] =
83
+ isset( $tr_bundle_meta[ $bundle_key ][ 'product_title' ] ) ?
84
+ $tr_bundle_meta[ $bundle_key ][ 'product_title' ] :
85
+ '';
86
  }else{
87
+ $tr_title= get_the_title( $tr_id );
88
+ $tr_bundle[ $bundle_key ][ 'product_title' ] = $tr_title;
89
  }
90
  }
91
+ if( isset( $bundle_data[ 'product_description' ] ) ){
92
+ if( $bundle_data[ 'override_description' ] == 'yes' ){
93
+ $tr_bundle[ $bundle_key ][ 'product_description' ] =
94
+ isset( $tr_bundle_meta[ $bundle_key ][ 'product_description' ] ) ?
95
+ $tr_bundle_meta[ $bundle_key ][ 'product_description' ] :
96
+ '';
97
  }else{
98
+ $tr_prod = get_post( $tr_id );
99
  $tr_desc = $tr_prod->post_excerpt;
100
+ $tr_bundle[ $bundle_key ][ 'product_description' ] = $tr_desc;
101
  }
102
  }
103
+ if( isset( $bundle_data[ 'filter_variations' ] ) && $bundle_data[ 'filter_variations' ] == 'yes' ){
104
+ $allowed_var = $bundle_data[ 'allowed_variations' ];
105
+ foreach( $allowed_var as $key => $var_id ){
106
+ $tr_var_id = apply_filters( 'translate_object_id', $var_id, get_post_type( $var_id ), true, $lang );
107
+ $tr_bundle[ $bundle_key ][ 'allowed_variations' ][ $key ] = $tr_var_id;
108
  }
109
  }
110
+ if( isset( $bundle_data[ 'bundle_defaults' ] ) && !empty( $bundle_data[ 'bundle_defaults' ] ) ){
111
+ foreach( $bundle_data[ 'bundle_defaults' ] as $tax => $term_slug ){
112
+
113
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug );
114
  if( $term_id ){
115
  // Global Attribute
116
+ $tr_def_id = apply_filters( 'translate_object_id', $term_id, $tax, true, $lang );
117
+ $tr_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax );
118
+ $tr_bundle[ $bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_term->slug;
119
  }else{
120
  // Custom Attribute
121
+ $args = array(
122
+ 'post_type' => 'product_variation',
123
+ 'meta_key' => 'attribute_'.$tax,
124
+ 'meta_value' => $term_slug,
125
+ 'meta_compare' => '='
126
+ );
127
  $variationloop = new WP_Query( $args );
128
  while ( $variationloop->have_posts() ) : $variationloop->the_post();
129
+ $tr_var_id = apply_filters( 'translate_object_id', get_the_ID(), 'product_variation', true, $lang );
130
+ $tr_meta = get_post_meta( $tr_var_id, 'attribute_'.$tax , true );
131
+ $tr_bundle[ $bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_meta;
132
  endwhile;
133
  }
134
  }
135
  }
136
  }
137
+ update_post_meta( $trnsl_product_id, '_bundle_data', $tr_bundle );
138
+
139
+ return $tr_bundle;
140
  }
141
+
142
  }
143
  // Update Bundled products title and descritpion after saving the translation
144
  function bundle_update( $original_product_id, $tr_id, $data, $lang ){
145
+
146
  $tr_bundle_data = array();
147
+ $tr_bundle_data = maybe_unserialize( get_post_meta($tr_id,'_bundle_data', true ) );
148
 
149
  $bundle_data = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
150
 
156
 
157
  foreach ( $product_bundles as $key => $bundle_id ) {
158
  $bundle_product_tr_id = apply_filters( 'translate_object_id', $bundle_id, get_post_type( $bundle_id ), true, $lang );
159
+ if( isset( $tr_bundle_data[ $bundle_product_tr_id ] ) ){
160
+ $tr_bundle_data[ $bundle_product_tr_id ][ 'product_title' ] = $data[ md5( 'bundle_'.$bundle_id.'_title' ) ];
161
+ $tr_bundle_data[ $bundle_product_tr_id ][ 'product_description' ] = $data[ md5( 'bundle_'.$bundle_id.'_desc' ) ];
162
  }
163
  }
164
  update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data );
165
 
166
+ return $tr_bundle_data;
167
  }
168
 
169
  // Add Bundles Box to WCML Translation GUI
189
 
190
  $group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_id ), $divider );
191
 
192
+ if( $product_bundle[ 'override_title' ] == 'yes' ) {
193
+ $bundle_field = new WPML_Editor_UI_Single_Line_Field(
194
+ 'bundle_' . $bundle_id . '_title',
195
+ __( 'Name', 'woocommerce-multilingual' ),
196
+ $data,
197
+ false
198
+ );
199
+ $group->add_field( $bundle_field );
200
  $add_group = true;
201
  }
202
 
203
+ if( $product_bundle[ 'override_description' ] == 'yes' ){
204
+ $bundle_field = new WPML_Editor_UI_Single_Line_Field(
205
+ 'bundle_'.$bundle_id.'_desc' ,
206
+ __( 'Description', 'woocommerce-multilingual' ),
207
+ $data,
208
+ false
209
+ );
210
  $group->add_field( $bundle_field );
211
  $add_group = true;
212
  }
215
  $bundles_section->add_field( $group );
216
  $flag = true;
217
  }
 
218
  }
219
 
220
  if( $flag ){
221
  $obj->add_field( $bundles_section );
222
  }
 
223
  }
224
 
225
 
237
 
238
  $product_bundles = array_keys( $bundle_data );
239
 
 
240
  foreach ( $product_bundles as $bundle_id ) {
241
 
 
 
 
 
 
 
242
  $curr_bundle_id = apply_filters( 'translate_object_id', $bundle_id, 'product', false, $lang );
243
 
244
+ if( $bundle_data[ $bundle_id ][ 'override_title' ] == 'yes' ){
245
+ $data[ 'bundle_'.$bundle_id.'_title' ] = array( 'original' => $bundle_data[ $bundle_id ][ 'product_title' ] );
246
+ if( isset( $tr_bundle_data[ $curr_bundle_id ][ 'override_title' ] ) ){
247
+ $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = $tr_bundle_data[ $curr_bundle_id ][ 'product_title' ];
248
+ }else{
249
+ $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = '';
250
+ }
251
  }
252
 
253
+ if( $bundle_data[ $bundle_id ][ 'override_description' ] == 'yes' ){
254
+ $data[ 'bundle_'.$bundle_id.'_desc' ] = array( 'original' => $bundle_data[ $bundle_id ][ 'product_description' ] );
255
+ if( isset( $tr_bundle_data[ $curr_bundle_id ][ 'override_description' ] ) ){
256
+ $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = $tr_bundle_data[ $curr_bundle_id ][ 'product_description' ];
257
+ }else{
258
+ $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = '';
259
+ }
260
  }
261
  }
262
 
269
  if ( $cart_item[ 'product_id' ] != $current_bundle_id ) {
270
  $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
271
  $cart_item[ 'data' ] = wc_get_product( $current_bundle_id );
272
+ if( is_array( $cart_item[ 'data' ]->bundle_data ) ){
273
+ $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
274
+ $remapped_bundled_item_ids = array();
275
+ foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
276
+ $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
277
+ }
278
+ $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids;
279
+ if ( isset( $cart_item[ 'stamp' ] ) ) {
280
+ $new_stamp = array();
281
+ foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
282
+ $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
283
+ }
284
+ $cart_item[ 'stamp' ] = $new_stamp;
285
+ }
286
+ }
287
  }
288
  }
289
  if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) {
290
  $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ];
291
+ if (
292
+ isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) &&
293
+ isset( $cart_item[ 'bundled_item_id' ] ) &&
294
+ isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] )
295
+ ) {
296
  $old_id = $cart_item[ 'bundled_item_id' ];
297
  $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ];
298
  $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ];
305
  }
306
  }
307
  }
308
+
309
  return $cart_item;
310
  }
311
 
332
  foreach( $bundle_data as $product ){
333
 
334
  foreach( $fields as $field ) {
335
+ if ( $product[ 'override_' . $field ] == 'yes' && !empty( $product[ 'product_' . $field ] ) ) {
336
 
337
+ $package[ 'contents' ][ 'product_bundles:' . $product['product_id'] . ':' . $field ] = array(
338
  'translate' => 1,
339
+ 'data' => $this->tp->encode_field_data( $product[ 'product_' . $field ], 'base64' ),
340
  'format' => 'base64'
341
  );
342
 
343
  }
344
  }
 
345
  }
 
346
  }
 
347
  }
348
 
349
  return $package;
352
 
353
  function save_bundle_data_translation( $post_id, $data, $job ){
354
 
355
+ remove_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
356
 
357
  $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
358
 
359
+ $bundle_data_original = get_post_meta( $job->original_doc_id , '_bundle_data', true );
360
 
361
  $translated_bundle_pieces = array();
362
 
363
  foreach( $data as $value){
364
 
365
+ if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value[ 'field_type' ], $matches ) ){
366
 
367
  $product_id = $matches[1];
368
  $field = $matches[2];
369
 
370
  $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', true, $job->language_code );
371
 
372
+ $products_translation_map[ $translated_product_id ] = $product_id;
373
 
374
  if( $translated_product_id ){
375
 
376
+ $translated_bundle_pieces[ $translated_product_id ][ $field ] = $value[ 'data' ];
377
 
378
  }
 
379
  }
 
380
  }
381
 
382
  if( $translated_bundle_pieces ){
383
  foreach( $translated_bundle_pieces as $product_id => $piece ){
384
 
385
+ if( isset( $products_translation_map[ $product_id ] ) ) {
386
 
387
+ $bundle_data[ $product_id ] = array(
388
 
389
  'product_id' => $product_id,
390
+ 'hide_thumbnail' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'hide_thumbnail' ],
391
+ 'override_title' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'override_title' ],
392
+ 'product_title' => isset( $piece[ 'title' ] ) ? $piece[ 'title' ] : '',
393
+ 'override_description' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'override_description' ],
394
+ 'product_description' => isset( $piece[ 'description' ] ) ? $piece[ 'description' ] : '',
395
+ 'optional' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'optional' ],
396
+ 'bundle_quantity' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'bundle_quantity' ],
397
+ 'bundle_quantity_max' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'bundle_quantity_max' ],
398
+ 'bundle_discount' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'bundle_discount' ],
399
+ 'visibility' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'visibility' ],
400
 
401
  );
402
  }
 
403
  }
404
  }
405
 
406
  update_post_meta( $post_id, '_bundle_data', $bundle_data );
407
 
408
  }
409
+ }
compatibility/class-wcml-table-rate-shipping.php CHANGED
@@ -1,65 +1,121 @@
1
  <?php
2
 
3
- class WCML_Table_Rate_Shipping{
4
-
5
- function __construct(){
6
-
7
- add_action('init', array($this, 'init'),9);
8
-
9
- add_filter('woocommerce_table_rate_query_rates_args', array($this, 'default_shipping_class_id'));
10
- add_filter('get_the_terms',array( $this, 'shipping_class_id_in_default_language'), 10, 3 );
11
- }
12
-
13
- public function init(){
14
- global $pagenow;
15
-
16
- //register shipping label
17
- if($pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page']=='shipping_zones' && isset( $_POST['shipping_label'] ) && isset( $_POST['woocommerce_table_rate_title'] )){
18
- do_action('wpml_register_single_string', 'woocommerce', $_POST['woocommerce_table_rate_title'] .'_shipping_method_title', $_POST['woocommerce_table_rate_title']);
19
- $shipping_labels = array_map( 'woocommerce_clean', $_POST['shipping_label'] );
20
- foreach($shipping_labels as $shipping_label){
21
- do_action('wpml_register_single_string', 'woocommerce', $shipping_label .'_shipping_method_title', $shipping_label);
22
- }
23
- }
24
-
25
- }
26
-
27
- public function default_shipping_class_id($args){
28
- global $sitepress, $woocommerce_wpml;
29
- if( !empty($args['shipping_class_id'])){
30
-
31
- $args['shipping_class_id'] = apply_filters( 'translate_object_id',$args['shipping_class_id'], 'product_shipping_class', false, $sitepress->get_default_language());
32
-
33
- if($woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT){
34
- // use unfiltred cart price to compare against limits of different shipping methods
35
- $args['price'] = $woocommerce_wpml->multi_currency->prices->unconvert_price_amount($args['price']);
36
- }
37
-
38
- }
39
-
40
- return $args;
41
- }
42
-
43
- public function shipping_class_id_in_default_language( $terms, $post_id, $taxonomy ) {
44
- global $sitepress, $icl_adjust_id_url_filter_off;
45
- if ( !is_admin() && $taxonomy == 'product_shipping_class' ) {
46
-
47
- foreach( $terms as $k => $term ){
48
- $shipping_class_id = apply_filters( 'translate_object_id', $term->term_id, 'product_shipping_class', false, $sitepress->get_default_language());
49
-
50
- $icl_adjust_id_url_filter = $icl_adjust_id_url_filter_off;
51
- $icl_adjust_id_url_filter_off = true;
52
-
53
- $terms[$k] = get_term( $shipping_class_id, 'product_shipping_class');
54
-
55
- $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter;
56
-
57
- }
58
-
59
- }
60
-
61
- return $terms;
62
-
63
- }
64
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  }
1
  <?php
2
 
3
+ /**
4
+ * Class WCML_Table_Rate_Shipping
5
+ */
6
+ class WCML_Table_Rate_Shipping {
7
+
8
+ /**
9
+ * @var SitePress
10
+ */
11
+ public $sitepress;
12
+
13
+ /**
14
+ * @var woocommerce_wpml
15
+ */
16
+ public $woocommerce_wpml;
17
+
18
+ /**
19
+ * WCML_Table_Rate_Shipping constructor.
20
+ *
21
+ * @param $sitepress
22
+ * @param $woocommerce_wpml
23
+ */
24
+ function __construct( &$sitepress, &$woocommerce_wpml ) {
25
+ $this->sitepress = $sitepress;
26
+ $this->woocommerce_wpml = $woocommerce_wpml;
27
+ add_action( 'init', array( $this, 'init' ), 9 );
28
+ add_filter( 'get_the_terms',array( $this, 'shipping_class_id_in_default_language' ), 10, 3 );
29
+
30
+ if( wcml_is_multi_currency_on() ) {
31
+ add_filter( 'woocommerce_table_rate_query_rates_args', array( $this, 'default_shipping_class_id' ) );
32
+ add_filter( 'woocommerce_table_rate_query_rates', array( $this, 'convert_costs' ) );
33
+ }
34
+
35
+ }
36
+
37
+ /**
38
+ * Register shipping labels for string translation.
39
+ */
40
+ public function init() {
41
+ // Register shipping label
42
+ if ( isset( $_GET['page'] ) && 'shipping_zones' === $_GET['page'] && isset( $_POST['shipping_label'] ) && isset( $_POST['woocommerce_table_rate_title'] ) ) {
43
+ do_action( 'wpml_register_single_string', 'woocommerce', sanitize_text_field( $_POST['woocommerce_table_rate_title'] ) . '_shipping_method_title', sanitize_text_field( $_POST['woocommerce_table_rate_title'] ) );
44
+ $shipping_labels = array_map( 'woocommerce_clean', $_POST['shipping_label'] );
45
+ foreach ( $shipping_labels as $shipping_label ) {
46
+ do_action( 'wpml_register_single_string', 'woocommerce', $shipping_label . '_shipping_method_title', $shipping_label );
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ * @param $args
53
+ *
54
+ * @return mixed
55
+ */
56
+ public function default_shipping_class_id( $args ) {
57
+ if ( ! empty( $args['shipping_class_id'] ) ) {
58
+
59
+ $args['shipping_class_id'] = apply_filters( 'translate_object_id', $args['shipping_class_id'], 'product_shipping_class', false, $this->sitepress->get_default_language() );
60
+
61
+ if ( WCML_MULTI_CURRENCIES_INDEPENDENT === $this->woocommerce_wpml->settings['enable_multi_currency'] ) {
62
+ // use unfiltered cart price to compare against limits of different shipping methods
63
+ $args['price'] = $this->woocommerce_wpml->multi_currency->prices->unconvert_price_amount( $args['price'] );
64
+ }
65
+ }
66
+
67
+ return $args;
68
+ }
69
+
70
+ /**
71
+ * @param $terms
72
+ * @param $post_id
73
+ * @param $taxonomy
74
+ *
75
+ * @return mixed
76
+ */
77
+ public function shipping_class_id_in_default_language( $terms, $post_id, $taxonomy ) {
78
+ global $icl_adjust_id_url_filter_off;
79
+ if ( 'product_shipping_class' === $taxonomy ) {
80
+
81
+ foreach ( $terms as $k => $term ) {
82
+ $shipping_class_id = apply_filters( 'translate_object_id', $term->term_id, 'product_shipping_class', false, $this->sitepress->get_default_language() );
83
+
84
+ $icl_adjust_id_url_filter = $icl_adjust_id_url_filter_off;
85
+ $icl_adjust_id_url_filter_off = true;
86
+
87
+ $terms[ $k ] = get_term( $shipping_class_id, 'product_shipping_class' );
88
+
89
+ $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter;
90
+ }
91
+ }
92
+
93
+ return $terms;
94
+ }
95
+
96
+ /**
97
+ * @param $rates
98
+ * @return mixed
99
+ *
100
+ * Converts shipping costs in secondary currencies
101
+ */
102
+ public function convert_costs( $rates ){
103
+
104
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
105
+
106
+ if( $client_currency != get_option('woocommerce_currency') ){
107
+
108
+ $multi_currency_prices = $this->woocommerce_wpml->multi_currency->prices;
109
+
110
+ foreach( $rates as $key => $rate ){
111
+
112
+ $rates[$key]->rate_cost = $multi_currency_prices->raw_price_filter( $rates[$key]->rate_cost, $client_currency );
113
+ $rates[$key]->rate_cost_per_item = $multi_currency_prices->raw_price_filter( $rates[$key]->rate_cost_per_item, $client_currency );
114
+
115
+ }
116
+
117
+ }
118
+
119
+ return $rates;
120
+ }
121
  }
compatibility/class-wcml-vpc.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Vpc {
4
+
5
+ function __construct() {
6
+ add_filter( 'wcml_calculate_totals_exception', array( $this, 'wcml_vpc_cart_exc' ), 10, 2 );
7
+ }
8
+
9
+ function wcml_vpc_cart_exc( $exc, $cart ) {
10
+
11
+ foreach( $cart->cart_contents as $cart_item ){
12
+ if ( array_key_exists( 'visual-product-configuration', $cart_item ) ) {
13
+ return false;
14
+ }
15
+ }
16
+
17
+ return $exc;
18
+ }
19
+
20
+ }
compatibility/res/css/wcml-bookings.css CHANGED
@@ -22,24 +22,25 @@
22
  padding: 6px 7px;
23
  }
24
 
25
- .wcml_wc_booking_cost_field label,
26
- .wcml_wc_booking_base_cost_field label,
27
- .wcml_wc_display_cost_field label{
28
- text-align: right;
29
- margin-left: -160px;
30
- }
31
-
32
  .wcml_custom_costs{
33
  padding: 9px 9px 0;
34
  display: inline-block;
35
  width: 100%;
 
 
36
  }
37
 
38
- #bookings_pricing .wcml_custom_costs label{
 
39
  width: auto;
40
  margin: 0 5px;
41
  float: left;
42
  }
 
 
 
 
 
43
 
44
  #bookings_pricing .wcml_custom_cost_field label,
45
  #bookings_resources .woocommerce_booking_resource .wcml_bookings_resource_block label{
@@ -57,4 +58,4 @@
57
  input.wcml_bookings_custom_price,
58
  #bookings_pricing .table_grid table td input.wcml_bookings_custom_price{
59
  background-color: #F5F2E1;
60
- }
22
  padding: 6px 7px;
23
  }
24
 
 
 
 
 
 
 
 
25
  .wcml_custom_costs{
26
  padding: 9px 9px 0;
27
  display: inline-block;
28
  width: 100%;
29
+ float:left;
30
+ margin-top:10px;
31
  }
32
 
33
+ #bookings_pricing .wcml_custom_costs label,
34
+ .woocommerce_options_panel .wcml_custom_costs label{
35
  width: auto;
36
  margin: 0 5px;
37
  float: left;
38
  }
39
+ .woocommerce_options_panel .wcml_bookings_range_block label{
40
+ width: 10px;;
41
+ margin: 0;
42
+ padding: inherit;
43
+ }
44
 
45
  #bookings_pricing .wcml_custom_cost_field label,
46
  #bookings_resources .woocommerce_booking_resource .wcml_bookings_resource_block label{
58
  input.wcml_bookings_custom_price,
59
  #bookings_pricing .table_grid table td input.wcml_bookings_custom_price{
60
  background-color: #F5F2E1;
61
+ }
embedded/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit655bc99a48b2de2700adf0e1886e5b25::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit00dcbeb0e1eb354a5d439568c0e22365::getLoader();
embedded/autoload_52.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
- return ComposerAutoloaderInitf22d2ac5fa5e49381a2eaa0f42a43b81::getLoader();
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
+ return ComposerAutoloaderInit3e6faae5084bf837bfc9888926348dac::getLoader();
embedded/composer/LICENSE CHANGED
@@ -1,5 +1,5 @@
1
 
2
- Copyright (c) 2015 Nils Adermann, Jordi Boggiano
3
 
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
  of this software and associated documentation files (the "Software"), to deal
1
 
2
+ Copyright (c) 2016 Nils Adermann, Jordi Boggiano
3
 
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
  of this software and associated documentation files (the "Software"), to deal
embedded/composer/autoload_classmap.php CHANGED
@@ -102,6 +102,7 @@ return array(
102
  'WCML_Upgrade' => $baseDir . '/inc/class-wcml-upgrade.php',
103
  'WCML_Url_Translation' => $baseDir . '/inc/class-wcml-url-translation.php',
104
  'WCML_Variation_Swatches_and_Photos' => $baseDir . '/compatibility/class-wcml-variation-swatches-and-photos.php',
 
105
  'WCML_W3TC_Multi_Currency' => $baseDir . '/inc/currencies/class-wcml-w3tc-multi-currency.php',
106
  'WCML_WC_Ajax_Cart' => $baseDir . '/compatibility/class-wcml-wc-ajax-cart.php',
107
  'WCML_WC_Gateways' => $baseDir . '/inc/class-wcml-wc-gateways.php',
102
  'WCML_Upgrade' => $baseDir . '/inc/class-wcml-upgrade.php',
103
  'WCML_Url_Translation' => $baseDir . '/inc/class-wcml-url-translation.php',
104
  'WCML_Variation_Swatches_and_Photos' => $baseDir . '/compatibility/class-wcml-variation-swatches-and-photos.php',
105
+ 'WCML_Vpc' => $baseDir . '/compatibility/class-wcml-vpc.php',
106
  'WCML_W3TC_Multi_Currency' => $baseDir . '/inc/currencies/class-wcml-w3tc-multi-currency.php',
107
  'WCML_WC_Ajax_Cart' => $baseDir . '/compatibility/class-wcml-wc-ajax-cart.php',
108
  'WCML_WC_Gateways' => $baseDir . '/inc/class-wcml-wc-gateways.php',
embedded/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit655bc99a48b2de2700adf0e1886e5b25
6
  {
7
  private static $loader;
8
 
@@ -19,23 +19,30 @@ class ComposerAutoloaderInit655bc99a48b2de2700adf0e1886e5b25
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit655bc99a48b2de2700adf0e1886e5b25', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit655bc99a48b2de2700adf0e1886e5b25', 'loadClassLoader'));
25
-
26
- $map = require __DIR__ . '/autoload_namespaces.php';
27
- foreach ($map as $namespace => $path) {
28
- $loader->set($namespace, $path);
29
- }
30
-
31
- $map = require __DIR__ . '/autoload_psr4.php';
32
- foreach ($map as $namespace => $path) {
33
- $loader->setPsr4($namespace, $path);
34
- }
35
-
36
- $classMap = require __DIR__ . '/autoload_classmap.php';
37
- if ($classMap) {
38
- $loader->addClassMap($classMap);
 
 
 
 
 
 
 
39
  }
40
 
41
  $loader->register(true);
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit00dcbeb0e1eb354a5d439568c0e22365
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit00dcbeb0e1eb354a5d439568c0e22365', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit00dcbeb0e1eb354a5d439568c0e22365', 'loadClassLoader'));
25
+
26
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
27
+ if ($useStaticLoader) {
28
+ require_once __DIR__ . '/autoload_static.php';
29
+
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit00dcbeb0e1eb354a5d439568c0e22365::getInitializer($loader));
31
+ } else {
32
+ $map = require __DIR__ . '/autoload_namespaces.php';
33
+ foreach ($map as $namespace => $path) {
34
+ $loader->set($namespace, $path);
35
+ }
36
+
37
+ $map = require __DIR__ . '/autoload_psr4.php';
38
+ foreach ($map as $namespace => $path) {
39
+ $loader->setPsr4($namespace, $path);
40
+ }
41
+
42
+ $classMap = require __DIR__ . '/autoload_classmap.php';
43
+ if ($classMap) {
44
+ $loader->addClassMap($classMap);
45
+ }
46
  }
47
 
48
  $loader->register(true);
embedded/composer/autoload_real_52.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
- class ComposerAutoloaderInitf22d2ac5fa5e49381a2eaa0f42a43b81 {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitf22d2ac5fa5e49381a2eaa0f42a43b81 {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInitf22d2ac5fa5e49381a2eaa0f42a43b81', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInitf22d2ac5fa5e49381a2eaa0f42a43b81', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
+ class ComposerAutoloaderInit3e6faae5084bf837bfc9888926348dac {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit3e6faae5084bf837bfc9888926348dac', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit3e6faae5084bf837bfc9888926348dac', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
embedded/composer/autoload_static.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_static.php @generated by Composer
4
+
5
+ namespace Composer\Autoload;
6
+
7
+ class ComposerStaticInit00dcbeb0e1eb354a5d439568c0e22365
8
+ {
9
+ public static $prefixLengthsPsr4 = array (
10
+ 'C' =>
11
+ array (
12
+ 'Composer\\Installers\\' => 20,
13
+ ),
14
+ );
15
+
16
+ public static $prefixDirsPsr4 = array (
17
+ 'Composer\\Installers\\' =>
18
+ array (
19
+ 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
20
+ ),
21
+ );
22
+
23
+ public static $prefixesPsr0 = array (
24
+ 'x' =>
25
+ array (
26
+ 'xrstf\\Composer52' =>
27
+ array (
28
+ 0 => __DIR__ . '/..' . '/xrstf/composer-php52/lib',
29
+ ),
30
+ ),
31
+ );
32
+
33
+ public static $classMap = array (
34
+ 'WCML_Accommodation_Bookings' => __DIR__ . '/../..' . '/compatibility/class-wcml-accommodation-bookings.php',
35
+ 'WCML_Admin_Currency_Selector' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-admin-currency-selector.php',
36
+ 'WCML_Admin_Menus' => __DIR__ . '/../..' . '/inc/admin-menus/class-wcml-admin-menus.php',
37
+ 'WCML_Adventure_tours' => __DIR__ . '/../..' . '/compatibility/class-wcml-adventure-tours.php',
38
+ 'WCML_Ajax_Layered_Nav_Widget' => __DIR__ . '/../..' . '/compatibility/class-wcml-ajax-layered-nav-widget.php',
39
+ 'WCML_Ajax_Setup' => __DIR__ . '/../..' . '/inc/class-wcml-ajax-setup.php',
40
+ 'WCML_Attribute_Translation_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-attribute-translation-ui.php',
41
+ 'WCML_Attributes' => __DIR__ . '/../..' . '/inc/class-wcml-attributes.php',
42
+ 'WCML_Aurum' => __DIR__ . '/../..' . '/compatibility/class-wcml-aurum.php',
43
+ 'WCML_Bookings' => __DIR__ . '/../..' . '/compatibility/class-wcml-bookings.php',
44
+ 'WCML_Bulk_Stock_Management' => __DIR__ . '/../..' . '/compatibility/class-wcml-bulk-stock-management.php',
45
+ 'WCML_Capabilities' => __DIR__ . '/../..' . '/inc/class-wcml-capabilities.php',
46
+ 'WCML_Cart' => __DIR__ . '/../..' . '/inc/class-wcml-cart.php',
47
+ 'WCML_Checkout_Addons' => __DIR__ . '/../..' . '/compatibility/class-wcml-checkout-addons.php',
48
+ 'WCML_Checkout_Field_Editor' => __DIR__ . '/../..' . '/compatibility/class-wcml-checkout-field-editor.php',
49
+ 'WCML_Compatibility' => __DIR__ . '/../..' . '/inc/class-wcml-compatibility.php',
50
+ 'WCML_Compatibility_Helper' => __DIR__ . '/../..' . '/compatibility/class-wcml-compatibility-helper.php',
51
+ 'WCML_Composite_Products' => __DIR__ . '/../..' . '/compatibility/class-wcml-composite-products.php',
52
+ 'WCML_Coupons' => __DIR__ . '/../..' . '/inc/class-wcml-coupons.php',
53
+ 'WCML_Currencies' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-currencies.php',
54
+ 'WCML_Currency_Switcher' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-currency-switcher.php',
55
+ 'WCML_Currency_Switcher_Widget' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-currency-switcher-widget.php',
56
+ 'WCML_Custom_Currency_Options' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-custom-currency-options.php',
57
+ 'WCML_Custom_Files_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-custom-files-ui.php',
58
+ 'WCML_Custom_Prices' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-custom-prices.php',
59
+ 'WCML_Custom_Prices_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-custom-prices-ui.php',
60
+ 'WCML_Dependencies' => __DIR__ . '/../..' . '/inc/class-wcml-dependencies.php',
61
+ 'WCML_Downloadable_Products' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-downloadable-products.php',
62
+ 'WCML_Dynamic_Pricing' => __DIR__ . '/../..' . '/compatibility/class-wcml-dynamic-pricing.php',
63
+ 'WCML_Editor_Save_Filters' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-editor-save-filters.php',
64
+ 'WCML_Editor_UI_Product_Job' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-editor-ui-product-job.php',
65
+ 'WCML_Emails' => __DIR__ . '/../..' . '/inc/class-wcml-emails.php',
66
+ 'WCML_Endpoints' => __DIR__ . '/../..' . '/inc/class-wcml-endpoints.php',
67
+ 'WCML_Extra_Product_Options' => __DIR__ . '/../..' . '/compatibility/class-wcml-extra-product-options.php',
68
+ 'WCML_Flatsome' => __DIR__ . '/../..' . '/compatibility/class-wcml-flatsome.php',
69
+ 'WCML_Install' => __DIR__ . '/../..' . '/inc/class-wcml-install.php',
70
+ 'WCML_Languages_Upgrade_Notice' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-languages-upgrade-notice.php',
71
+ 'WCML_Languages_Upgrader' => __DIR__ . '/../..' . '/inc/class-wcml-languages-upgrader.php',
72
+ 'WCML_Links' => __DIR__ . '/../..' . '/inc/admin-menus/class-wcml-links.php',
73
+ 'WCML_Locale' => __DIR__ . '/../..' . '/inc/class-wcml-locale.php',
74
+ 'WCML_Media' => __DIR__ . '/../..' . '/inc/class-wcml-media.php',
75
+ 'WCML_Menus_Wrap' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-menus-wrap.php',
76
+ 'WCML_Mix_and_Match_Products' => __DIR__ . '/../..' . '/compatibility/class-wcml-mix-and-match-products.php',
77
+ 'WCML_Multi_Currency' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency.php',
78
+ 'WCML_Multi_Currency_Configuration' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-configuration.php',
79
+ 'WCML_Multi_Currency_Coupons' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-coupons.php',
80
+ 'WCML_Multi_Currency_Install' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-install.php',
81
+ 'WCML_Multi_Currency_Orders' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-orders.php',
82
+ 'WCML_Multi_Currency_Prices' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-prices.php',
83
+ 'WCML_Multi_Currency_Reports' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-reports.php',
84
+ 'WCML_Multi_Currency_Resources' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-resources.php',
85
+ 'WCML_Multi_Currency_Shipping' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-shipping.php',
86
+ 'WCML_Multi_Currency_Table_Rate_Shipping' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-table-rate-shipping.php',
87
+ 'WCML_Multi_Currency_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-multi-currency-ui.php',
88
+ 'WCML_Not_Translatable_Attributes' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
89
+ 'WCML_Orders' => __DIR__ . '/../..' . '/inc/class-wcml-orders.php',
90
+ 'WCML_Per_Product_Shipping' => __DIR__ . '/../..' . '/compatibility/class-wcml-per-product-shipping.php',
91
+ 'WCML_Plugins_Wrap' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-plugins-wrap.php',
92
+ 'WCML_Product_Addons' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-addons.php',
93
+ 'WCML_Product_Bundles' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-bundles.php',
94
+ 'WCML_Products' => __DIR__ . '/../..' . '/inc/class-wcml-products.php',
95
+ 'WCML_Products_Screen_Options' => __DIR__ . '/../..' . '/inc/class-wcml-products-screen-options.php',
96
+ 'WCML_Products_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-products-ui.php',
97
+ 'WCML_Reports' => __DIR__ . '/../..' . '/inc/class-wcml-reports.php',
98
+ 'WCML_Requests' => __DIR__ . '/../..' . '/inc/class-wcml-requests.php',
99
+ 'WCML_Resources' => __DIR__ . '/../..' . '/inc/class-wcml-resources.php',
100
+ 'WCML_Settings_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-settings-ui.php',
101
+ 'WCML_Setup' => __DIR__ . '/../..' . '/inc/admin-menus/class-wcml-setup.php',
102
+ 'WCML_Setup_Attributes_UI' => __DIR__ . '/../..' . '/inc/template-classes/setup/class-wcml-setup-attributes-ui.php',
103
+ 'WCML_Setup_Introduction_UI' => __DIR__ . '/../..' . '/inc/template-classes/setup/class-wcml-setup-introduction-ui.php',
104
+ 'WCML_Setup_Multi_Currency_UI' => __DIR__ . '/../..' . '/inc/template-classes/setup/class-wcml-setup-multi-currency-ui.php',
105
+ 'WCML_Setup_Ready_UI' => __DIR__ . '/../..' . '/inc/template-classes/setup/class-wcml-setup-ready-ui.php',
106
+ 'WCML_Setup_Store_Pages_UI' => __DIR__ . '/../..' . '/inc/template-classes/setup/class-wcml-setup-store-pages-ui.php',
107
+ 'WCML_Setup_Translation_Interface_UI' => __DIR__ . '/../..' . '/inc/template-classes/setup/class-wcml-setup-translation-interface-ui.php',
108
+ 'WCML_Status_Config_Warnings_UI' => __DIR__ . '/../..' . '/inc/template-classes/status/class-wcml-status-config-warnings-ui.php',
109
+ 'WCML_Status_Status_UI' => __DIR__ . '/../..' . '/inc/template-classes/status/class-wcml-status-status-ui.php',
110
+ 'WCML_Status_Store_Pages_UI' => __DIR__ . '/../..' . '/inc/template-classes/status/class-wcml-status-store-pages-ui.php',
111
+ 'WCML_Status_Taxonomies_UI' => __DIR__ . '/../..' . '/inc/template-classes/status/class-wcml-status-taxonomies-ui.php',
112
+ 'WCML_Status_UI' => __DIR__ . '/../..' . '/inc/template-classes/status/class-wcml-status-ui.php',
113
+ 'WCML_Store_Pages' => __DIR__ . '/../..' . '/inc/class-wcml-store-pages.php',
114
+ 'WCML_Store_URLs_Edit_Base_UI' => __DIR__ . '/../..' . '/inc/template-classes/store-urls/class-wcml-store-urls-edit-base-ui.php',
115
+ 'WCML_Store_URLs_Translation_Statuses_UI' => __DIR__ . '/../..' . '/inc/template-classes/store-urls/class-wcml-store-urls-translation-statuses-ui.php',
116
+ 'WCML_Store_URLs_UI' => __DIR__ . '/../..' . '/inc/template-classes/store-urls/class-wcml-store-urls-ui.php',
117
+ 'WCML_Sync_Taxonomy' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-sync-taxonomy.php',
118
+ 'WCML_Synchronize_Product_Data' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-synchronize-product-data.php',
119
+ 'WCML_Synchronize_Variations_Data' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-synchronize-variations-data.php',
120
+ 'WCML_TP_Support' => __DIR__ . '/../..' . '/inc/class-wcml-tp-support.php',
121
+ 'WCML_Tab_Manager' => __DIR__ . '/../..' . '/compatibility/class-wcml-tab-manager.php',
122
+ 'WCML_Table_Rate_Shipping' => __DIR__ . '/../..' . '/compatibility/class-wcml-table-rate-shipping.php',
123
+ 'WCML_Terms' => __DIR__ . '/../..' . '/inc/class-wcml-terms.php',
124
+ 'WCML_Translation_Editor' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-translation-editor.php',
125
+ 'WCML_Troubleshooting' => __DIR__ . '/../..' . '/inc/class-wcml-troubleshooting.php',
126
+ 'WCML_Troubleshooting_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-troubleshooting-ui.php',
127
+ 'WCML_Upgrade' => __DIR__ . '/../..' . '/inc/class-wcml-upgrade.php',
128
+ 'WCML_Url_Translation' => __DIR__ . '/../..' . '/inc/class-wcml-url-translation.php',
129
+ 'WCML_Variation_Swatches_and_Photos' => __DIR__ . '/../..' . '/compatibility/class-wcml-variation-swatches-and-photos.php',
130
+ 'WCML_Vpc' => __DIR__ . '/../..' . '/compatibility/class-wcml-vpc.php',
131
+ 'WCML_W3TC_Multi_Currency' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-w3tc-multi-currency.php',
132
+ 'WCML_WC_Ajax_Cart' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-ajax-cart.php',
133
+ 'WCML_WC_Gateways' => __DIR__ . '/../..' . '/inc/class-wcml-wc-gateways.php',
134
+ 'WCML_WC_Name_Your_Price' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-name-your-price.php',
135
+ 'WCML_WC_Shipping' => __DIR__ . '/../..' . '/inc/class-wcml-wc-shipping.php',
136
+ 'WCML_WC_Strings' => __DIR__ . '/../..' . '/inc/class-wcml-wc-strings.php',
137
+ 'WCML_WC_Subscriptions' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-subscriptions.php',
138
+ 'WCML_WPSEO' => __DIR__ . '/../..' . '/compatibility/class-wcml-wpseo.php',
139
+ 'WCML_WooCommerce_Rest_API_Support' => __DIR__ . '/../..' . '/inc/class-wcml-woocommerce-rest-api-support.php',
140
+ 'WCML_gravityforms' => __DIR__ . '/../..' . '/compatibility/class-wcml-gravityforms.php',
141
+ 'WCML_sensei' => __DIR__ . '/../..' . '/compatibility/class-wcml-sensei.php',
142
+ 'WCML_wcExporter' => __DIR__ . '/../..' . '/compatibility/class-wcml-wcexporter.php',
143
+ 'WCML_xDomain_Data' => __DIR__ . '/../..' . '/inc/class-wcml-xdomain-data.php',
144
+ 'WPML_Templates_Factory' => __DIR__ . '/../..' . '/inc/template-classes/class-wpml-templates-factory.php',
145
+ 'woocommerce_wpml' => __DIR__ . '/../..' . '/inc/class-woocommerce-wpml.php',
146
+ );
147
+
148
+ public static function getInitializer(ClassLoader $loader)
149
+ {
150
+ return \Closure::bind(function () use ($loader) {
151
+ $loader->prefixLengthsPsr4 = ComposerStaticInit00dcbeb0e1eb354a5d439568c0e22365::$prefixLengthsPsr4;
152
+ $loader->prefixDirsPsr4 = ComposerStaticInit00dcbeb0e1eb354a5d439568c0e22365::$prefixDirsPsr4;
153
+ $loader->prefixesPsr0 = ComposerStaticInit00dcbeb0e1eb354a5d439568c0e22365::$prefixesPsr0;
154
+ $loader->classMap = ComposerStaticInit00dcbeb0e1eb354a5d439568c0e22365::$classMap;
155
+
156
+ }, null, ClassLoader::class);
157
+ }
158
+ }
embedded/composer/installed.json CHANGED
@@ -1,37 +1,4 @@
1
  [
2
- {
3
- "name": "xrstf/composer-php52",
4
- "version": "v1.0.20",
5
- "version_normalized": "1.0.20.0",
6
- "source": {
7
- "type": "git",
8
- "url": "https://github.com/composer-php52/composer-php52.git",
9
- "reference": "bd41459d5e27df8d33057842b32377c39e97a5a8"
10
- },
11
- "dist": {
12
- "type": "zip",
13
- "url": "https://api.github.com/repos/composer-php52/composer-php52/zipball/bd41459d5e27df8d33057842b32377c39e97a5a8",
14
- "reference": "bd41459d5e27df8d33057842b32377c39e97a5a8",
15
- "shasum": ""
16
- },
17
- "time": "2016-04-16 21:52:24",
18
- "type": "library",
19
- "extra": {
20
- "branch-alias": {
21
- "dev-default": "1.x-dev"
22
- }
23
- },
24
- "installation-source": "dist",
25
- "autoload": {
26
- "psr-0": {
27
- "xrstf\\Composer52": "lib/"
28
- }
29
- },
30
- "notification-url": "https://packagist.org/downloads/",
31
- "license": [
32
- "MIT"
33
- ]
34
- },
35
  {
36
  "name": "composer/installers",
37
  "version": "v1.1.0",
@@ -138,12 +105,12 @@
138
  },
139
  {
140
  "name": "otgs/installer",
141
- "version": "1.7.9",
142
- "version_normalized": "1.7.9.0",
143
  "source": {
144
  "type": "git",
145
  "url": "ssh://git@git.onthegosystems.com:10022/installer/installer.git",
146
- "reference": "2efbb75db7daf72bfd6bb5391f61b6155f39c225"
147
  },
148
  "require": {
149
  "composer/installers": "~1.0",
@@ -152,7 +119,7 @@
152
  "require-dev": {
153
  "phpunit/phpunit": "~4.5"
154
  },
155
- "time": "2016-07-05 06:21:57",
156
  "type": "library",
157
  "extra": {
158
  "branch-alias": {
@@ -184,5 +151,38 @@
184
  "update",
185
  "utils"
186
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  }
188
  ]
1
  [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  {
3
  "name": "composer/installers",
4
  "version": "v1.1.0",
105
  },
106
  {
107
  "name": "otgs/installer",
108
+ "version": "dev-master",
109
+ "version_normalized": "9999999-dev",
110
  "source": {
111
  "type": "git",
112
  "url": "ssh://git@git.onthegosystems.com:10022/installer/installer.git",
113
+ "reference": "fc4f8ad6696493a7416929b9815455960f476101"
114
  },
115
  "require": {
116
  "composer/installers": "~1.0",
119
  "require-dev": {
120
  "phpunit/phpunit": "~4.5"
121
  },
122
+ "time": "2016-08-03 09:59:11",
123
  "type": "library",
124
  "extra": {
125
  "branch-alias": {
151
  "update",
152
  "utils"
153
  ]
154
+ },
155
+ {
156
+ "name": "xrstf/composer-php52",
157
+ "version": "v1.0.20",
158
+ "version_normalized": "1.0.20.0",
159
+ "source": {
160
+ "type": "git",
161
+ "url": "https://github.com/composer-php52/composer-php52.git",
162
+ "reference": "bd41459d5e27df8d33057842b32377c39e97a5a8"
163
+ },
164
+ "dist": {
165
+ "type": "zip",
166
+ "url": "https://api.github.com/repos/composer-php52/composer-php52/zipball/bd41459d5e27df8d33057842b32377c39e97a5a8",
167
+ "reference": "bd41459d5e27df8d33057842b32377c39e97a5a8",
168
+ "shasum": ""
169
+ },
170
+ "time": "2016-04-16 21:52:24",
171
+ "type": "library",
172
+ "extra": {
173
+ "branch-alias": {
174
+ "dev-default": "1.x-dev"
175
+ }
176
+ },
177
+ "installation-source": "dist",
178
+ "autoload": {
179
+ "psr-0": {
180
+ "xrstf\\Composer52": "lib/"
181
+ }
182
+ },
183
+ "notification-url": "https://packagist.org/downloads/",
184
+ "license": [
185
+ "MIT"
186
+ ]
187
  }
188
  ]
embedded/composer/installers/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ vendor/
2
+ composer.lock
3
+ .idea/
embedded/composer/installers/composer.json CHANGED
@@ -19,6 +19,7 @@
19
  "Dolibarr",
20
  "Drupal",
21
  "Elgg",
 
22
  "FuelPHP",
23
  "Grav",
24
  "Hurad",
@@ -39,6 +40,7 @@
39
  "phpBB",
40
  "PPI",
41
  "Puppet",
 
42
  "Roundcube",
43
  "shopware",
44
  "SilverStripe",
19
  "Dolibarr",
20
  "Drupal",
21
  "Elgg",
22
+ "ExpressionEngine",
23
  "FuelPHP",
24
  "Grav",
25
  "Hurad",
40
  "phpBB",
41
  "PPI",
42
  "Puppet",
43
+ "RadPHP",
44
  "Roundcube",
45
  "shopware",
46
  "SilverStripe",
embedded/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\AsgardInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class AsgardInstallerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ /**
11
+ * @var OctoberInstaller
12
+ */
13
+ private $installer;
14
+
15
+ public function setUp()
16
+ {
17
+ $this->installer = new AsgardInstaller(
18
+ new Package('NyanCat', '4.2', '4.2'),
19
+ new Composer()
20
+ );
21
+ }
22
+
23
+ /**
24
+ * @dataProvider packageNameInflectionProvider
25
+ */
26
+ public function testInflectPackageVars($type, $name, $expected)
27
+ {
28
+ $this->assertEquals(
29
+ $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)),
30
+ array('name' => $expected, 'type' => $type)
31
+ );
32
+ }
33
+
34
+ public function packageNameInflectionProvider()
35
+ {
36
+ return array(
37
+ array(
38
+ 'asgard-module',
39
+ 'asgard-module',
40
+ 'Asgard'
41
+ ),
42
+ array(
43
+ 'asgard-module',
44
+ 'blog',
45
+ 'Blog'
46
+ ),
47
+ // tests that exactly one '-theme' is cut off
48
+ array(
49
+ 'asgard-theme',
50
+ 'some-theme-theme',
51
+ 'Some-theme',
52
+ ),
53
+ // tests that names without '-theme' suffix stay valid
54
+ array(
55
+ 'asgard-theme',
56
+ 'someothertheme',
57
+ 'Someothertheme',
58
+ ),
59
+ );
60
+ }
61
+ }
embedded/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\CakePHPInstaller;
5
+ use Composer\Repository\RepositoryManager;
6
+ use Composer\Repository\InstalledArrayRepository;
7
+ use Composer\Package\Package;
8
+ use Composer\Package\RootPackage;
9
+ use Composer\Package\Link;
10
+ use Composer\Package\Version\VersionParser;
11
+ use Composer\Composer;
12
+ use Composer\Config;
13
+
14
+ class CakePHPInstallerTest extends TestCase
15
+ {
16
+ private $composer;
17
+ private $io;
18
+
19
+ /**
20
+ * setUp
21
+ *
22
+ * @return void
23
+ */
24
+ public function setUp()
25
+ {
26
+ $this->package = new Package('CamelCased', '1.0', '1.0');
27
+ $this->io = $this->getMock('Composer\IO\PackageInterface');
28
+ $this->composer = new Composer();
29
+ $this->composer->setConfig(new Config(false));
30
+ }
31
+
32
+ /**
33
+ * testInflectPackageVars
34
+ *
35
+ * @return void
36
+ */
37
+ public function testInflectPackageVars()
38
+ {
39
+ $installer = new CakePHPInstaller($this->package, $this->composer);
40
+ $result = $installer->inflectPackageVars(array('name' => 'CamelCased'));
41
+ $this->assertEquals($result, array('name' => 'CamelCased'));
42
+
43
+ $installer = new CakePHPInstaller($this->package, $this->composer);
44
+ $result = $installer->inflectPackageVars(array('name' => 'with-dash'));
45
+ $this->assertEquals($result, array('name' => 'WithDash'));
46
+
47
+ $installer = new CakePHPInstaller($this->package, $this->composer);
48
+ $result = $installer->inflectPackageVars(array('name' => 'with_underscore'));
49
+ $this->assertEquals($result, array('name' => 'WithUnderscore'));
50
+
51
+ $installer = new CakePHPInstaller($this->package, $this->composer);
52
+ $result = $installer->inflectPackageVars(array('name' => 'cake/acl'));
53
+ $this->assertEquals($result, array('name' => 'Cake/Acl'));
54
+
55
+ $installer = new CakePHPInstaller($this->package, $this->composer);
56
+ $result = $installer->inflectPackageVars(array('name' => 'cake/debug-kit'));
57
+ $this->assertEquals($result, array('name' => 'Cake/DebugKit'));
58
+ }
59
+
60
+ /**
61
+ * Test getLocations returning appropriate values based on CakePHP version
62
+ *
63
+ */
64
+ public function testGetLocations() {
65
+ $package = new RootPackage('CamelCased', '1.0', '1.0');
66
+ $composer = $this->composer;
67
+ $rm = new RepositoryManager(
68
+ $this->getMock('Composer\IO\IOInterface'),
69
+ $this->getMock('Composer\Config')
70
+ );
71
+ $composer->setRepositoryManager($rm);
72
+ $installer = new CakePHPInstaller($package, $composer);
73
+
74
+ // 2.0 < cakephp < 3.0
75
+ $this->setCakephpVersion($rm, '2.0.0');
76
+ $result = $installer->getLocations();
77
+ $this->assertContains('Plugin/', $result['plugin']);
78
+
79
+ $this->setCakephpVersion($rm, '2.5.9');
80
+ $result = $installer->getLocations();
81
+ $this->assertContains('Plugin/', $result['plugin']);
82
+
83
+ $this->setCakephpVersion($rm, '~2.5');
84
+ $result = $installer->getLocations();
85
+ $this->assertContains('Plugin/', $result['plugin']);
86
+
87
+ // special handling for 2.x versions when 3.x is still in development
88
+ $this->setCakephpVersion($rm, 'dev-master');
89
+ $result = $installer->getLocations();
90
+ $this->assertContains('Plugin/', $result['plugin']);
91
+
92
+ $this->setCakephpVersion($rm, '>=2.5');
93
+ $result = $installer->getLocations();
94
+ $this->assertContains('Plugin/', $result['plugin']);
95
+
96
+ // cakephp >= 3.0
97
+ $this->setCakephpVersion($rm, '3.0.*-dev');
98
+ $result = $installer->getLocations();
99
+ $this->assertContains('vendor/{$vendor}/{$name}/', $result['plugin']);
100
+
101
+ $this->setCakephpVersion($rm, '~8.8');
102
+ $result = $installer->getLocations();
103
+ $this->assertContains('vendor/{$vendor}/{$name}/', $result['plugin']);
104
+ }
105
+
106
+ protected function setCakephpVersion($rm, $version) {
107
+ $parser = new VersionParser();
108
+ list(, $version) = explode(' ', $parser->parseConstraints($version));
109
+ $installed = new InstalledArrayRepository();
110
+ $package = new Package('cakephp/cakephp', $version, $version);
111
+ $installed->addPackage($package);
112
+ $rm->setLocalRepository($installed);
113
+ }
114
+
115
+ }
embedded/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers\Test;
4
+
5
+ use Composer\Installers\CraftInstaller;
6
+
7
+ /**
8
+ * Tests for the CraftInstaller Class
9
+ *
10
+ * @coversDefaultClass Composer\Installers\CraftInstaller
11
+ */
12
+ class CraftInstallerTest extends TestCase
13
+ {
14
+ /** @var CraftInstaller */
15
+ private $installer;
16
+
17
+ /**
18
+ * Sets up the fixture, for example, instantiate the class-under-test.
19
+ *
20
+ * This method is called before a test is executed.
21
+ */
22
+ final public function setup()
23
+ {
24
+ $this->installer = new CraftInstaller();
25
+ }
26
+
27
+ /**
28
+ * @param string $packageName
29
+ * @param string $expectedName
30
+ *
31
+ * @covers ::inflectPackageVars
32
+ *
33
+ * @dataProvider provideExpectedInflectionResults
34
+ */
35
+ final public function testInflectPackageVars($packageName, $expectedName)
36
+ {
37
+ $installer = $this->installer;
38
+
39
+ $vars = array('name' => $packageName);
40
+ $expected = array('name' => $expectedName);
41
+
42
+ $actual = $installer->inflectPackageVars($vars);
43
+
44
+ $this->assertEquals($actual, $expected);
45
+ }
46
+
47
+ /**
48
+ * Provides various names for packages and the expected result after inflection
49
+ *
50
+ * @return array
51
+ */
52
+ final public function provideExpectedInflectionResults()
53
+ {
54
+ return array(
55
+ // lowercase
56
+ array('foo', 'foo'),
57
+ array('craftfoo', 'craftfoo'),
58
+ array('fooplugin', 'fooplugin'),
59
+ array('craftfooplugin', 'craftfooplugin'),
60
+ // lowercase - dash
61
+ array('craft-foo', 'foo'),
62
+ array('foo-plugin', 'foo'),
63
+ array('craft-foo-plugin', 'foo'),
64
+ // lowercase - underscore
65
+ array('craft_foo', 'craft_foo'),
66
+ array('foo_plugin', 'foo_plugin'),
67
+ array('craft_foo_plugin', 'craft_foo_plugin'),
68
+ // CamelCase
69
+ array('Foo', 'Foo'),
70
+ array('CraftFoo', 'CraftFoo'),
71
+ array('FooPlugin', 'FooPlugin'),
72
+ array('CraftFooPlugin', 'CraftFooPlugin'),
73
+ // CamelCase - Dash
74
+ array('Craft-Foo', 'Foo'),
75
+ array('Foo-Plugin', 'Foo'),
76
+ array('Craft-Foo-Plugin', 'Foo'),
77
+ // CamelCase - underscore
78
+ array('Craft_Foo', 'Craft_Foo'),
79
+ array('Foo_Plugin', 'Foo_Plugin'),
80
+ array('Craft_Foo_Plugin', 'Craft_Foo_Plugin'),
81
+ );
82
+ }
83
+ }
embedded/composer/installers/tests/Composer/Installers/Test/DokuWikiInstallerTest.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\DokuWikiInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class DokuWikiInstallerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ /**
11
+ * @var DokuWikiInstaller
12
+ */
13
+ private $installer;
14
+
15
+ public function setUp()
16
+ {
17
+ $this->installer = new DokuWikiInstaller(
18
+ new Package('NyanCat', '4.2', '4.2'),
19
+ new Composer()
20
+ );
21
+ }
22
+
23
+ /**
24
+ * @dataProvider packageNameInflectionProvider
25
+ */
26
+ public function testInflectPackageVars($type, $name, $expected)
27
+ {
28
+ $this->assertEquals(
29
+ $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)),
30
+ array('name' => $expected, 'type'=>$type)
31
+ );
32
+ }
33
+
34
+ public function packageNameInflectionProvider()
35
+ {
36
+ return array(
37
+ array(
38
+ 'dokuwiki-plugin',
39
+ 'dokuwiki-test-plugin',
40
+ 'test',
41
+ ),
42
+ array(
43
+ 'dokuwiki-plugin',
44
+ 'test-plugin',
45
+ 'test',
46
+ ),
47
+ array(
48
+ 'dokuwiki-plugin',
49
+ 'dokuwiki_test',
50
+ 'test',
51
+ ),
52
+ array(
53
+ 'dokuwiki-plugin',
54
+ 'test',
55
+ 'test',
56
+ ),
57
+ array(
58
+ 'dokuwiki-plugin',
59
+ 'test-template',
60
+ 'test-template',
61
+ ),
62
+ array(
63
+ 'dokuwiki-template',
64
+ 'dokuwiki-test-template',
65
+ 'test',
66
+ ),
67
+ array(
68
+ 'dokuwiki-template',
69
+ 'test-template',
70
+ 'test',
71
+ ),
72
+ array(
73
+ 'dokuwiki-template',
74
+ 'dokuwiki_test',
75
+ 'test',
76
+ ),
77
+ array(
78
+ 'dokuwiki-template',
79
+ 'test',
80
+ 'test',
81
+ ),
82
+ array(
83
+ 'dokuwiki-template',
84
+ 'test-plugin',
85
+ 'test-plugin',
86
+ ),
87
+ );
88
+ }
89
+ }
embedded/composer/installers/tests/Composer/Installers/Test/GravInstallerTest.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Composer;
5
+ use Composer\Installers\GravInstaller;
6
+
7
+ class GravInstallerTest extends TestCase
8
+ {
9
+ /* @var \Composer\Composer */
10
+ protected $composer;
11
+
12
+ public function setUp()
13
+ {
14
+ $this->composer = new Composer();
15
+ }
16
+
17
+ public function testInflectPackageVars()
18
+ {
19
+ $package = $this->getPackage('vendor/name', '0.0.0');
20
+ $installer = new GravInstaller($package, $this->composer);
21
+ $packageVars = $this->getPackageVars($package);
22
+
23
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => 'test')));
24
+ $this->assertEquals('test', $result['name']);
25
+
26
+ foreach ($installer->getLocations() as $name => $location) {
27
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "$name-test")));
28
+ $this->assertEquals('test', $result['name']);
29
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "test-$name")));
30
+ $this->assertEquals('test', $result['name']);
31
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "$name-test-test")));
32
+ $this->assertEquals('test-test', $result['name']);
33
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "test-test-$name")));
34
+ $this->assertEquals('test-test', $result['name']);
35
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-$name-test")));
36
+ $this->assertEquals('test', $result['name']);
37
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-test-$name")));
38
+ $this->assertEquals('test', $result['name']);
39
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-$name-test-test")));
40
+ $this->assertEquals('test-test', $result['name']);
41
+ $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-test-test-$name")));
42
+ $this->assertEquals('test-test', $result['name']);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * @param $package \Composer\Package\PackageInterface
48
+ */
49
+ public function getPackageVars($package)
50
+ {
51
+ $type = $package->getType();
52
+
53
+ $prettyName = $package->getPrettyName();
54
+ if (strpos($prettyName, '/') !== false) {
55
+ list($vendor, $name) = explode('/', $prettyName);
56
+ } else {
57
+ $vendor = '';
58
+ $name = $prettyName;
59
+ }
60
+
61
+ return compact('name', 'vendor', 'type');
62
+ }
63
+ }
embedded/composer/installers/tests/Composer/Installers/Test/InstallerTest.php ADDED
@@ -0,0 +1,476 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\Installer;
5
+ use Composer\Util\Filesystem;
6
+ use Composer\Package\Package;
7
+ use Composer\Package\RootPackage;
8
+ use Composer\Composer;
9
+ use Composer\Config;
10
+
11
+ class InstallerTest extends TestCase
12
+ {
13
+ private $composer;
14
+ private $config;
15
+ private $vendorDir;
16
+ private $binDir;
17
+ private $dm;
18
+ private $repository;
19
+ private $io;
20
+ private $fs;
21
+
22
+ /**
23
+ * setUp
24
+ *
25
+ * @return void
26
+ */
27
+ public function setUp()
28
+ {
29
+ $this->fs = new Filesystem;
30
+
31
+ $this->composer = new Composer();
32
+ $this->config = new Config();
33
+ $this->composer->setConfig($this->config);
34
+
35
+ $this->vendorDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'baton-test-vendor';
36
+ $this->ensureDirectoryExistsAndClear($this->vendorDir);
37
+
38
+ $this->binDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'baton-test-bin';
39
+ $this->ensureDirectoryExistsAndClear($this->binDir);
40
+
41
+ $this->config->merge(array(
42
+ 'config' => array(
43
+ 'vendor-dir' => $this->vendorDir,
44
+ 'bin-dir' => $this->binDir,
45
+ ),
46
+ ));
47
+
48
+ $this->dm = $this->getMockBuilder('Composer\Downloader\DownloadManager')
49
+ ->disableOriginalConstructor()
50
+ ->getMock();
51
+ $this->composer->setDownloadManager($this->dm);
52
+
53
+ $this->repository = $this->getMock('Composer\Repository\InstalledRepositoryInterface');
54
+ $this->io = $this->getMock('Composer\IO\IOInterface');
55
+ }
56
+
57
+ /**
58
+ * tearDown
59
+ *
60
+ * @return void
61
+ */
62
+ public function tearDown()
63
+ {
64
+ $this->fs->removeDirectory($this->vendorDir);
65
+ $this->fs->removeDirectory($this->binDir);
66
+ }
67
+
68
+ /**
69
+ * testSupports
70
+ *
71
+ * @return void
72
+ *
73
+ * @dataProvider dataForTestSupport
74
+ */
75
+ public function testSupports($type, $expected)
76
+ {
77
+ $installer = new Installer($this->io, $this->composer);
78
+ $this->assertSame($expected, $installer->supports($type), sprintf('Failed to show support for %s', $type));
79
+ }
80
+
81
+ /**
82
+ * dataForTestSupport
83
+ */
84
+ public function dataForTestSupport()
85
+ {
86
+ return array(
87
+ array('agl-module', true),
88
+ array('aimeos-extension', true),
89
+ array('annotatecms-module', true),
90
+ array('annotatecms-component', true),
91
+ array('annotatecms-service', true),
92
+ array('bitrix-module', true),
93
+ array('bitrix-component', true),
94
+ array('bitrix-theme', true),
95
+ array('bonefish-package', true),
96
+ array('cakephp', false),
97
+ array('cakephp-', false),
98
+ array('cakephp-app', false),
99
+ array('cakephp-plugin', true),
100
+ array('chef-cookbook', true),
101
+ array('chef-role', true),
102
+ array('codeigniter-app', false),
103
+ array('codeigniter-library', true),
104
+ array('codeigniter-third-party', true),
105
+ array('codeigniter-module', true),
106
+ array('concrete5-block', true),
107
+ array('concrete5-package', true),
108
+ array('concrete5-theme', true),
109
+ array('concrete5-update', true),
110
+ array('craft-plugin', true),
111
+ array('croogo-plugin', true),
112
+ array('croogo-theme', true),
113
+ array('decibel-app', true),
114
+ array('dokuwiki-plugin', true),
115
+ array('dokuwiki-template', true),
116
+ array('drupal-module', true),
117
+ array('dolibarr-module', true),
118
+ array('ee3-theme', true),
119
+ array('ee3-addon', true),
120
+ array('ee2-theme', true),
121
+ array('ee2-addon', true),
122
+ array('elgg-plugin', true),
123
+ array('fuel-module', true),
124
+ array('fuel-package', true),
125
+ array('fuel-theme', true),
126
+ array('fuelphp-component', true),
127
+ array('hurad-plugin', true),
128
+ array('hurad-theme', true),
129
+ array('imagecms-template', true),
130
+ array('imagecms-module', true),
131
+ array('imagecms-library', true),
132
+ array('joomla-library', true),
133
+ array('kirby-plugin', true),
134
+ array('kohana-module', true),
135
+ array('laravel-library', true),
136
+ array('lithium-library', true),
137
+ array('magento-library', true),
138
+ array('mako-package', true),
139
+ array('modxevo-snippet', true),
140
+ array('modxevo-plugin', true),
141
+ array('modxevo-module', true),
142
+ array('modxevo-template', true),
143
+ array('modxevo-lib', true),
144
+ array('mediawiki-extension', true),
145
+ array('mediawiki-skin', true),
146
+ array('microweber-module', true),
147
+ array('modulework-module', true),
148
+ array('moodle-mod', true),
149
+ array('october-module', true),
150
+ array('october-plugin', true),
151
+ array('piwik-plugin', true),
152
+ array('phpbb-extension', true),
153
+ array('pimcore-plugin', true),
154
+ array('ppi-module', true),
155
+ array('prestashop-module', true),
156
+ array('prestashop-theme', true),
157
+ array('puppet-module', true),
158
+ array('radphp-bundle', true),
159
+ array('redaxo-addon', true),
160
+ array('redaxo-bestyle-plugin', true),
161
+ array('roundcube-plugin', true),
162
+ array('shopware-backend-plugin', true),
163
+ array('shopware-core-plugin', true),
164
+ array('shopware-frontend-plugin', true),
165
+ array('shopware-theme', true),
166
+ array('silverstripe-module', true),
167
+ array('silverstripe-theme', true),
168
+ array('smf-module', true),
169
+ array('smf-theme', true),
170
+ array('symfony1-plugin', true),
171
+ array('thelia-module', true),
172
+ array('thelia-frontoffice-template', true),
173
+ array('thelia-backoffice-template', true),
174
+ array('thelia-email-template', true),
175
+ array('tusk-task', true),
176
+ array('tusk-asset', true),
177
+ array('typo3-flow-plugin', true),
178
+ array('typo3-cms-extension', true),
179
+ array('whmcs-gateway', true),
180
+ array('wolfcms-plugin', true),
181
+ array('wordpress-plugin', true),
182
+ array('wordpress-core', false),
183
+ array('zend-library', true),
184
+ array('zikula-module', true),
185
+ array('zikula-theme', true),
186
+ array('kodicms-plugin', true),
187
+ array('kodicms-media', true),
188
+ array('phifty-bundle', true),
189
+ array('phifty-library', true),
190
+ array('phifty-framework', true),
191
+ );
192
+ }
193
+
194
+ /**
195
+ * testInstallPath
196
+ *
197
+ * @dataProvider dataForTestInstallPath
198
+ */
199
+ public function testInstallPath($type, $path, $name, $version = '1.0.0')
200
+ {
201
+ $installer = new Installer($this->io, $this->composer);
202
+ $package = new Package($name, $version, $version);
203
+
204
+ $package->setType($type);
205
+ $result = $installer->getInstallPath($package);
206
+ $this->assertEquals($path, $result);
207
+ }
208
+
209
+ /**
210
+ * dataFormTestInstallPath
211
+ */
212
+ public function dataForTestInstallPath()
213
+ {
214
+ return array(
215
+ array('agl-module', 'More/MyTestPackage/', 'agl/my_test-package'),
216
+ array('aimeos-extension', 'ext/ai-test/', 'author/ai-test'),
217
+ array('annotatecms-module', 'addons/modules/my_module/', 'vysinsky/my_module'),
218
+ array('annotatecms-component', 'addons/components/my_component/', 'vysinsky/my_component'),
219
+ array('annotatecms-service', 'addons/services/my_service/', 'vysinsky/my_service'),
220
+ array('bitrix-module', 'bitrix/modules/my_module/', 'author/my_module'),
221
+ array('bitrix-component', 'bitrix/components/my_component/', 'author/my_component'),
222
+ array('bitrix-theme', 'bitrix/templates/my_theme/', 'author/my_theme'),
223
+ array('bitrix-d7-module', 'bitrix/modules/author.my_module/', 'author/my_module'),
224
+ array('bitrix-d7-component', 'bitrix/components/author/my_component/', 'author/my_component'),
225
+ array('bitrix-d7-template', 'bitrix/templates/author_my_template/', 'author/my_template'),
226
+ array('bonefish-package', 'Packages/bonefish/package/', 'bonefish/package'),
227
+ array('cakephp-plugin', 'Plugin/Ftp/', 'shama/ftp'),
228
+ array('chef-cookbook', 'Chef/mre/my_cookbook/', 'mre/my_cookbook'),
229
+ array('chef-role', 'Chef/roles/my_role/', 'mre/my_role'),
230
+ array('codeigniter-library', 'application/libraries/my_package/', 'shama/my_package'),
231
+ array('codeigniter-module', 'application/modules/my_package/', 'shama/my_package'),
232
+ array('concrete5-block', 'blocks/concrete5_block/', 'remo/concrete5_block'),
233
+ array('concrete5-package', 'packages/concrete5_package/', 'remo/concrete5_package'),
234
+ array('concrete5-theme', 'themes/concrete5_theme/', 'remo/concrete5_theme'),
235
+ array('concrete5-update', 'updates/concrete5/', 'concrete5/concrete5'),
236
+ array('craft-plugin', 'craft/plugins/my_plugin/', 'mdcpepper/my_plugin'),
237
+ array('croogo-plugin', 'Plugin/Sitemaps/', 'fahad19/sitemaps'),
238
+ array('croogo-theme', 'View/Themed/Readable/', 'rchavik/readable'),
239
+ array('decibel-app', 'app/someapp/', 'author/someapp'),
240
+ array('dokuwiki-plugin', 'lib/plugins/someplugin/', 'author/someplugin'),
241
+ array('dokuwiki-template', 'lib/tpl/sometemplate/', 'author/sometemplate'),
242
+ array('dolibarr-module', 'htdocs/custom/my_module/', 'shama/my_module'),
243
+ array('drupal-module', 'modules/my_module/', 'shama/my_module'),
244
+ array('drupal-theme', 'themes/my_module/', 'shama/my_module'),
245
+ array('drupal-profile', 'profiles/my_module/', 'shama/my_module'),
246
+ array('drupal-drush', 'drush/my_module/', 'shama/my_module'),
247
+ array('elgg-plugin', 'mod/sample_plugin/', 'test/sample_plugin'),
248
+ array('ee3-addon', 'system/user/addons/ee_theme/', 'author/ee_theme'),
249
+ array('ee3-theme', 'themes/user/ee_package/', 'author/ee_package'),
250
+ array('ee2-addon', 'system/expressionengine/third-party/ee_theme/', 'author/ee_theme'),
251
+ array('ee2-theme', 'themes/third-party/ee_package/', 'author/ee_package'),
252
+ array('fuel-module', 'fuel/app/modules/module/', 'fuel/module'),
253
+ array('fuel-package', 'fuel/packages/orm/', 'fuel/orm'),
254
+ array('fuel-theme', 'fuel/app/themes/theme/', 'fuel/theme'),
255
+ array('fuelphp-component', 'components/demo/', 'fuelphp/demo'),
256
+ array('hurad-plugin', 'plugins/Akismet/', 'atkrad/akismet'),
257
+ array('hurad-theme', 'plugins/Hurad2013/', 'atkrad/Hurad2013'),
258
+ array('imagecms-template', 'templates/my_template/', 'shama/my_template'),
259
+ array('imagecms-module', 'application/modules/my_module/', 'shama/my_module'),
260
+ array('imagecms-library', 'application/libraries/my_library/', 'shama/my_library'),
261
+ array('joomla-plugin', 'plugins/my_plugin/', 'shama/my_plugin'),
262
+ array('kirby-plugin', 'site/plugins/my_plugin/', 'shama/my_plugin'),
263
+ array('kohana-module', 'modules/my_package/', 'shama/my_package'),
264
+ array('laravel-library', 'libraries/my_package/', 'shama/my_package'),
265
+ array('lithium-library', 'libraries/li3_test/', 'user/li3_test'),
266
+ array('magento-library', 'lib/foo/', 'test/foo'),
267
+ array('modxevo-snippet', 'assets/snippets/my_snippet/', 'shama/my_snippet'),
268
+ array('modxevo-plugin', 'assets/plugins/my_plugin/', 'shama/my_plugin'),
269
+ array('modxevo-module', 'assets/modules/my_module/', 'shama/my_module'),
270
+ array('modxevo-template', 'assets/templates/my_template/', 'shama/my_template'),
271
+ array('modxevo-lib', 'assets/lib/my_lib/', 'shama/my_lib'),
272
+ array('mako-package', 'app/packages/my_package/', 'shama/my_package'),
273
+ array('mediawiki-extension', 'extensions/APC/', 'author/APC'),
274
+ array('mediawiki-extension', 'extensions/APC/', 'author/APC-extension'),
275
+ array('mediawiki-extension', 'extensions/UploadWizard/', 'author/upload-wizard'),
276
+ array('mediawiki-extension', 'extensions/SyntaxHighlight_GeSHi/', 'author/syntax-highlight_GeSHi'),
277
+ array('mediawiki-skin', 'skins/someskin/', 'author/someskin-skin'),
278
+ array('mediawiki-skin', 'skins/someskin/', 'author/someskin'),
279
+ array('microweber-module', 'userfiles/modules/my-thing/', 'author/my-thing-module'),
280
+ array('modulework-module', 'modules/my_package/', 'shama/my_package'),
281
+ array('moodle-mod', 'mod/my_package/', 'shama/my_package'),
282
+ array('october-module', 'modules/my_plugin/', 'shama/my_plugin'),
283
+ array('october-plugin', 'plugins/shama/my_plugin/', 'shama/my_plugin'),
284
+ array('october-theme', 'themes/my_theme/', 'shama/my_theme'),
285
+ array('piwik-plugin', 'plugins/VisitSummary/', 'shama/visit-summary'),
286
+ array('prestashop-module', 'modules/a-module/', 'vendor/a-module'),
287
+ array('prestashop-theme', 'themes/a-theme/', 'vendor/a-theme'),
288
+ array('phpbb-extension', 'ext/test/foo/', 'test/foo'),
289
+ array('phpbb-style', 'styles/foo/', 'test/foo'),
290
+ array('phpbb-language', 'language/foo/', 'test/foo'),
291
+ array('pimcore-plugin', 'plugins/MyPlugin/', 'ubikz/my_plugin'),
292
+ array('ppi-module', 'modules/foo/', 'test/foo'),
293
+ array('puppet-module', 'modules/puppet-name/', 'puppet/puppet-name'),
294
+ array('radphp-bundle', 'src/Migration/', 'atkrad/migration'),
295
+ array('redaxo-addon', 'redaxo/include/addons/my_plugin/', 'shama/my_plugin'),
296
+ array('redaxo-bestyle-plugin', 'redaxo/include/addons/be_style/plugins/my_plugin/', 'shama/my_plugin'),
297
+ array('roundcube-plugin', 'plugins/base/', 'test/base'),
298
+ array('roundcube-plugin', 'plugins/replace_dash/', 'test/replace-dash'),
299
+ array('shopware-backend-plugin', 'engine/Shopware/Plugins/Local/Backend/ShamaMyBackendPlugin/', 'shama/my-backend-plugin'),
300
+ array('shopware-core-plugin', 'engine/Shopware/Plugins/Local/Core/ShamaMyCorePlugin/', 'shama/my-core-plugin'),
301
+ array('shopware-frontend-plugin', 'engine/Shopware/Plugins/Local/Frontend/ShamaMyFrontendPlugin/', 'shama/my-frontend-plugin'),
302
+ array('shopware-theme', 'templates/my_theme/', 'shama/my-theme'),
303
+ array('silverstripe-module', 'my_module/', 'shama/my_module'),
304
+ array('silverstripe-module', 'sapphire/', 'silverstripe/framework', '2.4.0'),
305
+ array('silverstripe-module', 'framework/', 'silverstripe/framework', '3.0.0'),
306
+ array('silverstripe-module', 'framework/', 'silverstripe/framework', '3.0.0-rc1'),
307
+ array('silverstripe-module', 'framework/', 'silverstripe/framework', 'my/branch'),
308
+ array('silverstripe-theme', 'themes/my_theme/', 'shama/my_theme'),
309
+ array('smf-module', 'Sources/my_module/', 'shama/my_module'),
310
+ array('smf-theme', 'Themes/my_theme/', 'shama/my_theme'),
311
+ array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sfShamaPlugin'),
312
+ array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sf-shama-plugin'),
313
+ array('thelia-module', 'local/modules/my_module/', 'shama/my_module'),
314
+ array('thelia-frontoffice-template', 'templates/frontOffice/my_template_fo/', 'shama/my_template_fo'),
315
+ array('thelia-backoffice-template', 'templates/backOffice/my_template_bo/', 'shama/my_template_bo'),
316
+ array('thelia-email-template', 'templates/email/my_template_email/', 'shama/my_template_email'),
317
+ array('tusk-task', '.tusk/tasks/my_task/', 'shama/my_task'),
318
+ array('typo3-flow-package', 'Packages/Application/my_package/', 'shama/my_package'),
319
+ array('typo3-flow-build', 'Build/my_package/', 'shama/my_package'),
320
+ array('typo3-cms-extension', 'typo3conf/ext/my_extension/', 'shama/my_extension'),
321
+ array('whmcs-gateway', 'modules/gateways/gateway_name/', 'vendor/gateway_name'),
322
+ array('wolfcms-plugin', 'wolf/plugins/my_plugin/', 'shama/my_plugin'),
323
+ array('wordpress-plugin', 'wp-content/plugins/my_plugin/', 'shama/my_plugin'),
324
+ array('wordpress-muplugin', 'wp-content/mu-plugins/my_plugin/', 'shama/my_plugin'),
325
+ array('zend-extra', 'extras/library/zend_test/', 'shama/zend_test'),
326
+ array('zikula-module', 'modules/my-test_module/', 'my/test_module'),
327
+ array('zikula-theme', 'themes/my-test_theme/', 'my/test_theme'),
328
+ array('kodicms-media', 'cms/media/vendor/my_media/', 'shama/my_media'),
329
+ array('kodicms-plugin', 'cms/plugins/my_plugin/', 'shama/my_plugin'),
330
+ array('phifty-bundle', 'bundles/core/', 'shama/core'),
331
+ array('phifty-library', 'libraries/my-lib/', 'shama/my-lib'),
332
+ array('phifty-framework', 'frameworks/my-framework/', 'shama/my-framework'),
333
+ );
334
+ }
335
+
336
+ /**
337
+ * testGetCakePHPInstallPathException
338
+ *
339
+ * @return void
340
+ *
341
+ * @expectedException \InvalidArgumentException
342
+ */
343
+ public function testGetCakePHPInstallPathException()
344
+ {
345
+ $installer = new Installer($this->io, $this->composer);
346
+ $package = new Package('shama/ftp', '1.0.0', '1.0.0');
347
+
348
+ $package->setType('cakephp-whoops');
349
+ $result = $installer->getInstallPath($package);
350
+ }
351
+
352
+ /**
353
+ * testCustomInstallPath
354
+ */
355
+ public function testCustomInstallPath()
356
+ {
357
+ $installer = new Installer($this->io, $this->composer);
358
+ $package = new Package('shama/ftp', '1.0.0', '1.0.0');
359
+ $package->setType('cakephp-plugin');
360
+ $consumerPackage = new RootPackage('foo/bar', '1.0.0', '1.0.0');
361
+ $this->composer->setPackage($consumerPackage);
362
+ $consumerPackage->setExtra(array(
363
+ 'installer-paths' => array(
364
+ 'my/custom/path/{$name}/' => array(
365
+ 'shama/ftp',
366
+ 'foo/bar',
367
+ ),
368
+ ),
369
+ ));
370
+ $result = $installer->getInstallPath($package);
371
+ $this->assertEquals('my/custom/path/Ftp/', $result);
372
+ }
373
+
374
+ /**
375
+ * testCustomInstallerName
376
+ */
377
+ public function testCustomInstallerName()
378
+ {
379
+ $installer = new Installer($this->io, $this->composer);
380
+ $package = new Package('shama/cakephp-ftp-plugin', '1.0.0', '1.0.0');
381
+ $package->setType('cakephp-plugin');
382
+ $package->setExtra(array(
383
+ 'installer-name' => 'FTP',
384
+ ));
385
+ $result = $installer->getInstallPath($package);
386
+ $this->assertEquals('Plugin/FTP/', $result);
387
+ }
388
+
389
+ /**
390
+ * testCustomTypePath
391
+ */
392
+ public function testCustomTypePath()
393
+ {
394
+ $installer = new Installer($this->io, $this->composer);
395
+ $package = new Package('slbmeh/my_plugin', '1.0.0', '1.0.0');
396
+ $package->setType('wordpress-plugin');
397
+ $consumerPackage = new RootPackage('foo/bar', '1.0.0', '1.0.0');
398
+ $this->composer->setPackage($consumerPackage);
399
+ $consumerPackage->setExtra(array(
400
+ 'installer-paths' => array(
401
+ 'my/custom/path/{$name}/' => array(
402
+ 'type:wordpress-plugin'
403
+ ),
404
+ ),
405
+ ));
406
+ $result = $installer->getInstallPath($package);
407
+ $this->assertEquals('my/custom/path/my_plugin/', $result);
408
+ }
409
+
410
+ /**
411
+ * testVendorPath
412
+ */
413
+ public function testVendorPath()
414
+ {
415
+ $installer = new Installer($this->io, $this->composer);
416
+ $package = new Package('penyaskito/my_module', '1.0.0', '1.0.0');
417
+ $package->setType('drupal-module');
418
+ $consumerPackage = new RootPackage('drupal/drupal', '1.0.0', '1.0.0');
419
+ $this->composer->setPackage($consumerPackage);
420
+ $consumerPackage->setExtra(array(
421
+ 'installer-paths' => array(
422
+ 'modules/custom/{$name}/' => array(
423
+ 'vendor:penyaskito'
424
+ ),
425
+ ),
426
+ ));
427
+ $result = $installer->getInstallPath($package);
428
+ $this->assertEquals('modules/custom/my_module/', $result);
429
+ }
430
+
431
+ /**
432
+ * testNoVendorName
433
+ */
434
+ public function testNoVendorName()
435
+ {
436
+ $installer = new Installer($this->io, $this->composer);
437
+ $package = new Package('sfPhpunitPlugin', '1.0.0', '1.0.0');
438
+
439
+ $package->setType('symfony1-plugin');
440
+ $result = $installer->getInstallPath($package);
441
+ $this->assertEquals('plugins/sfPhpunitPlugin/', $result);
442
+ }
443
+
444
+ /**
445
+ * testTypo3Inflection
446
+ */
447
+ public function testTypo3Inflection()
448
+ {
449
+ $installer = new Installer($this->io, $this->composer);
450
+ $package = new Package('typo3/fluid', '1.0.0', '1.0.0');
451
+
452
+ $package->setAutoload(array(
453
+ 'psr-0' => array(
454
+ 'TYPO3\\Fluid' => 'Classes',
455
+ ),
456
+ ));
457
+
458
+ $package->setType('typo3-flow-package');
459
+ $result = $installer->getInstallPath($package);
460
+ $this->assertEquals('Packages/Application/TYPO3.Fluid/', $result);
461
+ }
462
+
463
+ public function testUninstallAndDeletePackageFromLocalRepo()
464
+ {
465
+ $package = new Package('foo', '1.0.0', '1.0.0');
466
+
467
+ $installer = $this->getMock('Composer\Installers\Installer', array('getInstallPath'), array($this->io, $this->composer));
468
+ $installer->expects($this->once())->method('getInstallPath')->with($package)->will($this->returnValue(sys_get_temp_dir().'/foo'));
469
+
470
+ $repo = $this->getMock('Composer\Repository\InstalledRepositoryInterface');
471
+ $repo->expects($this->once())->method('hasPackage')->with($package)->will($this->returnValue(true));
472
+ $repo->expects($this->once())->method('removePackage')->with($package);
473
+
474
+ $installer->uninstall($repo, $package);
475
+ }
476
+ }
embedded/composer/installers/tests/Composer/Installers/Test/MediaWikiInstallerTest.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\MediaWikiInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class MediaWikiInstallerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ /**
11
+ * @var MediaWikiInstaller
12
+ */
13
+ private $installer;
14
+
15
+ public function setUp()
16
+ {
17
+ $this->installer = new MediaWikiInstaller(
18
+ new Package('NyanCat', '4.2', '4.2'),
19
+ new Composer()
20
+ );
21
+ }
22
+
23
+ /**
24
+ * @dataProvider packageNameInflectionProvider
25
+ */
26
+ public function testInflectPackageVars($type, $name, $expected)
27
+ {
28
+ $this->assertEquals(
29
+ $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)),
30
+ array('name' => $expected, 'type'=>$type)
31
+ );
32
+ }
33
+
34
+ public function packageNameInflectionProvider()
35
+ {
36
+ return array(
37
+ array(
38
+ 'mediawiki-extension',
39
+ 'sub-page-list',
40
+ 'SubPageList',
41
+ ),
42
+ array(
43
+ 'mediawiki-extension',
44
+ 'sub-page-list-extension',
45
+ 'SubPageList',
46
+ ),
47
+ array(
48
+ 'mediawiki-extension',
49
+ 'semantic-mediawiki',
50
+ 'SemanticMediawiki',
51
+ ),
52
+ // tests that exactly one '-skin' is cut off, and that skins do not get ucwords treatment like extensions
53
+ array(
54
+ 'mediawiki-skin',
55
+ 'some-skin-skin',
56
+ 'some-skin',
57
+ ),
58
+ // tests that names without '-skin' suffix stay valid
59
+ array(
60
+ 'mediawiki-skin',
61
+ 'someotherskin',
62
+ 'someotherskin',
63
+ ),
64
+ );
65
+ }
66
+ }
embedded/composer/installers/tests/Composer/Installers/Test/OctoberInstallerTest.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\OctoberInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class OctoberInstallerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ /**
11
+ * @var OctoberInstaller
12
+ */
13
+ private $installer;
14
+
15
+ public function setUp()
16
+ {
17
+ $this->installer = new OctoberInstaller(
18
+ new Package('NyanCat', '4.2', '4.2'),
19
+ new Composer()
20
+ );
21
+ }
22
+
23
+ /**
24
+ * @dataProvider packageNameInflectionProvider
25
+ */
26
+ public function testInflectPackageVars($type, $name, $expected)
27
+ {
28
+ $this->assertEquals(
29
+ $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)),
30
+ array('name' => $expected, 'type' => $type)
31
+ );
32
+ }
33
+
34
+ public function packageNameInflectionProvider()
35
+ {
36
+ return array(
37
+ array(
38
+ 'october-plugin',
39
+ 'subpagelist',
40
+ 'subpagelist',
41
+ ),
42
+ array(
43
+ 'october-plugin',
44
+ 'subpagelist-plugin',
45
+ 'subpagelist',
46
+ ),
47
+ array(
48
+ 'october-plugin',
49
+ 'semanticoctober',
50
+ 'semanticoctober',
51
+ ),
52
+ // tests that exactly one '-theme' is cut off
53
+ array(
54
+ 'october-theme',
55
+ 'some-theme-theme',
56
+ 'some-theme',
57
+ ),
58
+ // tests that names without '-theme' suffix stay valid
59
+ array(
60
+ 'october-theme',
61
+ 'someothertheme',
62
+ 'someothertheme',
63
+ ),
64
+ );
65
+ }
66
+ }
embedded/composer/installers/tests/Composer/Installers/Test/PimcoreInstallerTest.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\PimcoreInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class PimcoreInstallerTest extends TestCase
9
+ {
10
+ private $composer;
11
+ private $io;
12
+
13
+ /**
14
+ * setUp
15
+ *
16
+ * @return void
17
+ */
18
+ public function setUp()
19
+ {
20
+ $this->package = new Package('CamelCased', '1.0', '1.0');
21
+ $this->io = $this->getMock('Composer\IO\PackageInterface');
22
+ $this->composer = new Composer();
23
+ }
24
+
25
+ /**
26
+ * testInflectPackageVars
27
+ *
28
+ * @return void
29
+ */
30
+ public function testInflectPackageVars()
31
+ {
32
+ $installer = new PimcoreInstaller($this->package, $this->composer);
33
+ $result = $installer->inflectPackageVars(array('name' => 'CamelCased'));
34
+ $this->assertEquals($result, array('name' => 'CamelCased'));
35
+
36
+ $installer = new PimcoreInstaller($this->package, $this->composer);
37
+ $result = $installer->inflectPackageVars(array('name' => 'with-dash'));
38
+ $this->assertEquals($result, array('name' => 'WithDash'));
39
+
40
+ $installer = new PimcoreInstaller($this->package, $this->composer);
41
+ $result = $installer->inflectPackageVars(array('name' => 'with_underscore'));
42
+ $this->assertEquals($result, array('name' => 'WithUnderscore'));
43
+ }
44
+ }
embedded/composer/installers/tests/Composer/Installers/Test/PiwikInstallerTest.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Composer;
5
+ use Composer\Installers\PiwikInstaller;
6
+ use Composer\Package\Package;
7
+ use Composer\Package\PackageInterface;
8
+
9
+ /**
10
+ * Class PiwikInstallerTest
11
+ *
12
+ * @package Composer\Installers\Test
13
+ */
14
+ class PiwikInstallerTest extends TestCase
15
+ {
16
+ /**
17
+ * @varComposer
18
+ */
19
+ private $composer;
20
+
21
+ /**
22
+ * @var PackageInterface
23
+ */
24
+ private $io;
25
+
26
+ /**
27
+ * @var Package
28
+ */
29
+ private $package;
30
+
31
+ /**
32
+ * setUp
33
+ *
34
+ * @return void
35
+ */
36
+ public function setUp()
37
+ {
38
+ $this->package = new Package('VisitSummary', '1.0', '1.0');
39
+ $this->io = $this->getMock('Composer\IO\PackageInterface');
40
+ $this->composer = new Composer();
41
+ }
42
+
43
+ /**
44
+ * testInflectPackageVars
45
+ *
46
+ * @return void
47
+ */
48
+ public function testInflectPackageVars()
49
+ {
50
+ $installer = new PiwikInstaller($this->package, $this->composer);
51
+ $result = $installer->inflectPackageVars(array('name' => 'VisitSummary'));
52
+ $this->assertEquals($result, array('name' => 'VisitSummary'));
53
+
54
+ $installer = new PiwikInstaller($this->package, $this->composer);
55
+ $result = $installer->inflectPackageVars(array('name' => 'visit-summary'));
56
+ $this->assertEquals($result, array('name' => 'VisitSummary'));
57
+
58
+ $installer = new PiwikInstaller($this->package, $this->composer);
59
+ $result = $installer->inflectPackageVars(array('name' => 'visit_summary'));
60
+ $this->assertEquals($result, array('name' => 'VisitSummary'));
61
+ }
62
+
63
+ }
embedded/composer/installers/tests/Composer/Installers/Test/TestCase.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Installers\Test;
14
+
15
+ use Composer\Package\Version\VersionParser;
16
+ use Composer\Package\Package;
17
+ use Composer\Package\AliasPackage;
18
+ use Composer\Package\LinkConstraint\VersionConstraint;
19
+ use Composer\Util\Filesystem;
20
+
21
+ abstract class TestCase extends \PHPUnit_Framework_TestCase
22
+ {
23
+ private static $parser;
24
+
25
+ protected static function getVersionParser()
26
+ {
27
+ if (!self::$parser) {
28
+ self::$parser = new VersionParser();
29
+ }
30
+
31
+ return self::$parser;
32
+ }
33
+
34
+ protected function getVersionConstraint($operator, $version)
35
+ {
36
+ return new VersionConstraint(
37
+ $operator,
38
+ self::getVersionParser()->normalize($version)
39
+ );
40
+ }
41
+
42
+ protected function getPackage($name, $version)
43
+ {
44
+ $normVersion = self::getVersionParser()->normalize($version);
45
+
46
+ return new Package($name, $normVersion, $version);
47
+ }
48
+
49
+ protected function getAliasPackage($package, $version)
50
+ {
51
+ $normVersion = self::getVersionParser()->normalize($version);
52
+
53
+ return new AliasPackage($package, $normVersion, $version);
54
+ }
55
+
56
+ protected function ensureDirectoryExistsAndClear($directory)
57
+ {
58
+ $fs = new Filesystem();
59
+ if (is_dir($directory)) {
60
+ $fs->removeDirectory($directory);
61
+ }
62
+ mkdir($directory, 0777, true);
63
+ }
64
+ }
embedded/composer/installers/tests/bootstrap.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+
3
+ $loader = require __DIR__ . '/../src/bootstrap.php';
4
+ $loader->add('Composer\Installers\Test', __DIR__);
embedded/installer/changelog.txt DELETED
@@ -1,133 +0,0 @@
1
- = 1.7.8 =
2
- * Small fix for hiding the WPML registration notice
3
-
4
- = 1.7.7 =
5
- * Fixed js error showing up during registration
6
- * Styles update for unified WPML messages
7
-
8
- = 1.7.6 =
9
- * Updated error messages when validating site keys and stopped removing site keys in case of communication errors
10
- * Added a note for users who renewed or purchased new subscriptions and who need to revalidate their subscription from their websites
11
- * Fixed a problem with the registrations for multi-site setups when WordPress was installed in a separate folder
12
-
13
- = 1.7.5 =
14
- * Fixed a bug causing registration to not be recognized for the entire network in the multi-site mode
15
-
16
- = 1.7.4 =
17
- * Use https for wp-types API
18
-
19
- = 1.7.3 =
20
- * Added a dependencies class and check for the windows paths length exception
21
- * Bug fix: all downloads showed up twice on the plugins list whe upgrading from WPML 3.3
22
-
23
- = 1.7.2 =
24
- * Added an exception to handle the case when Types embedded is installer from Toolset Installer and its included Installer version overrides the one running the Toolset setup wizard
25
-
26
- = 1.7.1 =
27
- * Added an exception for the case of Types 1.8.9 (Installer 1.7.0) together with older WPML (older Installer)
28
-
29
- = 1.7.0 =
30
- * New format for the products data file.
31
- * Other fixes
32
-
33
- = 1.6.8 =
34
- * Sanitized an input that was a potential security issue
35
-
36
- = 1.6.7 =
37
- * Fixed a bug causing repeated calls to the Toolset api to validate the user subscription
38
- * Use https for API urls
39
-
40
- = 1.6.6 =
41
- * Fixed the 'Call to undefined function get_plugins()' issue
42
-
43
- = 1.6.5 =
44
- * Added configuration file for composer
45
- * Updated how free plugins are shown on the plugins list (commercial tab)
46
- * API calls for manipulating translation service preferences
47
- * Support for hosting custom Installer packages on wpml.org
48
- * Fixed a warning that was showing when using the OTGS_DISABLE_AUTO_UPDATES constant before any product data was downloaded
49
- * Changed the frequency with which product updates are checked automatically (24 hours)
50
- * Improved reporting for version numbers
51
-
52
- = 1.6.4 =
53
- * Enabled the OTGS_DISABLE_AUTO_UPDATES constant for theme update checks
54
- * Fixed a bug that was causing Register links to show for all installed plugins
55
-
56
- = 1.6.3 =
57
- * Fixed performance issue related to themes upgrade logic
58
-
59
- = 1.6 =
60
- * Improved the way plugins are matched: not just by the folder name (slug) but also by name
61
- * Added support for installing and upgrading themes from repositories (currently: Toolset themes)
62
- * Added support for 'alias' plugins on the toolset and wpml repositories (currently: Types)
63
- * Enhanced the progress animation during plugins downloading
64
-
65
- = 1.5.6 =
66
- * Updated the translations
67
- * Fix for WPML 3.2 conditional upgrade logic
68
-
69
- = 1.5.5 =
70
- * Fixed the logic for the high_priority parameter
71
- * Fixed js bug causing a conflict with NextGen
72
- * Fixed bug preventing users to install and upgrade Types when they didn't have a Toolset subscription
73
- * Fixed bug preventing users to upgrade from the embedded Types to the full version
74
-
75
- = 1.5.4 =
76
- * Option to disable auto-updates
77
- * Escaped urls generated with add_query_arg
78
-
79
- = 1.5.3 =
80
- * Fixed bug in WP_Installer::custom_plugins_api_call (filter for plugins_api) causing conflicts with other filters for plugins_api
81
-
82
- = 1.5.2 =
83
- * More meaningful errors when plugin downloads fail
84
- * WordPress 4.2 compatibility
85
- * Performance improvements (will not load in places where it's not needed and not make unnecessary requests to the CDN)
86
- * Support putting deps.xml config file in the theme folder (root)
87
- * Included code for importing data for toolset plugins
88
- * Use CloudFront urls for products list files
89
-
90
- = 1.5.1 =
91
- * Fix for allowing embedded plugins to be updated
92
- * Logic for the migration from embedded plugins to full plugins
93
-
94
- = 1.5 =
95
- * Support for embedded plugins
96
- * Bug fix: When user registers site key with trailing slash, downloads might not work
97
- * Tweak: Set a higher timeout limit for the http requests to CDN and API
98
- * API function: link to specific repository
99
- * API function: get product price
100
- * New method for defining affiliate info (with backwards compatibility)
101
-
102
- = 1.4 =
103
- * Show explicit error in case of connectivity issues while validating a key.
104
- * Bug fix: Downloading plugins in bulk was broken by plugin that had a redirect after activation
105
- * Display friendly error message when WordPress does not have permissions to write to the plugins folder
106
- * Added support for configuration files to auto-download required plugins and theme keys
107
- * Changed the "Update this info" button to "Check for updates" (it refreshes the subscription info and checks for updates)
108
- * Support for high_priority parameter that allows setting priority for an Installer instance when more with the same version number exist.
109
- * Config files from different instances are combined (define repositories in different instances)
110
- * Updated support for conditional updates display for ICL users
111
- * More friendly error reporting and handling when using an invalid site key or the plugins archives are not valid.
112
-
113
-
114
- = 1.3.1 =
115
- * Support for conditional release notification (ICanLocalize)
116
-
117
- = 1.3 =
118
- * Added a new repository: Toolset
119
- * The product packages can be displayed hierarchically and ordered
120
- * The link to automatically create site keys will follow through login on the account site (e.g. wpml.org, wp-types.com)
121
- * Fixed animation issues (not showing in most browsers) when downloading plugins.
122
- * Created an admin screen on the repository end (icl-mpp) to sho registration stats (site keys, site keys usage, components usage etc..).
123
- * Bug fix: Renew and Upgrade buttons were not entirely clickable
124
- * Bug fix: Action buttons (buy, renew, upgrade) were not displayed correctly when WPML was not active (Installer embedded in theme)
125
- * Support for site-wide registration. Products can be registered on the network instead of on each site separately.
126
- * Users are able to add either http or https version for any site urls. There will be one site key that will work with both http and https versions.
127
-
128
- = 1.2 =
129
- * Added pagination for site keys list of Account -> My Sites
130
- * Reversed the order in which the site keys are displayed.
131
- * Fixed problem with WPML registration information (site key) not being saved when the option_value field in the wp_options table used a different charset than the default WordPress charset defined in wp-config.php
132
- * Allow registering new sites by clicking a link in the WordPress admin instead of copying and pasting the site url in the Account -> My Sites section
133
- * Display more detailed debug information related to connectivity issues with the WPML repository
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/composer.json DELETED
@@ -1,31 +0,0 @@
1
- {
2
- "name": "otgs/installer",
3
- "description": "Installs and updates WPML and Toolset dependencies automatically",
4
- "keywords": ["plugins", "install", "utils", "update"],
5
- "homepage": "https://git.onthegosystems.com/installer/installer",
6
- "type": "wordpress-plugin",
7
- "license": "GPL-2.0",
8
- "authors": [
9
- {
10
- "name": "Mihai Grigori",
11
- "email": "mihai@wpml.org",
12
- "homepage": "http://www.wp-types.com"
13
- }
14
- ],
15
- "require": {
16
- "php": ">=5.2.0",
17
- "composer/installers": "~1.0"
18
- },
19
- "require-dev": {
20
- "phpunit/phpunit": "~4.5"
21
- },
22
- "extra": {
23
- "branch-alias": {
24
- "dev-master": "1.7.x-dev",
25
- "dev-develop": "1.7.x-dev"
26
- }
27
- },
28
- "scripts": {
29
- "test": "phpunit"
30
- }
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/includes/class-installer-dependencies.php DELETED
@@ -1,278 +0,0 @@
1
- <?php
2
-
3
- class Installer_Dependencies{
4
-
5
- private $uploading_allowed = null;
6
- private $is_win_paths_exception = array();
7
-
8
-
9
- function __construct(){
10
-
11
- add_action( 'admin_init', array( $this, 'prevent_plugins_update_on_plugins_page' ), 100);
12
-
13
-
14
-
15
- global $pagenow;
16
- if($pagenow == 'update.php'){
17
- if(isset($_GET['action']) && $_GET['action'] == 'update-selected'){
18
- add_action('admin_head', array($this, 'prevent_plugins_update_on_updates_screen')); //iframe/bulk
19
- }else{
20
- add_action('all_admin_notices', array($this, 'prevent_plugins_update_on_updates_screen')); //regular/singular
21
- }
22
- }
23
- add_action('wp_ajax_update-plugin', array($this, 'prevent_plugins_update_on_updates_screen'), 0); // high priority, before WP
24
-
25
- }
26
-
27
- public function is_win_paths_exception($repository_id){
28
-
29
- if(!isset($this->is_win_paths_exception[$repository_id])) {
30
-
31
- $this->is_win_paths_exception[$repository_id] = false;
32
-
33
- if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
34
-
35
- $windows_max_path_length = 256;
36
- $longest_path['wpml'] = 109;
37
- $longest_path['toolset'] = 99;
38
-
39
- $margin = 15;
40
-
41
- $upgrade_path_length = strlen( WP_CONTENT_DIR . '/upgrade' );
42
-
43
- $installer_settings = WP_Installer()->settings;
44
-
45
- if ( is_array( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] ) ) {
46
- $a_plugin = current( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] );
47
- $url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
48
- $tmpfname = wp_tempnam( $url );
49
-
50
- $tmpname_length = strlen( basename( $tmpfname ) ) - 4; // -.tmp
51
-
52
- if ( $upgrade_path_length + $tmpname_length + $longest_path[$repository_id] + $margin > $windows_max_path_length ) {
53
-
54
- $this->is_win_paths_exception[$repository_id] = true;
55
-
56
- }
57
-
58
- }
59
-
60
-
61
- }
62
-
63
- }
64
-
65
- return $this->is_win_paths_exception[$repository_id];
66
-
67
- }
68
-
69
- public function is_uploading_allowed(){
70
-
71
- if(!isset($this->uploading_allowed)){
72
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
73
- require_once WP_Installer()->plugin_path() . '/includes/installer-upgrader-skins.php';
74
-
75
- $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
76
- $upgrader = new Plugin_Upgrader($upgrader_skins);
77
-
78
- ob_start();
79
- $res = $upgrader->fs_connect( array(WP_CONTENT_DIR, WP_PLUGIN_DIR) );
80
- ob_end_clean();
81
-
82
- if ( ! $res || is_wp_error( $res ) ) {
83
- $this->uploading_allowed = false;
84
- }else{
85
- $this->uploading_allowed = true;
86
- }
87
- }
88
-
89
- return $this->uploading_allowed;
90
-
91
- }
92
-
93
- public function cant_download($repository_id){
94
-
95
- return !$this->is_uploading_allowed() || $this->is_win_paths_exception($repository_id);
96
-
97
- }
98
-
99
- public function win_paths_exception_message(){
100
- return __('Downloading is not possible. WordPress cannot create required folders because of the
101
- 256 characters limitation of the current Windows environment.', 'installer');
102
- }
103
-
104
- public function prevent_plugins_update_on_plugins_page(){
105
-
106
- $plugins = get_site_transient( 'update_plugins' );
107
- if ( isset($plugins->response) && is_array($plugins->response) ) {
108
- $plugins_with_updates = array_keys( $plugins->response );
109
- }
110
-
111
- if( !empty($plugins_with_updates) ) {
112
-
113
- $plugins = get_plugins();
114
-
115
- $installer_settings = WP_Installer()->settings;
116
- foreach ($installer_settings['repositories'] as $repository_id => $repository) {
117
-
118
- if ($this->is_win_paths_exception($repository_id)) {
119
-
120
- $repositories_plugins = array();
121
- foreach ($repository['data']['packages'] as $package) {
122
- foreach ($package['products'] as $product) {
123
- foreach ($product['plugins'] as $plugin_slug) {
124
- $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
125
- if ( empty($download['free-on-wporg']) ) {
126
- $repositories_plugins[$download['slug']] = $download['name'];
127
- }
128
- }
129
- }
130
- }
131
-
132
- foreach ($plugins as $plugin_id => $plugin) {
133
-
134
- if( in_array( $plugin_id, $plugins_with_updates ) ) {
135
-
136
- $wp_plugin_slug = dirname($plugin_id);
137
- if (empty($wp_plugin_slug)) {
138
- $wp_plugin_slug = basename($plugin_id, '.php');
139
- }
140
-
141
- foreach ($repositories_plugins as $slug => $name) {
142
- if ($wp_plugin_slug == $slug || $name == $plugin['Name'] || $name == $plugin['Title']) { //match order: slug, name, title
143
-
144
- remove_action("after_plugin_row_$plugin_id", 'wp_plugin_update_row', 10, 2);
145
- add_action("after_plugin_row_$plugin_id", array($this, 'wp_plugin_update_row_win_exception'), 10, 2);
146
-
147
- }
148
- }
149
-
150
- }
151
-
152
- }
153
-
154
- }
155
-
156
-
157
- }
158
-
159
- }
160
-
161
- }
162
-
163
- public function wp_plugin_update_row_win_exception(){
164
- $wp_list_table = _get_list_table('WP_Plugins_List_Table');
165
- echo '<tr class="plugin-update-tr">';
166
- echo '<td class="plugin-update colspanchange" colspan="' . esc_attr( $wp_list_table->get_column_count() ) .
167
- '"><div class="update-message">' . $this->win_paths_exception_message() . '</div></td>';
168
- echo '</tr>';
169
- }
170
-
171
- public function prevent_plugins_update_on_updates_screen(){
172
-
173
- if ( isset($_REQUEST['action']) ) {
174
-
175
- $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
176
-
177
- $installer_settings = WP_Installer()->settings;
178
-
179
- //bulk mode
180
- if('update-selected' == $action) {
181
-
182
- global $plugins;
183
-
184
- if(isset($plugins) && is_array($plugins)) {
185
-
186
- foreach ($plugins as $k => $plugin) {
187
-
188
- $wp_plugin_slug = dirname($plugin);
189
-
190
- foreach ($installer_settings['repositories'] as $repository_id => $repository) {
191
-
192
- if( $this->is_win_paths_exception($repository_id) ){
193
-
194
- foreach ($repository['data']['packages'] as $package) {
195
-
196
- foreach ($package['products'] as $product) {
197
-
198
- foreach ($product['plugins'] as $plugin_slug) {
199
-
200
- $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
201
-
202
- if ($download['slug'] == $wp_plugin_slug && empty($download['free-on-wporg']) ) {
203
-
204
- echo '<div class="updated error"><p>' . $this->win_paths_exception_message() .
205
- ' <strong>(' . $download['name'] . ')</strong>' . '</p></div>';
206
- unset($plugins[$k]);
207
-
208
- break(3);
209
-
210
- }
211
-
212
- }
213
-
214
- }
215
-
216
- }
217
-
218
-
219
- }
220
-
221
- }
222
-
223
- }
224
-
225
- }
226
-
227
- }
228
-
229
-
230
- if( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
231
-
232
- $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
233
-
234
- $wp_plugin_slug = dirname($plugin);
235
-
236
- foreach($installer_settings['repositories'] as $repository_id => $repository){
237
-
238
- if( $this->is_win_paths_exception( $repository_id ) ) {
239
- foreach ($repository['data']['packages'] as $package) {
240
-
241
- foreach($package['products'] as $product) {
242
-
243
- foreach($product['plugins'] as $plugin_slug) {
244
- $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
245
-
246
- //match by folder, will change to match by name and folder
247
- if ( $download['slug'] == $wp_plugin_slug && empty ($download['free-on-wporg'] ) ) {
248
-
249
- echo '<div class="updated error"><p>' . $this->win_paths_exception_message() . '</p></div>';
250
-
251
- echo '<div class="wrap">';
252
- echo '<h2>' . __('Update Plugin') . '</h2>';
253
- echo '<a href="' . admin_url('update-core.php') . '">' . __('Return to the updates page', 'installer') . '</a>';
254
- echo '</div>';
255
- require_once(ABSPATH . 'wp-admin/admin-footer.php');
256
- exit;
257
-
258
- }
259
-
260
- }
261
-
262
- }
263
-
264
- }
265
- }
266
-
267
- }
268
-
269
- }
270
- }
271
-
272
- }
273
-
274
-
275
- }
276
-
277
-
278
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/includes/class-installer-theme.php DELETED
@@ -1,979 +0,0 @@
1
- <?php
2
- /**
3
- * Installer Class for Theme Support
4
- *
5
- * Supports automatic updates and installation of Toolset/WPML Themes
6
- *
7
- * @class Installer_Theme_Class
8
- * @version 1.6
9
- * @category Class
10
- * @author OnTheGoSystems
11
- */
12
-
13
- if ( !defined( 'ABSPATH' ) ) {
14
- exit;
15
- }
16
-
17
- /**
18
- * Installer_Theme_Class
19
- */
20
- class Installer_Theme_Class {
21
-
22
- /** Theme Repository */
23
- private $theme_repo;
24
-
25
- /** Repository API */
26
- private $repository_api;
27
-
28
- /** Repository Theme Products */
29
- private $repository_theme_products;
30
-
31
- /** Site URL */
32
- private $installer_site_url;
33
-
34
- /** Site Key */
35
- private $installer_site_key;
36
-
37
- /** The Themes Option */
38
- protected $installer_themes_option;
39
-
40
- /** Update settings */
41
- protected $installer_themes_available_updates;
42
-
43
- /** The Themes */
44
- protected $installer_themes = array();
45
-
46
- /** Repository with themes */
47
- protected $installer_repo_with_themes;
48
-
49
- /** Active tab */
50
- protected $installer_theme_active_tab;
51
-
52
- /** Theme user registration */
53
- protected $theme_user_registration;
54
-
55
- /** Client active subscription */
56
- protected $installer_theme_subscription_type;
57
-
58
- public function __construct() {
59
-
60
- /** Properties */
61
-
62
- //Get installer repositories
63
- $installer_repositories = WP_Installer()->get_repositories();
64
-
65
- //Get repos with themes
66
- $repos_with_themes = $this->installer_theme_reposities_that_has_themes( $installer_repositories );
67
-
68
- if ( is_array( $repos_with_themes ) ) {
69
- //Assign to property
70
- $this->installer_repo_with_themes = $repos_with_themes;
71
-
72
- //Let's looped through repos with themes
73
- foreach ( $repos_with_themes as $k => $repo ) {
74
-
75
- //$repo could be 'toolset' or 'wpml'
76
- //Assign each repo with theme to property
77
- $this->theme_repo[] = $repo;
78
-
79
- if ( (isset($installer_repositories[$repo]['api-url'])) && (isset($installer_repositories[$repo]['products'])) ) {
80
-
81
- //Define the rest of the properties based on the given repo
82
- $this->repository_api[$repo] = $installer_repositories[$repo]['api-url'];
83
- $this->repository_theme_products[$repo] = $installer_repositories[$repo]['products'];
84
- $this->installer_site_url[$repo] = WP_Installer()->get_installer_site_url( $repo );
85
- $this->installer_site_key[$repo] = WP_Installer()->get_site_key( $repo );
86
- $this->theme_user_registration[$repo] = false;
87
-
88
- if ( WP_Installer()->repository_has_valid_subscription( $repo ) ) {
89
-
90
- $this->installer_theme_subscription_type = WP_Installer()->get_subscription_type_for_repository( $repo );
91
- $this->installer_themes_option[$repo] = 'wp_installer_' . $repo . '_themes';
92
- $this->installer_themes_available_updates[$repo] = 'wp_installer_' . $repo . '_updated_themes';
93
- $this->installer_theme_active_tab = '';
94
-
95
- //We only set themes available to this validated subscription
96
- $this->installer_theme_available( $repo, $this->installer_theme_subscription_type );
97
-
98
- add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_sets_active_tab_on_init'), 10 );
99
- $this->theme_user_registration[$repo] = true;
100
- }
101
-
102
- /** We are ready.. let's initialize .... */
103
- $this->init();
104
- }
105
- }
106
- add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_loaded_hooks') );
107
- }
108
- }
109
-
110
- /** Init */
111
- public function init() {
112
- add_action( 'admin_enqueue_scripts', array($this, 'installer_theme_enqueue_scripts') );
113
- add_filter( 'themes_api', array($this, 'installer_theme_api_override'), 10, 3 );
114
- add_filter( 'themes_api_result', array($this, 'installer_theme_api_override_response'), 10, 3 );
115
- add_filter( 'site_transient_update_themes', array($this, 'installer_theme_upgrade_check'), 10, 1 );
116
- add_action( 'http_api_debug', array($this, 'installer_theme_sync_native_wp_api'), 10, 5 );
117
- add_filter( 'installer_theme_hook_response_theme', array($this, 'installer_theme_add_num_ratings'), 10, 1 );
118
- add_filter( 'themes_update_check_locales', array($this, 'installer_theme_sync_call_wp_theme_api'), 10, 1 );
119
- add_filter( 'admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 3 );
120
- add_filter( 'network_admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 2 );
121
- add_action( 'wp_ajax_installer_theme_frontend_selected_tab', array($this, 'installer_theme_frontend_selected_tab'), 0 );
122
- add_action( 'wp_loaded', array($this, 'installer_themes_support_set_up_func') );
123
- }
124
-
125
- /** Enqueue scripts */
126
- public function installer_theme_enqueue_scripts() {
127
- $current_screen = $this->installer_theme_current_screen();
128
- $commercial_plugin_screen = $this->installer_theme_is_commercial_plugin_screen( $current_screen );
129
- if ( ('theme-install' == $current_screen) || ($commercial_plugin_screen) || ('theme-install-network' == $current_screen) ) {
130
- $repo_with_themes = $this->installer_repo_with_themes;
131
- $js_array = array();
132
- if ( is_array( $repo_with_themes ) ) {
133
- foreach ( $repo_with_themes as $k => $v ) {
134
-
135
- //Hyperlink text
136
- $theme_repo_name = $this->installer_theme_get_repo_product_name( $v );
137
- $the_hyperlink_text = esc_js( $theme_repo_name );
138
-
139
- if ( is_multisite() ) {
140
- $admin_url_passed = network_admin_url();
141
- } else {
142
- $admin_url_passed = admin_url();
143
- }
144
-
145
- //Define
146
- $js_array[$v] = array(
147
- 'the_hyperlink_text' => $the_hyperlink_text,
148
- 'registration_status' => $this->theme_user_registration[$v],
149
- 'is_commercial_plugin_tab' => $commercial_plugin_screen,
150
- 'registration_url' => $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $v
151
- );
152
-
153
- }
154
- }
155
-
156
- if ( !(empty($js_array)) ) {
157
- wp_enqueue_script( 'installer-theme-install', WP_Installer()->res_url() . '/res/js/installer_theme_install.js', array('jquery', 'installer-admin'), WP_Installer()->version() );
158
- $installer_ajax_url = admin_url( 'admin-ajax.php' );
159
-
160
- if ( is_ssl() ) {
161
- $installer_ajax_url = str_replace( 'http://', 'https://', $installer_ajax_url );
162
- } else {
163
- $installer_ajax_url = str_replace( 'https://', 'http://', $installer_ajax_url );
164
- }
165
-
166
- //Case where user is subscribed to a subscription that does not have themes
167
- $subscription_js_check = $this->installer_theme_subscription_does_not_have_theme( $js_array );
168
-
169
- wp_localize_script( 'installer-theme-install', 'installer_theme_install_localize',
170
- array(
171
- 'js_array_installer' => $js_array,
172
- 'ajaxurl' => $installer_ajax_url,
173
- 'no_associated_themes' => $subscription_js_check,
174
- 'installer_theme_frontend_selected_tab_nonce' => wp_create_nonce( 'installer_theme_frontend_selected_tab' )
175
- )
176
- );
177
- }
178
- }
179
- }
180
-
181
- /** Case where user is subscribed to a subscription that does not have themes */
182
- protected function installer_theme_subscription_does_not_have_theme( $js_array ) {
183
-
184
- $any_subscription_has_theme = array();
185
- $number_of_registrations = array();
186
-
187
- //Step1, we looped through JS array
188
- foreach ( $js_array as $repo_slug => $js_details ) {
189
-
190
- //Step2, checked if user is registered
191
- if ( isset($this->theme_user_registration[$repo_slug]) ) {
192
- $registration_status = $this->theme_user_registration[$repo_slug];
193
- if ( $registration_status ) {
194
-
195
- //Registered
196
- $number_of_registrations[] = $repo_slug;
197
-
198
- //Step3, we checked if the $repo_slug has available theme
199
- $themes_available = false;
200
- if ( isset($this->installer_themes[$repo_slug]) ) {
201
- $themes_available = $this->installer_themes[$repo_slug];
202
- if ( !(empty($themes_available)) ) {
203
- //This subscription has theme
204
- $themes_available = true;
205
- }
206
- }
207
-
208
- if ( $themes_available ) {
209
- $any_subscription_has_theme[] = $repo_slug;
210
- }
211
- }
212
- }
213
-
214
- }
215
-
216
- //Step4, we are done looping, check if there are any repos that have themes
217
- if ( empty($registration_status) ) {
218
-
219
- //No registration on any repos
220
- return FALSE;
221
-
222
- } elseif ( !(empty($registration_status)) ) {
223
-
224
- //Has some registration on some repos
225
- //We then checked if this user has any active subscriptions
226
- if ( empty($any_subscription_has_theme) ) {
227
- //No subscription
228
- return TRUE;
229
- } else {
230
- //Has subscription found
231
- return FALSE;
232
- }
233
- }
234
- }
235
-
236
- /** Check if its the commercial plugin screen */
237
- private function installer_theme_is_commercial_plugin_screen( $current_screen ) {
238
- $commercial = false;
239
- if ( ('plugin-install' == $current_screen) || ('plugin-install-network' == $current_screen) ) {
240
- if ( isset($_GET['tab']) ) {
241
- $tab = $_GET['tab'];
242
- if ( 'commercial' == $tab ) {
243
- $commercial = true;
244
- }
245
- }
246
- }
247
- return $commercial;
248
- }
249
-
250
- /** Current screen */
251
- private function installer_theme_current_screen() {
252
-
253
- $current_screen_loaded = false;
254
-
255
- if ( function_exists( 'get_current_screen' ) ) {
256
-
257
- $screen_output = get_current_screen();
258
- $current_screen_loaded = $screen_output->id;
259
-
260
- }
261
-
262
- return $current_screen_loaded;
263
-
264
- }
265
-
266
- /** Override WordPress Themes API */
267
- public function installer_theme_api_override( $api_boolean, $action, $args ) {
268
-
269
- //Let's checked if user is browsing our themes
270
- if ( isset($args->browse) ) {
271
- $browse = $args->browse;
272
- if ( in_array( $browse, $this->theme_repo ) ) {
273
- //Uniquely validated for our Themes
274
- if ( 'query_themes' == $action ) {
275
- //User is querying or asking information about our themes, let's override
276
- $api_boolean = true;
277
- }
278
- }
279
- } elseif ( isset($args->slug) ) {
280
- //We are installing our themes
281
- $theme_to_install = $args->slug;
282
-
283
- //Lets uniquely validate if this belongs to us
284
- //Check if this is OTGS theme
285
- $validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
286
- if ( $validate_check ) {
287
- //Belongs to us
288
- if ( !(empty($theme_to_install)) ) {
289
- $api_boolean = true;
290
- }
291
- }
292
- }
293
-
294
- return $api_boolean;
295
- }
296
-
297
- /** Override WordPress Themes API response with our own themes API*/
298
- public function installer_theme_api_override_response( $res, $action, $args ) {
299
-
300
- if ( true === $res ) {
301
- if ( isset($args->browse) ) {
302
- $browse = $args->browse;
303
- if ( in_array( $browse, $this->theme_repo ) ) {
304
- //Uniquely validated for our themes
305
- if ( 'query_themes' == $action ) {
306
- //Client querying OTGS themes
307
- //Check for registration status
308
- if ( isset($this->theme_user_registration[$browse]) ) {
309
- //Set
310
- if ( !($this->theme_user_registration[$browse]) ) {
311
- //Not registered yet
312
- $res = new stdClass();
313
- $res->info = array();
314
- $res->themes = array();
315
- return $res;
316
- } else {
317
- //Registered
318
- $themes = $this->installer_theme_get_themes( '', $browse );
319
- $res = $this->installer_theme_format_response( $themes, $action );
320
- }
321
- }
322
- }
323
- }
324
- } elseif ( isset($args->slug) ) {
325
- //We are installing theme
326
- //Lets uniquely validate if this belongs to our theme
327
- $theme_to_install = $args->slug;
328
-
329
- //Lets uniquely validate if this belongs to us
330
- //Check if this is OTGS theme
331
- $validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
332
- if ( $validate_check ) {
333
- //Belongs to us
334
- if ( ($res) && ('theme_information' == $action) ) {
335
- $themes = $this->installer_theme_get_themes( '', $this->installer_theme_active_tab );
336
- $res = $this->installer_theme_format_response( $themes, $action, $args->slug );
337
- }
338
- }
339
- }
340
- return $res;
341
- } else {
342
- //Default WP Themes here
343
- $client_side_active_tab = get_option( 'wp_installer_clientside_active_tab' );
344
- if ( $client_side_active_tab ) {
345
- if ( !(in_array( $client_side_active_tab, $this->theme_repo )) ) {
346
- //Not OTGS tab
347
- return $res;
348
- }
349
- }
350
-
351
- }
352
- }
353
-
354
- /** Get Themes */
355
- private function installer_theme_get_themes( $product_url = '', $repo_source = '' ) {
356
-
357
- //Query API
358
- if ( empty($product_url) ) {
359
- //Not set
360
- if ( isset($this->repository_theme_products[$this->installer_theme_active_tab]) ) {
361
- $query_remote_url = $this->repository_theme_products[$this->installer_theme_active_tab];
362
- }
363
-
364
- } else {
365
- $query_remote_url = $product_url;
366
- }
367
-
368
- //Let's retrieved current installer settings so we won't be querying all the time
369
- $current_installer_settings = WP_Installer()->get_settings();
370
-
371
- //Set $themes to FALSE by default
372
- $themes = false;
373
-
374
- if ( (is_array( $current_installer_settings )) && (!(empty($current_installer_settings))) ) {
375
-
376
- //Set and already defined, retrieved $products
377
- if ( isset($current_installer_settings['repositories'][$repo_source]['data']) ) {
378
- $products = $current_installer_settings['repositories'][$repo_source]['data'];
379
- if ( isset($products['downloads']['themes']) ) {
380
- $themes = $products['downloads']['themes'];
381
- }
382
- }
383
-
384
- } else {
385
-
386
- //Call API
387
- $response = wp_remote_get( $query_remote_url );
388
-
389
- if ( is_wp_error( $response ) ) {
390
- //Error detected: http fallback
391
- $query_remote_url = preg_replace( "@^https://@", 'http://', $query_remote_url );
392
- $response = wp_remote_get( $query_remote_url );
393
- }
394
-
395
- if ( !(is_wp_error( $response )) ) {
396
- //Not WP error
397
- //Evaluate response
398
- if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
399
- //In this case, response is set and defined, proceed...
400
- $body = wp_remote_retrieve_body( $response );
401
- if ( $body ) {
402
- $products = json_decode( $body, true );
403
- if ( isset($products['downloads']['themes']) ) {
404
- $themes = $products['downloads']['themes'];
405
- }
406
- }
407
-
408
- }
409
- }
410
- }
411
-
412
- //Return themes, can be filtered by user subscription type
413
- return apply_filters( 'installer_theme_get_themes', $themes, $this->installer_theme_active_tab );
414
- }
415
-
416
- /** Format response in compatibility with WordPress Theme API response */
417
- private function installer_theme_format_response( $themes, $action, $slug = '' ) {
418
-
419
- //Let's append download link only when retrieving theme information for installation
420
- if ( ('theme_information' == $action) && (!(empty($slug))) ) {
421
-
422
- //Only return one result -> the theme to be installed
423
- foreach ( $themes as $k => $theme ) {
424
- if ( $slug == $theme['basename'] ) {
425
- $theme['download_link'] = WP_Installer()->append_site_key_to_download_url( $theme['url'], $this->installer_site_key[$this->installer_theme_active_tab], $this->installer_theme_active_tab );
426
- $theme = json_decode( json_encode( $theme ), FALSE );
427
- return $theme;
428
- }
429
- }
430
-
431
- } else {
432
-
433
- $res = new stdClass();
434
- $res->info = array();
435
- $res->themes = array();
436
-
437
- //Define info
438
- $res->info['page'] = 1;
439
- $res->info['pages'] = 10;
440
-
441
- //Let's count available themes ;
442
- $res->info['results'] = count( $themes );
443
-
444
- //Let's saved themes for easy access later on
445
- $this->installer_theme_savethemes_by_slug( $themes );
446
-
447
- //Let's defined available themes
448
- if ( isset($this->installer_theme_subscription_type) ) {
449
- //Has subscription type defined, let's saved what is associated with this subscription
450
- $this->installer_theme_available( $this->installer_theme_active_tab, $this->installer_theme_subscription_type );
451
- } else {
452
- $this->installer_theme_available( $this->installer_theme_active_tab );
453
- }
454
-
455
- //Let's add themes to the overriden WordPress API Theme response
456
- /** Installer 1.7.6: Update to compatible data format response from WP Theme API */
457
- $theme_compatible_array=array();
458
- if ((is_array($themes))) {
459
- foreach ($themes as $k=>$v) {
460
- $theme_compatible_array[]=(object)($v);
461
- }
462
- }
463
- $res->themes = $theme_compatible_array;
464
- $res->themes = apply_filters( 'installer_theme_hook_response_theme', $res->themes );
465
- return $res;
466
- }
467
- }
468
-
469
- /** Let's save all available themes by its slug after any latest API query */
470
- private function installer_theme_savethemes_by_slug( $themes, $doing_query = false ) {
471
-
472
- if ( !($doing_query) ) {
473
- $this->installer_themes[$this->installer_theme_active_tab] = array();
474
- }
475
-
476
- if ( !(empty($themes)) ) {
477
- $themes_for_saving = array();
478
- foreach ( $themes as $k => $theme ) {
479
- if ( !($doing_query) ) {
480
- if ( isset($theme['slug']) ) {
481
- $theme_slug = $theme['slug'];
482
- if ( !(empty($theme_slug)) ) {
483
- $themes_for_saving[] = $theme_slug;
484
- }
485
- }
486
- } else {
487
-
488
- if ( ((isset($theme['slug'])) && (isset($theme['version'])) &&
489
- (isset($theme['theme_page_url']))) && (isset($theme['url']))
490
- ) {
491
- $theme_slug = $theme['slug'];
492
- $theme_version = $theme['version'];
493
- $theme_page_url = $theme['theme_page_url'];
494
- $theme_url = $theme['url'];
495
- if ( (!(empty($theme_slug))) && (!(empty($theme_version))) &&
496
- (!(empty($theme_page_url))) && (!(empty($theme_url)))
497
- ) {
498
- //$theme_slug is unique for every theme
499
- $themes_for_saving[$theme_slug] = array(
500
- 'version' => $theme_version,
501
- 'theme_page_url' => $theme_page_url,
502
- 'url' => $theme_url
503
- );
504
-
505
- }
506
- }
507
- }
508
-
509
- }
510
-
511
- if ( !(empty($themes_for_saving)) ) {
512
- //Has themes for saving
513
- if ( !($doing_query) ) {
514
- //Not doing query
515
- $existing_themes = get_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
516
- if ( !($existing_themes) ) {
517
- //Does not yet exists
518
- delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
519
- update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
520
- } else {
521
- //exists, check if we need to update
522
- if ( $existing_themes == $themes_for_saving ) {
523
- //Equal, no need to update here
524
- } else {
525
- //Update
526
- delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
527
- update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
528
- }
529
- }
530
- } else {
531
- //Used for query purposes only, don't save anything
532
- return $themes_for_saving;
533
- }
534
- }
535
- }
536
- }
537
-
538
- /** Available themes */
539
- private function installer_theme_available( $repo, $subscription_type = '' ) {
540
-
541
- $subscription_type = intval( $subscription_type );
542
- if ( $subscription_type > 0 ) {
543
-
544
- //Here we have a case of validated subscription
545
- //We need to set themes that is available to this subscription
546
- $themes_associated_with_subscription = $this->installer_themes[$repo] = $this->installer_theme_get_themes_by_subscription( $subscription_type, $repo );
547
- if ( !(empty($themes_associated_with_subscription)) ) {
548
- //Has themes
549
- $this->installer_themes[$repo] = $themes_associated_with_subscription;
550
- }
551
- } else {
552
-
553
- //Get themes
554
- $this->installer_themes[$repo] = get_option( $this->installer_themes_option[$repo] );
555
- }
556
- }
557
-
558
- /** Theme upgrade check */
559
- public function installer_theme_upgrade_check( $the_value ) {
560
-
561
- //Step1: Let's looped through repos with themes and check if we have updates available for them.
562
- if ( (is_array( $this->installer_repo_with_themes )) && (!(empty($this->installer_repo_with_themes))) ) {
563
- foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
564
- //Step2: Let's checked if we have update for this theme
565
- $update_available = get_option( $this->installer_themes_available_updates[$repo_slug] );
566
- if ( $update_available ) {
567
- if ( (is_array( $update_available )) && (!(empty($update_available))) ) {
568
- //Has updates available coming from this specific theme repo
569
- //Let's loop through the themes that needs update
570
- foreach ( $update_available as $theme_slug => $v ) {
571
- //Add to response API
572
- $the_value->response [$theme_slug] = array(
573
- 'theme' => $theme_slug,
574
- 'new_version' => $v['new_version'],
575
- 'url' => $v['url'],
576
- 'package' => $v['package']
577
- );
578
- }
579
- }
580
- }
581
- }
582
- }
583
- //Return
584
- return $the_value;
585
- }
586
-
587
- /** Return repositories that has themes */
588
- private function installer_theme_reposities_that_has_themes( $repositories, $ret_value = true, $doing_api_query = false ) {
589
-
590
- $repositories_with_themes = array();
591
-
592
- if ( (is_array( $repositories )) && (!(empty($repositories))) ) {
593
-
594
- //Let's checked if we have something before
595
- $themes = get_option( 'installer_repositories_with_theme' );
596
-
597
- if ( (!($themes)) || ($doing_api_query) ) {
598
- //Not yet defined
599
- //Loop through each repositories and check whether they have themes
600
- foreach ( $repositories as $k => $v ) {
601
- if ( isset($v['products']) ) {
602
- $products_url = $v['products'];
603
- $themes = $this->installer_theme_get_themes( $products_url, $k );
604
- if ( (is_array( $themes )) && (!(empty($themes))) ) {
605
- //Repo has themes
606
- $repositories_with_themes[] = $k;
607
- }
608
- }
609
- }
610
- } else {
611
- //Already set
612
- $repositories_with_themes = $themes;
613
- }
614
-
615
- if ( (((is_array( $repositories_with_themes )) && (!(empty($repositories_with_themes)))) && (!($themes))) || ($doing_api_query) ) {
616
- //Save to db
617
- update_option( 'installer_repositories_with_theme', $repositories_with_themes );
618
- }
619
- }
620
-
621
- if ( $ret_value ) {
622
- return $repositories_with_themes;
623
- }
624
-
625
- }
626
-
627
- /** When WordPress queries its own Themes API, we sync with our own */
628
- public function installer_theme_sync_native_wp_api( $response, $responsetext, $class, $args, $url ) {
629
-
630
- $api_native_string = 'api.wordpress.org/themes/';
631
- if ( (strpos( $url, $api_native_string ) !== false) ) {
632
- //WordPress is querying its own themes API
633
- $installer_repositories = WP_Installer()->get_repositories();
634
-
635
- //Query our own API and update repository values too
636
- $this->installer_theme_reposities_that_has_themes( $installer_repositories, false, true );
637
- }
638
- }
639
-
640
- /** Returns product name by theme repo slug */
641
- private function installer_theme_get_repo_product_name( $theme_repo ) {
642
-
643
- $theme_repo_name = false;
644
-
645
- if ( isset(WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name']) ) {
646
- //Set
647
- $prod_name = WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name'];
648
- if ( !(empty($prod_name)) ) {
649
- $theme_repo_name = $prod_name;
650
- }
651
- } else {
652
- //Not yet
653
- if ( $theme_repo == $this->theme_repo ) {
654
- $result = $this->installer_theme_general_api_query();
655
- if ( isset($result['product-name']) ) {
656
- $product_name = $result['product-name'];
657
- if ( !(empty($product_name)) ) {
658
- $theme_repo_name = $product_name;
659
- }
660
- }
661
- }
662
- }
663
-
664
- return $theme_repo_name;
665
- }
666
-
667
- /** General query API method, returns $products */
668
- private function installer_theme_general_api_query() {
669
- $products = false;
670
- $response = wp_remote_get( $this->repository_theme_products );
671
- if ( !(is_wp_error( $response )) ) {
672
- //Not WP error
673
- //Evaluate response
674
- if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
675
- //In this case, response is set and defined, proceed...
676
- $body = wp_remote_retrieve_body( $response );
677
- if ( $body ) {
678
- $result = json_decode( $body, true );
679
- if ( (is_array( $result )) && (!(empty($result))) ) {
680
- $products = $result;
681
- }
682
- }
683
-
684
- }
685
- }
686
-
687
- return $products;
688
- }
689
-
690
- /** General method to check if themes are OTGS themes based on its slug*/
691
- private function installer_themes_belong_to_us( $theme_slug ) {
692
-
693
- $found = false;
694
- $theme_slug = trim( $theme_slug );
695
-
696
- foreach ( $this->installer_themes as $repo_with_theme => $themes ) {
697
- foreach ( $themes as $k => $otgs_theme_slug ) {
698
- if ( $theme_slug == $otgs_theme_slug ) {
699
- //match found! Theme belongs to otgs
700
- return true;
701
- }
702
- }
703
- }
704
- return $found;
705
-
706
- }
707
-
708
- /** Sets active tab on init */
709
- public function installer_theme_sets_active_tab_on_init() {
710
-
711
- if ( isset ($_SERVER ['REQUEST_URI']) ) {
712
- $request_uri = $_SERVER ['REQUEST_URI'];
713
- if ( isset ($_GET ['browse']) ) {
714
- $active_tab = trim( $_GET ['browse'] );
715
- $this->installer_theme_active_tab = $active_tab;
716
- } elseif ( isset ($_POST ['request'] ['browse']) ) {
717
- $active_tab = trim( $_POST ['request'] ['browse'] );
718
- $this->installer_theme_active_tab = $active_tab;
719
- } elseif ( (isset ($_GET ['theme_repo'])) && (isset ($_GET ['action'])) ) {
720
- $theme_repo = trim( $_GET ['theme_repo'] );
721
- $the_action = trim( $_GET ['action'] );
722
- if ( ('install-theme' == $the_action) && (!(empty($theme_repo))) ) {
723
- $this->installer_theme_active_tab = $theme_repo;
724
- }
725
- } elseif ( wp_get_referer() ) {
726
- $referer = wp_get_referer();
727
- $parts = parse_url( $referer );
728
- if ( isset($parts['query']) ) {
729
- parse_str( $parts['query'], $query );
730
- if ( isset($query['browse']) ) {
731
- $this->installer_theme_active_tab = $query['browse'];
732
- }
733
- }
734
- }
735
- }
736
- }
737
-
738
- /** WP Theme API compatibility- added num ratings */
739
- /** Installer 1.7.6+ Added updated 'rating' field */
740
- public function installer_theme_add_num_ratings( $themes ) {
741
-
742
- if ( (is_array( $themes )) && (!(empty($themes))) ) {
743
- foreach ( $themes as $k => $v ) {
744
- if ( !(isset($v->num_ratings)) ) {
745
- $themes[$k]->num_ratings = 100;
746
- }
747
- if ( !(isset($v->rating)) ) {
748
- $themes[$k]->rating = 100;
749
- }
750
- }
751
- }
752
-
753
- return $themes;
754
- }
755
-
756
- /** When WordPress.org makes a call to its repository, let's run our own upgrade checks too */
757
- public function installer_theme_sync_call_wp_theme_api( $locales ) {
758
-
759
- $this->installer_theme_upgrade_theme_check();
760
-
761
- return $locales;
762
- }
763
-
764
- /** Upgrade theme check */
765
- private function installer_theme_upgrade_theme_check() {
766
-
767
- // Step1-> we get all installed themes in clients local themes directory
768
- $installed_themes = wp_get_themes();
769
-
770
- // Step2: We need to loop through each repository with themes
771
- foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
772
-
773
- // We then need to retrieved the products URL for each of this repo
774
- $products_url = $this->repository_theme_products [$repo_slug];
775
-
776
- // Step3-> we get all available themes in our repository via API based on this URL
777
- $available_themes = $this->installer_theme_get_themes( $products_url, $repo_slug );
778
-
779
- if ( !($available_themes) ) {
780
-
781
- // API is not available as of the moment, return..
782
- return;
783
- } else {
784
-
785
- // We have available themes here...
786
- // Step4->let's simplify available themes data by slugs
787
- $simplified_available_themes = $this->installer_theme_savethemes_by_slug( $available_themes, true );
788
-
789
- // Step5->Let's loop through installed themes
790
- if ( (is_array( $installed_themes )) && (!(empty ($installed_themes))) ) {
791
- $otgs_theme_updates_available = array();
792
- foreach ( $installed_themes as $theme_slug => $theme_object ) {
793
- if ( array_key_exists( $theme_slug, $simplified_available_themes ) ) {
794
-
795
- // This is our theme
796
- // Step6->Let's get version of the local theme installed
797
- $local_version = $theme_object->get( 'Version' );
798
-
799
- // Step7->Let's get the latest version of this theme, page URL and download URL from our repository
800
- $repository_version = $simplified_available_themes [$theme_slug] ['version'];
801
- $theme_page_url = $simplified_available_themes [$theme_slug] ['theme_page_url'];
802
- $theme_download_url = $simplified_available_themes [$theme_slug] ['url'];
803
-
804
- // Step8->Let's compare the version
805
- if ( version_compare( $repository_version, $local_version, '>' ) ) {
806
-
807
- // Update available for this theme
808
- // Step9-> Define download URL with site key
809
- $package_url = WP_Installer()->append_site_key_to_download_url( $theme_download_url, $this->installer_site_key [$repo_slug], $repo_slug );
810
-
811
- //Step10-> Assign to updates array for later accessing.
812
- $otgs_theme_updates_available[$theme_slug] = array(
813
- 'theme' => $theme_slug,
814
- 'new_version' => $repository_version,
815
- 'url' => $theme_page_url,
816
- 'package' => $package_url
817
- );
818
- }
819
- }
820
- }
821
- //Exited the upgrade loop for this specific theme repository
822
- if ( !(empty($otgs_theme_updates_available)) ) {
823
- //Has updates
824
- update_option( $this->installer_themes_available_updates[$repo_slug], $otgs_theme_updates_available );
825
- } else {
826
- //No updates
827
- delete_option( $this->installer_themes_available_updates[$repo_slug] );
828
- }
829
-
830
- }
831
- }
832
- }
833
- }
834
-
835
- /** When the user is on Themes install page OTG themes repository, let's the currently selected tab */
836
- public function installer_theme_add_query_arg_tab( $url, $path, $blog_id = null ) {
837
-
838
- $wp_install_string = 'update.php?action=install-theme';
839
- if ( $path == $wp_install_string ) {
840
- if ( isset($this->installer_theme_active_tab) ) {
841
- if ( !(empty($this->installer_theme_active_tab)) ) {
842
- $url = add_query_arg( array(
843
- 'theme_repo' => $this->installer_theme_active_tab
844
- ), $url );
845
- }
846
- }
847
- }
848
- return $url;
849
- }
850
-
851
- /** Save frontend theme tab selected */
852
- public function installer_theme_frontend_selected_tab() {
853
- if ( isset($_POST["frontend_tab_selected"]) ) {
854
- check_ajax_referer( 'installer_theme_frontend_selected_tab', 'installer_theme_frontend_selected_tab_nonce' );
855
-
856
- //Client_side_active_tab
857
- $frontend_tab_selected = filter_input( INPUT_POST, 'frontend_tab_selected', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE );
858
- if ( !(empty($frontend_tab_selected)) ) {
859
- //Front end tab selected
860
- update_option( 'wp_installer_clientside_active_tab', $frontend_tab_selected, false );
861
-
862
- //Check for registration status
863
- if ( isset($this->theme_user_registration[$frontend_tab_selected]) ) {
864
- //Set
865
- if ( !($this->theme_user_registration[$frontend_tab_selected]) ) {
866
- //Not registered yet
867
-
868
- if ( is_multisite() ) {
869
- $admin_url_passed = network_admin_url();
870
- } else {
871
- $admin_url_passed = admin_url();
872
- }
873
-
874
- $registration_url = $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $frontend_tab_selected;
875
-
876
- //Message and link
877
- $theme_repo_name = $this->installer_theme_get_repo_product_name( $frontend_tab_selected );;
878
- $response['unregistered_messages'] = sprintf( __( 'To install and update %s, please %sregister%s %s for this site.', 'installer' ),
879
- $theme_repo_name, '<a href="' . $registration_url . '">', '</a>', $theme_repo_name );
880
-
881
- }
882
- }
883
-
884
- $response['output'] = $frontend_tab_selected;
885
- echo json_encode( $response );
886
- }
887
- die();
888
- }
889
- die();
890
- }
891
-
892
- /** Installer loaded aux hooks */
893
- public function installer_theme_loaded_hooks() {
894
-
895
- if ( isset($this->installer_theme_subscription_type) ) {
896
- $subscription_type = intval( $this->installer_theme_subscription_type );
897
- if ( $subscription_type > 0 ) {
898
- //Client is subscribed
899
- add_filter( 'installer_theme_get_themes', array($this, 'installer_theme_filter_themes_by_subscription'), 10, 2 );
900
- }
901
- }
902
-
903
- }
904
-
905
- /** Get themes by subscription type */
906
- protected function installer_theme_get_themes_by_subscription( $subscription_type, $repo ) {
907
-
908
- $themes_associated_with_subscription = array();
909
- if ( isset(WP_Installer()->settings['repositories'][$repo]['data']['packages']) ) {
910
- //Set
911
- $packages = WP_Installer()->settings['repositories'][$repo]['data']['packages'];
912
- $available_themes_subscription = array();
913
- foreach ( $packages as $package_id => $package_details ) {
914
- if ( isset($package_details['products']) ) {
915
- $the_products = $package_details['products'];
916
- foreach ( $the_products as $product_slug => $product_details ) {
917
- if ( isset($product_details['subscription_type']) ) {
918
- $subscription_type_from_settings = intval( $product_details['subscription_type'] );
919
- if ( $subscription_type_from_settings == $subscription_type ) {
920
- //We found the subscription
921
- if ( isset($product_details['themes']) ) {
922
- $themes_associated_with_subscription = $product_details['themes'];
923
- return $themes_associated_with_subscription;
924
- }
925
- }
926
- }
927
-
928
- }
929
- }
930
- }
931
- }
932
- return $themes_associated_with_subscription;
933
- }
934
-
935
- /** Filter API theme response according to user subscription */
936
- public function installer_theme_filter_themes_by_subscription( $themes, $active_tab ) {
937
-
938
- //Step1, we only filter OTGS themes
939
- $orig = count( $themes );
940
- if ( in_array( $active_tab, $this->theme_repo ) ) {
941
- //OTGS Theme
942
- //Step2, we retrieved the available themes based on client subscription
943
- if ( isset($this->installer_themes[$active_tab]) ) {
944
- $available_themes = $this->installer_themes[$active_tab];
945
- //Step3, we filter $themes based on this info
946
- if ( (is_array( $themes )) && (!(empty($themes))) ) {
947
- foreach ( $themes as $k => $theme ) {
948
- //Step4, get theme slug
949
- if ( isset($theme['slug']) ) {
950
- $theme_slug = $theme['slug'];
951
- if ( !(empty($theme_slug)) ) {
952
- if ( !(in_array( $theme_slug, $available_themes )) ) {
953
- //This theme is not in available themes
954
- unset($themes[$k]);
955
- }
956
- }
957
- }
958
- }
959
- }
960
- }
961
- }
962
- $new = count( $themes );
963
- if ( $orig != $new ) {
964
- //It is filtered
965
- $themes = array_values( $themes );
966
- }
967
-
968
- return $themes;
969
- }
970
-
971
- /** Hook to wp_loaded, fires when all Installer theme class is ready */
972
- public function installer_themes_support_set_up_func() {
973
- do_action( 'installer_themes_support_set_up' );
974
- }
975
-
976
- }
977
-
978
- /** Instantiate Installer Theme Class */
979
- new Installer_Theme_Class;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/includes/installer-api.php DELETED
@@ -1,81 +0,0 @@
1
- <?php
2
-
3
- class WP_Installer_API{
4
-
5
- public static function get_product_installer_link($repository_id, $package_id = false){
6
-
7
- $menu_url = WP_Installer()->menu_url();
8
-
9
- $url = $menu_url . '#' . $repository_id;
10
- if($package_id){
11
- $url .= '/' . $package_id;
12
- }
13
-
14
- return $url;
15
-
16
- }
17
-
18
- public static function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
19
-
20
- $price = WP_Installer()->get_product_price($repository_id, $package_id, $product_id, $incl_discount);
21
-
22
- return $price;
23
- }
24
-
25
- /**
26
- * Retrieve the preferred translation service.
27
- *
28
- * @since 1.6.5
29
- *
30
- * @param string The repository id (e.g. wpml)
31
- * @return string The translation service id
32
- */
33
- public static function get_preferred_ts($repository_id = 'wpml'){
34
-
35
- if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'])){
36
- return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'];
37
- }
38
-
39
- return false;
40
-
41
- }
42
-
43
- /**
44
- * Set the preferred translation service.
45
- *
46
- * @since 1.6.5
47
- *
48
- * @param string The translation service id
49
- * @param string The repository id (e.g. wpml)
50
- */
51
- public static function set_preferred_ts( $value, $repository_id = 'wpml' ){
52
-
53
- if( isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] ) ){
54
-
55
- WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $value;
56
-
57
- WP_Installer()->save_settings();
58
-
59
- }
60
-
61
- }
62
-
63
- /**
64
- * Retrieve the referring translation service (if any)
65
- *
66
- * @since 1.6.5
67
- *
68
- * @param string The repository id (e.g. wpml)
69
- * @return string The translation service id or false
70
- */
71
- public static function get_ts_referal($repository_id = 'wpml'){
72
-
73
- if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'])){
74
- return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'];
75
- }
76
-
77
- return false;
78
-
79
- }
80
-
81
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/includes/installer-upgrader-skins.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- class Installer_Upgrader_Skins extends WP_Upgrader_Skin{
3
-
4
- function __construct($args = array()){
5
- $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
6
- $this->options = wp_parse_args($args, $defaults);
7
- }
8
-
9
- function header(){
10
-
11
- }
12
-
13
- function footer(){
14
-
15
- }
16
-
17
- function error($error){
18
- $this->installer_error = $error;
19
- }
20
-
21
- function add_strings(){
22
-
23
- }
24
-
25
- function feedback($string){
26
-
27
- }
28
-
29
- function before(){
30
-
31
- }
32
-
33
- function after(){
34
-
35
- }
36
-
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/includes/installer.class.php DELETED
@@ -1,2559 +0,0 @@
1
- <?php
2
-
3
- final class WP_Installer{
4
- protected static $_instance = null;
5
-
6
- public $settings = array();
7
-
8
- private $repositories = array();
9
-
10
- protected $api_debug = '';
11
-
12
- private $config = array();
13
-
14
- protected $_plugins_renew_warnings = array();
15
-
16
- protected $_gz_on = false;
17
-
18
- private $admin_messages = array();
19
-
20
- private $_using_icl = false;
21
- private $_wpml_version = false;
22
-
23
- private $package_source = array();
24
-
25
- const SITE_KEY_VALIDATION_SOURCE_OTHER = 0;
26
- const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_SPECIFIC = 1;
27
- const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT = 2;
28
- const SITE_KEY_VALIDATION_SOURCE_REGISTRATION = 3;
29
- const SITE_KEY_VALIDATION_SOURCE_REVALIDATION = 4;
30
- const SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK = 5;
31
-
32
- public $dependencies;
33
-
34
- public static function instance() {
35
-
36
- if ( is_null( self::$_instance ) ) {
37
- self::$_instance = new self();
38
- }
39
-
40
- return self::$_instance;
41
- }
42
-
43
- public function __construct(){
44
-
45
- if(!is_admin() || !is_user_logged_in()) return; //Only for admin
46
-
47
- $this->_gz_on = function_exists('gzuncompress') && function_exists('gzcompress');
48
- $this->settings = $this->get_settings();
49
-
50
- add_action('admin_notices', array($this, 'show_site_key_nags'));
51
-
52
- add_action('admin_notices', array($this, 'show_admin_messages'));
53
-
54
- add_action('admin_init', array($this, 'load_embedded_plugins'), 0);
55
-
56
- add_action('admin_menu', array($this, 'menu_setup'));
57
- add_action('network_admin_menu', array($this, 'menu_setup'));
58
-
59
- if(defined('DOING_AJAX') && isset($_POST['action']) && $_POST['action'] == 'installer_download_plugin'){
60
- add_filter( 'site_transient_update_plugins', array( $this, 'plugins_upgrade_check') );
61
- }
62
- add_filter('plugins_api', array( $this, 'custom_plugins_api_call'), 10, 3);
63
- add_filter('pre_set_site_transient_update_plugins', array( $this, 'plugins_upgrade_check'));
64
-
65
- // register repositories
66
- $this->load_repositories_list();
67
-
68
- if( empty($this->settings['last_repositories_update']) || time() - $this->settings['last_repositories_update'] > 86400
69
- || ( isset($_GET['force-check']) && $_GET['force-check'] == 1 ) ){
70
- $this->refresh_repositories_data();
71
- }
72
-
73
- // default config
74
- $this->config['plugins_install_tab'] = false;
75
-
76
- add_action('init', array($this, 'init'));
77
-
78
- //add_filter('wp_installer_buy_url', array($this, 'append_parameters_to_buy_url'));
79
-
80
- add_action('init', array($this,'load_locale'));
81
-
82
- }
83
-
84
- public function get_repositories() {
85
-
86
- return $this->repositories;
87
-
88
- }
89
-
90
- public function set_config($key, $value){
91
-
92
- $this->config[$key] = $value;
93
-
94
- }
95
-
96
- public function init(){
97
- global $pagenow;
98
-
99
- $this->dependencies = new Installer_Dependencies;
100
-
101
- if(empty($this->settings['_pre_1_0_clean_up'])) {
102
- $this->_pre_1_0_clean_up();
103
- }
104
-
105
- $this->settings = $this->_old_products_format_backwards_compatibility($this->settings);
106
-
107
- if ( !function_exists( 'get_plugins' ) ) {
108
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
109
- }
110
-
111
- $this->_using_icl = function_exists('wpml_site_uses_icl') && wpml_site_uses_icl();
112
- $this->_wpml_version = defined('ICL_SITEPRESS_VERSION') ? ICL_SITEPRESS_VERSION : '';
113
-
114
- wp_enqueue_script('installer-admin', $this->res_url() . '/res/js/admin.js', array('jquery'), $this->version());
115
- wp_enqueue_style('installer-admin', $this->res_url() . '/res/css/admin.css', array(), $this->version());
116
-
117
- $translation_array = array(
118
- 'installing' => __( 'Installing %s', 'installer' ),
119
- 'updating' => __( 'Updating %s', 'installer' ),
120
- 'activating' => __( 'Activating %s', 'installer' )
121
- );
122
-
123
- wp_localize_script( 'installer-admin', 'installer_strings', $translation_array );
124
-
125
- if($pagenow == 'plugins.php'){
126
- add_action('admin_notices', array($this, 'setup_plugins_page_notices'));
127
- add_action('admin_notices', array($this, 'setup_plugins_renew_warnings'), 10);
128
- add_action('admin_notices', array($this, 'queue_plugins_renew_warnings'), 20);
129
-
130
- add_action('admin_init', array($this, 'setup_plugins_action_links'));
131
-
132
- }
133
-
134
- if($this->is_repositories_page()){
135
- add_action('admin_init', array($this, 'validate_repository_subscription'));
136
- }
137
-
138
- if(defined('DOING_AJAX')){
139
- add_action('wp_ajax_save_site_key', array($this, 'save_site_key'));
140
- add_action('wp_ajax_remove_site_key', array($this, 'remove_site_key'));
141
- add_action('wp_ajax_update_site_key', array($this, 'update_site_key'));
142
-
143
- add_action('wp_ajax_installer_download_plugin', array($this, 'download_plugin_ajax_handler'));
144
- add_action('wp_ajax_installer_activate_plugin', array($this, 'activate_plugin'));
145
-
146
- add_action('wp_ajax_installer_dismiss_nag', array($this, 'dismiss_nag'));
147
- }
148
-
149
- if($pagenow == 'update.php'){
150
- if(isset($_GET['action']) && $_GET['action'] == 'update-selected'){
151
- add_action('admin_head', array($this, 'plugin_upgrade_custom_errors')); //iframe/bulk
152
- }else{
153
- add_action('all_admin_notices', array($this, 'plugin_upgrade_custom_errors')); //regular/singular
154
- }
155
- }
156
-
157
- // WP 4.2
158
- if(defined('DOING_AJAX')){
159
- add_action('wp_ajax_update-plugin', array($this, 'plugin_upgrade_custom_errors'), 0); // high priority, before WP
160
- }
161
-
162
- //Include theme support
163
- include_once $this->plugin_path() . '/includes/class-installer-theme.php';
164
-
165
- // Extra information about the source of Installer
166
- $package_source_file = $this->plugin_path() . '/installer-source.json';
167
- if( file_exists( $package_source_file ) ){
168
- $this->package_source = json_decode( file_get_contents( $package_source_file ) );
169
- }
170
- }
171
-
172
- protected function log($message){
173
- if( defined('WPML_INSTALLER_LOGGING') && WPML_INSTALLER_LOGGING ){
174
- if($fh = @fopen( $this->plugin_path() . '/installer.log', 'a' )){
175
- fwrite($fh, current_time( 'mysql' ) . "\t" . $message . "\n");
176
- }
177
- }
178
- }
179
-
180
- public function register_admin_message($text, $type = 'updated'){
181
- $this->admin_messages[] = array('text' => $text, 'type' => $type);
182
- }
183
-
184
- public function show_admin_messages(){
185
- if(!empty($this->admin_messages)){
186
- $types = array( 'error', 'updated', 'notice' );
187
- foreach($this->admin_messages as $message){
188
- $class = in_array( $message['type'], $types ) ? $message['type'] : 'updated';
189
- ?>
190
- <div class="<?php echo $class ?>">
191
- <p>
192
- <?php echo $message['text'] ?>
193
- </p>
194
- </div>
195
- <?php
196
- }
197
- }
198
- }
199
-
200
- public function load_locale(){
201
- $locale = get_locale();
202
- $locale = apply_filters( 'plugin_locale', $locale, 'installer' );
203
- $mo_file = $this->plugin_path() . '/locale/installer-' . $locale . '.mo';
204
- if(file_exists($mo_file)){
205
- load_textdomain( 'installer', $mo_file );
206
- }
207
- }
208
-
209
- public function load_embedded_plugins(){
210
- if(file_exists($this->plugin_path() . '/embedded-plugins' )) {
211
- include_once $this->plugin_path() . '/embedded-plugins/embedded-plugins.class.php';
212
- $this->installer_embedded_plugins = new Installer_Embedded_Plugins();
213
- }
214
- }
215
-
216
- public function menu_setup(){
217
- global $pagenow;
218
-
219
- if(is_multisite() && !is_network_admin()){
220
- $this->menu_multisite_redirect();
221
- add_options_page(__('Installer', 'installer'), __('Installer', 'installer'), 'manage_options', 'installer', array($this, 'show_products')) ;
222
- }else{
223
- if($this->config['plugins_install_tab'] && is_admin() && $pagenow == 'plugin-install.php'){
224
- // Default GUI, under Plugins -> Install
225
- add_filter('install_plugins_tabs', array($this, 'add_install_plugins_tab'));
226
- add_action('install_plugins_commercial', array($this, 'show_products'));
227
- }
228
- }
229
-
230
- }
231
-
232
- public function menu_url(){
233
- if(is_multisite()){
234
- if(is_network_admin()){
235
- $url = network_admin_url('plugin-install.php?tab=commercial');
236
- }else{
237
- $url = admin_url('options-general.php?page=installer');
238
- }
239
- }else{
240
- $url = admin_url('plugin-install.php?tab=commercial');
241
- }
242
- return $url;
243
- }
244
-
245
- private function menu_multisite_redirect(){
246
- global $pagenow;
247
-
248
- if($pagenow == 'plugin-install.php' && isset($_GET['tab']) && $_GET['tab'] == 'commercial'){
249
- wp_redirect($this->menu_url());
250
- exit;
251
- }
252
-
253
- }
254
-
255
- private function _pre_1_0_clean_up(){
256
- global $wpdb;
257
-
258
- if(!defined('WPRC_VERSION')){
259
- $old_tables = array(
260
- $wpdb->prefix . 'wprc_cached_requests',
261
- $wpdb->prefix . 'wprc_extension_types',
262
- $wpdb->prefix . 'wprc_extensions',
263
- $wpdb->prefix . 'wprc_repositories',
264
- $wpdb->prefix . 'wprc_repositories_relationships',
265
- );
266
-
267
- foreach($old_tables as $table){
268
- $wpdb->query(sprintf("DROP TABLE IF EXISTS %s", $table));
269
- }
270
-
271
- }
272
-
273
- $this->settings['_pre_1_0_clean_up'] = true;
274
- $this->save_settings();
275
- }
276
-
277
- public function setup_plugins_action_links(){
278
-
279
- $plugins = get_plugins();
280
-
281
- $repositories_plugins = array();
282
-
283
- if( !empty($this->settings['repositories']) ) {
284
-
285
- foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
286
-
287
- foreach ( $repository['data']['packages'] as $package ) {
288
-
289
- foreach ( $package['products'] as $product ) {
290
-
291
- foreach ( $product['plugins'] as $plugin_slug ) {
292
-
293
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
294
-
295
- if ( !isset($repositories_plugins[$repository_id][$download['slug']]) ) {
296
- $repositories_plugins[$repository_id][$download['slug']] = array(
297
- 'name' => $download['name'],
298
- 'registered' => $this->plugin_is_registered( $repository_id, $download['slug'] ) ? 1 : 0
299
- );
300
- }
301
-
302
- }
303
-
304
- }
305
-
306
- }
307
-
308
- foreach ( $plugins as $plugin_id => $plugin ) {
309
-
310
- $wp_plugin_slug = dirname( $plugin_id );
311
- if ( empty($wp_plugin_slug) ) {
312
- $wp_plugin_slug = basename( $plugin_id, '.php' );
313
- }
314
-
315
- foreach ( $repositories_plugins as $repository_id => $r_plugins ) {
316
-
317
- foreach ( $r_plugins as $slug => $r_plugin ) {
318
-
319
- if ( $wp_plugin_slug == $slug || $r_plugin['name'] == $plugin['Name'] || $r_plugin['name'] == $plugin['Title'] ) { //match order: slug, name, title
320
-
321
- if ( $r_plugin['registered'] ) {
322
- add_filter( 'plugin_action_links_' . $plugin_id, array($this, 'plugins_action_links_registered') );
323
- } else {
324
- add_filter( 'plugin_action_links_' . $plugin_id, array($this, 'plugins_action_links_not_registered') );
325
- }
326
-
327
- }
328
-
329
- }
330
-
331
- }
332
-
333
-
334
- }
335
-
336
- }
337
- }
338
-
339
- }
340
-
341
- public function plugins_action_links_registered($links){
342
- $links[] = '<a href="' . $this->menu_url() . '">' . __('Registered', 'installer') . '</a>';
343
- return $links;
344
- }
345
-
346
- public function plugins_action_links_not_registered($links){
347
- $links[] = '<a href="' . $this->menu_url() . '">' . __('Register', 'installer') . '</a>';
348
- return $links;
349
- }
350
-
351
- public function plugin_is_registered($repository_id, $slug){
352
-
353
- $registered = false;
354
-
355
- if( $this->repository_has_valid_subscription($repository_id) ){
356
-
357
- $subscription_type = $this->get_subscription_type_for_repository($repository_id);
358
- $r_plugins = array();
359
-
360
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
361
-
362
- foreach($package['products'] as $product){
363
-
364
- if( $product['subscription_type'] == $subscription_type || $this->have_superior_subscription($subscription_type, $product) ) {
365
-
366
- foreach ($product['plugins'] as $plugin_slug) {
367
-
368
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
369
-
370
- if (!isset($rep_plugins[$download['slug']])) {
371
- $r_plugins[$download['slug']] = $download['slug'];
372
- }
373
-
374
- }
375
-
376
- }
377
-
378
- }
379
-
380
- }
381
-
382
- $registered = isset($r_plugins[$slug]);
383
-
384
- }
385
-
386
-
387
- return $registered;
388
-
389
- }
390
-
391
- public function version(){
392
- return WP_INSTALLER_VERSION;
393
- }
394
-
395
- public function plugin_path() {
396
- return untrailingslashit( plugin_dir_path( dirname(__FILE__) ) );
397
- }
398
-
399
- public function plugin_url() {
400
- if(isset($this->config['in_theme_folder']) && !empty($this->config['in_theme_folder'])){
401
- $url = untrailingslashit(get_template_directory_uri() . '/' . $this->config['in_theme_folder']);
402
- }else{
403
- $url = untrailingslashit( plugins_url( '/', dirname(__FILE__) ) );
404
- }
405
-
406
- return $url;
407
- }
408
-
409
- public function is_repositories_page(){
410
- global $pagenow;
411
-
412
- return $pagenow == 'plugin-install.php' && isset($_GET['tab']) && $_GET['tab'] == 'commercial';
413
- }
414
-
415
- public function res_url(){
416
- if(isset($this->config['in_theme_folder']) && !empty($this->config['in_theme_folder'])){
417
- $url = untrailingslashit(get_template_directory_uri() . '/' . $this->config['in_theme_folder']);
418
- }else{
419
- $url = $this->plugin_url();
420
- }
421
- return $url;
422
- }
423
-
424
- public function save_settings(){
425
-
426
- $_settings = serialize($this->settings);
427
- if($this->_gz_on){
428
- $_settings = gzcompress($_settings);
429
- }
430
- $_settings = base64_encode($_settings);
431
-
432
- update_option( 'wp_installer_settings', $_settings );
433
-
434
- if( is_multisite() && is_main_site() && isset($this->settings['repositories']) ){
435
- $network_settings = array();
436
-
437
- foreach( $this->settings['repositories'] as $rep_id => $repository ){
438
- if( isset($repository['subscription']) )
439
- $network_settings[$rep_id] = $repository['subscription'];
440
- }
441
-
442
- update_site_option( 'wp_installer_network', $network_settings );
443
-
444
-
445
- }
446
-
447
- }
448
-
449
- public function get_settings($refresh = false){
450
-
451
- if($refresh || empty($this->settings)){
452
-
453
- $_settings = get_option('wp_installer_settings');
454
-
455
-
456
- if (is_array($_settings) || empty($_settings)) { //backward compatibility 1.1
457
- $this->settings = $_settings;
458
-
459
- } else {
460
- $_settings = base64_decode($_settings);
461
- if ($this->_gz_on) {
462
- $_settings = gzuncompress($_settings);
463
- }
464
- $this->settings = unserialize($_settings);
465
- }
466
-
467
- if (is_multisite() && isset($this->settings['repositories'])) {
468
- $network_settings = maybe_unserialize(get_site_option('wp_installer_network'));
469
- if ($network_settings) {
470
- foreach ($this->settings['repositories'] as $rep_id => $repository) {
471
- if (isset($network_settings[$rep_id])) {
472
- $this->settings['repositories'][$rep_id]['subscription'] = $network_settings[$rep_id];
473
- }
474
- }
475
- }
476
- }
477
-
478
-
479
- $this->settings = $this->_pre_1_6_backwards_compatibility($this->settings);
480
-
481
- $this->settings = $this->_old_products_format_backwards_compatibility($this->settings);
482
-
483
- }
484
-
485
-
486
- return $this->settings;
487
- }
488
-
489
- //backward compatibility, will remove 'basename' in version 1.8
490
- private function _pre_1_6_backwards_compatibility($settings){
491
-
492
- if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) ){
493
-
494
- foreach ($settings['repositories'] as $repository_id => $repository) {
495
-
496
- foreach ($repository['data']['downloads']['plugins'] as $slug => $download) {
497
-
498
- $settings['repositories'][$repository_id]['data']['downloads']['plugins'][$slug]['slug'] = $download['basename'];
499
-
500
- }
501
- }
502
-
503
- }
504
-
505
- return $settings;
506
-
507
- }
508
-
509
- //backward compatibility - support old products list format (downloads under products instead of global downloads list)
510
- private function _old_products_format_backwards_compatibility($settings){
511
-
512
- if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) && empty($this->_old_products_format_backwards_compatibility) ) {
513
-
514
- foreach ($settings['repositories'] as $repository_id => $repository) {
515
-
516
- $populate_downloads = false;
517
-
518
- foreach ($repository['data']['packages'] as $package_id => $package) {
519
-
520
- foreach ($package['products'] as $product_id => $product) {
521
-
522
- if (!isset($product['plugins'])) {
523
-
524
- $populate_downloads = true;
525
-
526
- foreach ($product['downloads'] as $download_id => $download) {
527
-
528
- $settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['plugins'][] = $download['slug'];
529
-
530
- }
531
-
532
- }
533
-
534
- }
535
-
536
- }
537
-
538
- if ($populate_downloads) {
539
-
540
- // Add downloads branch
541
- foreach ($repository['data']['packages'] as $package_id => $package) {
542
-
543
- foreach ($package['products'] as $product_id => $product) {
544
-
545
- foreach ($product['downloads'] as $download_id => $download) {
546
-
547
- if (!isset($settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']])) {
548
- $settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']] = $download;
549
- }
550
-
551
- $settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['plugins'][] = $download['slug'];
552
- }
553
-
554
- unset($settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['downloads']);
555
-
556
- }
557
-
558
- }
559
-
560
- }
561
-
562
- }
563
-
564
- $this->_old_products_format_backwards_compatibility = true;
565
-
566
- }
567
-
568
- return $settings;
569
-
570
- }
571
-
572
- public function get_installer_site_url( $repository_id = false ){
573
- global $current_site;
574
-
575
- $site_url = get_site_url();
576
-
577
- if( $repository_id && is_multisite() && isset( $this->settings['repositories'] ) ){
578
- $network_settings = maybe_unserialize( get_site_option('wp_installer_network') );
579
-
580
- if ( isset( $network_settings[$repository_id] ) ) {
581
- $site_url = get_site_url( $current_site->blog_id );
582
- }
583
-
584
- }
585
-
586
- return $site_url;
587
- }
588
-
589
- public function show_site_key_nags(){
590
- $screen = get_current_screen();
591
-
592
- if($screen->base == 'settings_page_installer' || ($screen->base == 'plugin-install' && isset($_GET['tab']) && $_GET['tab'] == 'commercial')){
593
- return;
594
- }
595
-
596
- if(!empty($this->config['site_key_nags'])){
597
-
598
- foreach($this->config['site_key_nags'] as $nag){
599
-
600
- if(!$this->repository_has_subscription($nag['repository_id'] )){
601
- $show = true;
602
- if(!empty($nag['condition_cb'])){
603
- $show = call_user_func($nag['condition_cb']);
604
- }
605
-
606
- if(empty($this->settings['dismissed_nags'][$nag['repository_id']]) && $show){
607
- echo '<div class="updated error otgs-is-dismissible"><p>';
608
- printf(__("To get automatic updates, you need to register %s for this site. %sRegister %s%s", 'sitepress'),
609
- $nag['product_name'], '<a class="button-primary" href="' . $this->menu_url() . '">', $nag['product_name'], '</a>');
610
-
611
- echo '</p>';
612
- echo '<span class="installer-dismiss-nag notice-dismiss" data-repository="' . $nag['repository_id'] . '"><span class="screen-reader-text">' . __('Dismiss', 'sitepress') . '</span></span>';
613
- echo '</div>';
614
- }
615
- }
616
-
617
- }
618
-
619
- }
620
-
621
- }
622
-
623
- public function dismiss_nag(){
624
- $this->settings['dismissed_nags'][$_POST['repository']] = 1;
625
-
626
- $this->save_settings();
627
-
628
- echo json_encode(array());
629
- exit;
630
- }
631
-
632
- public function add_install_plugins_tab($tabs){
633
-
634
- $tabs['commercial'] = __('Commercial', 'installer');
635
-
636
- return $tabs;
637
- }
638
-
639
- public function load_repositories_list(){
640
- global $wp_installer_instances;
641
-
642
- foreach ($wp_installer_instances as $instance) {
643
-
644
- if (file_exists(dirname($instance['bootfile']) . '/repositories.xml')) {
645
- $config_file = dirname($instance['bootfile']) . '/repositories.xml';
646
-
647
- if (file_exists(dirname($instance['bootfile']) . '/repositories.sandbox.xml')) {
648
- $config_file = dirname($instance['bootfile']) . '/repositories.sandbox.xml';
649
- add_filter('https_ssl_verify', '__return_false');
650
- }
651
-
652
- $repos = simplexml_load_file($config_file);
653
-
654
- if($repos) {
655
- foreach ($repos as $repo) {
656
- $id = strval($repo->id);
657
-
658
- $data['api-url'] = strval($repo->apiurl);
659
- $data['products'] = strval($repo->products);
660
-
661
- // excludes rule;
662
- if (isset($this->config['repositories_exclude']) && in_array($id, $this->config['repositories_exclude'])) {
663
- continue;
664
- }
665
-
666
- // includes rule;
667
- if (isset($this->config['repositories_include']) && !in_array($id, $this->config['repositories_include'])) {
668
- continue;
669
- }
670
-
671
- $this->repositories[$id] = $data;
672
-
673
- }
674
- }
675
-
676
- }
677
- }
678
-
679
- }
680
-
681
- public function filter_repositories_list(){
682
-
683
- if(!empty($this->settings['repositories'])) {
684
- foreach ($this->settings['repositories'] as $id => $repo_data) {
685
-
686
- // excludes rule;
687
- if (isset($this->config['repositories_exclude']) && in_array($id, $this->config['repositories_exclude'])) {
688
- unset($this->settings['repositories'][$id]);
689
- }
690
-
691
- // includes rule;
692
- if (isset($this->config['repositories_include']) && !in_array($id, $this->config['repositories_include'])) {
693
- unset($this->settings['repositories'][$id]);
694
- }
695
-
696
-
697
- }
698
- }
699
-
700
-
701
- }
702
-
703
- public function refresh_repositories_data(){
704
- static $checked = false;
705
-
706
- if( defined('OTGS_DISABLE_AUTO_UPDATES') && OTGS_DISABLE_AUTO_UPDATES && empty($_GET['force-check']) || $checked ){
707
-
708
- if(empty($this->settings['repositories']) && $this->is_repositories_page()){
709
-
710
- foreach($this->repositories as $id => $data) {
711
- $repository_names[] = $id;
712
-
713
- }
714
-
715
- $error = sprintf(__("Installer cannot display the products information because the automatic updating for %s was explicitly disabled with the configuration below (usually in wp-config.php):", 'installer'), strtoupper( join(', ', $repository_names) ));
716
- $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code><br /><br />';
717
- $error .= sprintf(__("In order to see the products information, please run the %smanual updates check%s to initialize the products list or (temporarily) remove the above code.", 'installer'), '<a href="' . admin_url('update-core.php') . '">', '</a>');
718
-
719
- $this->register_admin_message($error, 'error');
720
-
721
-
722
- }
723
-
724
- return;
725
- }
726
-
727
- $checked = true;
728
-
729
- foreach($this->repositories as $id => $data){
730
-
731
- $response = wp_remote_get($data['products']);
732
-
733
- if(is_wp_error($response)){
734
- // http fallback
735
- $data['products'] = preg_replace("@^https://@", 'http://', $data['products']);
736
- $response = wp_remote_get($data['products']);
737
- }
738
-
739
- if(is_wp_error($response)){
740
-
741
- $error = sprintf(__("Installer cannot contact our updates server to get information about the available products and check for new versions. If you are seeing this message for the first time, you can ignore it, as it may be a temporary communication problem. If the problem persists and your WordPress admin is slowing down, you can disable automated version checks. Add the following line to your wp-config.php file:", 'installer'), strtoupper($id));
742
- $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code>';
743
-
744
- $this->register_admin_message($error, 'error');
745
-
746
- continue;
747
- }
748
-
749
- if($response && isset($response['response']['code']) && $response['response']['code'] == 200){
750
- $body = wp_remote_retrieve_body($response);
751
- if($body){
752
- $products = json_decode($body, true);
753
-
754
- if(is_array($products)){
755
- $this->settings['repositories'][$id]['data'] = $products;
756
- $this->settings = $this->_pre_1_6_backwards_compatibility($this->settings);
757
- }
758
- }
759
-
760
- }
761
-
762
- $this->log( sprintf("Checked for %s updates: %s", $id, $data['products']) );
763
-
764
-
765
- }
766
-
767
- // cleanup
768
- if(empty($this->settings['repositories'])){
769
- $this->settings['repositories'] = array();
770
- }
771
- foreach($this->settings['repositories'] as $id => $data){
772
- if(!in_array($id, array_keys($this->repositories))){
773
- unset($this->settings['repositories'][$id]);
774
- }
775
- }
776
-
777
- $this->settings['last_repositories_update']= time();
778
-
779
- $this->save_settings();
780
-
781
- }
782
-
783
- public function show_products($args = array()){
784
-
785
- $screen = get_current_screen();
786
-
787
- if($screen->base == 'settings_page_installer'){ // settings page
788
- echo '<div class="wrap">';
789
- echo '<h2>' . __('Installer', 'installer') . '</h2>';
790
- echo '<br />';
791
- }
792
-
793
- if(!is_array($args)) $args = array();
794
- if(empty($args['template'])) $args['template'] = 'default';
795
-
796
- $this->filter_repositories_list();
797
-
798
- if(!empty($this->settings['repositories'])){
799
-
800
- $this->localize_strings();
801
- $this->set_filtered_prices($args);
802
- $this->set_hierarchy_and_order();
803
-
804
- foreach($this->settings['repositories'] as $repository_id => $repository){
805
-
806
- if($args['template'] == 'compact'){
807
-
808
- if(isset($args['repository']) && $args['repository'] == $repository_id){
809
- include $this->plugin_path() . '/templates/products-compact.php';
810
- }
811
-
812
- }else{
813
-
814
- include $this->plugin_path() . '/templates/repository-listing.php';
815
-
816
- }
817
-
818
- unset($site_key, $subscription_type, $expired, $upgrade_options, $products_avaliable);
819
-
820
- }
821
-
822
- }else{
823
-
824
- echo '<center>' . __('No repositories defined.', 'installer') . '</center>';
825
-
826
- }
827
-
828
- if($screen->base == 'settings_page_installer'){ // settings page
829
- echo '</div>';
830
- }
831
-
832
-
833
- }
834
-
835
- public function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
836
-
837
- $price = false;
838
-
839
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package ){
840
-
841
- if($package['id'] == $package_id){
842
- if(isset($package['products'][$product_id])){
843
- if($incl_discount && isset($package['products'][$product_id]['price_disc'])){
844
- $price = $package['products'][$product_id]['price_disc'];
845
- }elseif(isset($package['products'][$product_id]['price'])){
846
- $price = $package['products'][$product_id]['price'];
847
- }
848
- }
849
- break;
850
- }
851
- }
852
-
853
- return $price;
854
- }
855
-
856
- private function _render_product_packages($packages, $subscription_type, $expired, $upgrade_options, $repository_id){
857
-
858
- $data = array();
859
-
860
- foreach($packages as $package_id => $package){
861
-
862
- $row = array('products' => array(), 'downloads' => array());
863
- foreach($package['products'] as $product){
864
-
865
- // filter out free subscriptions from being displayed as buying options
866
- if( empty($product['price']) && (empty($subscription_type) || $expired) ){
867
- continue;
868
- }
869
-
870
- // buy base
871
- if(empty($subscription_type) || $expired) {
872
-
873
- $p['url'] = $this->append_parameters_to_buy_url($product['url'], $repository_id);
874
- if (!empty($product['price_disc'])) {
875
- $p['label'] = $product['call2action'] . ' - ' . sprintf('$%s %s$%d%s (USD)', $product['price_disc'], '&nbsp;&nbsp;<del>', $product['price'], '</del>');
876
- } else {
877
- $p['label'] = $product['call2action'] . ' - ' . sprintf('$%d (USD)', $product['price']);
878
- }
879
- $row['products'][] = $p;
880
-
881
- // renew
882
- } elseif(isset($subscription_type) && $product['subscription_type'] == $subscription_type){
883
-
884
- if($product['renewals']) {
885
- foreach ($product['renewals'] as $renewal) {
886
- $p['url'] = $this->append_parameters_to_buy_url($renewal['url'], $repository_id);
887
- $p['label'] = $renewal['call2action'] . ' - ' . sprintf('$%d (USD)', $renewal['price']);
888
- }
889
-
890
- $row['products'][] = $p;
891
- }
892
-
893
- }
894
-
895
- // upgrades
896
- if(!empty($upgrade_options[$product['subscription_type']])){
897
-
898
- foreach($upgrade_options[$product['subscription_type']] as $stype => $upgrade){
899
- if($stype != $subscription_type) continue;
900
-
901
- $p['url'] = $this->append_parameters_to_buy_url($upgrade['url'], $repository_id);
902
- if (!empty($upgrade['price_disc'])) {
903
- $p['label'] = $upgrade['call2action'] . ' - ' . sprintf('$%s %s$%d%s (USD)', $upgrade['price_disc'], '&nbsp;&nbsp;<del>', $upgrade['price'], '</del>');
904
- } else {
905
- $p['label'] = $upgrade['call2action'] . ' - ' . sprintf('$%d (USD)', $upgrade['price']);
906
- }
907
- $row['products'][] = $p;
908
-
909
- }
910
-
911
- }
912
-
913
- // downloads
914
- if(isset($subscription_type) && !$expired && $product['subscription_type'] == $subscription_type){
915
- foreach($product['plugins'] as $plugin_slug){
916
-
917
- $row['downloads'][] = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
918
-
919
- }
920
-
921
- }
922
-
923
- //subpackages
924
- if(!empty($package['sub-packages'])){
925
- $row['sub-packages'] = $package['sub-packages'];
926
- }
927
-
928
- }
929
-
930
- $row['id'] = $package['id'];
931
- $row['image_url'] = $package['image_url'];
932
- $row['name'] = $package['name'];
933
- $row['description'] = $package['description'];
934
-
935
- if(!empty($row['products']) || !empty($row['downloads']) || !empty($row['sub-packages'])){
936
- $data[] = $row;
937
- }
938
-
939
-
940
- }
941
-
942
- return $data;
943
-
944
- }
945
-
946
- public function get_extra_url_parameters(){
947
-
948
- $parameters = array();
949
-
950
- if(!empty($this->package_source)){
951
- foreach($this->package_source as $key => $val){
952
- $parameters[$key] = $val;
953
- }
954
- }
955
-
956
- $parameters['installer_version'] = WP_INSTALLER_VERSION;
957
- $parameters['theme'] = wp_get_theme()->get( 'Name' );
958
- $parameters['site_name'] = get_bloginfo( 'name' );
959
-
960
- return $parameters;
961
- }
962
-
963
- public function append_parameters_to_buy_url($url, $repository_id, $args = array()){
964
-
965
- $url = add_query_arg( array('icl_site_url' => $this->get_installer_site_url( $repository_id ) ), $url );
966
-
967
- $affiliate_id = false;
968
- $affiliate_key = false;
969
-
970
- // Add extra parameters for custom Installer packages
971
- if( !empty($this->package_source) ){
972
- $extra = $this->get_extra_url_parameters();
973
-
974
- if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
975
-
976
- if( !empty($extra['affiliate_key']) && !empty($extra['user_id']) ){
977
- $this->config['affiliate_id:' . $repository_id] = $extra['user_id'];
978
- $this->config['affiliate_key:' . $repository_id] = $extra['affiliate_key'];
979
- unset($extra['affiliate_key'], $extra['user_id'], $extra['repository']); // no need to include these ones
980
- }
981
-
982
- $url = add_query_arg($extra, $url);
983
- }
984
-
985
- }
986
-
987
- if(isset($this->config['affiliate_id:' . $repository_id]) && isset($this->config['affiliate_key:' . $repository_id])){
988
-
989
- $affiliate_id = $this->config['affiliate_id:' . $repository_id];
990
- $affiliate_key = $this->config['affiliate_key:' . $repository_id];
991
-
992
- }elseif(isset($args['affiliate_id:' . $repository_id]) && isset($args['affiliate_key:' . $repository_id])){
993
-
994
- $affiliate_id = $args['affiliate_id:' . $repository_id];
995
- $affiliate_key = $args['affiliate_key:' . $repository_id];
996
-
997
- }elseif(defined('ICL_AFFILIATE_ID') && defined('ICL_AFFILIATE_KEY')){ //support for 1 repo
998
-
999
- $affiliate_id = ICL_AFFILIATE_ID;
1000
- $affiliate_key = ICL_AFFILIATE_KEY;
1001
-
1002
- }elseif(isset($this->config['affiliate_id']) && isset($this->config['affiliate_key'])) {
1003
- // BACKWARDS COMPATIBILITY
1004
- $affiliate_id = $this->config['affiliate_id'];
1005
- $affiliate_key = $this->config['affiliate_key'];
1006
- }
1007
-
1008
- if($affiliate_id && $affiliate_key){
1009
- $url = add_query_arg(array('aid' => $affiliate_id, 'affiliate_key' => $affiliate_key), $url);
1010
- }
1011
-
1012
- if($repository_id == 'wpml'){
1013
- $url = add_query_arg(array('using_icl' => $this->_using_icl, 'wpml_version' => $this->_wpml_version), $url);
1014
- }
1015
-
1016
- $url = apply_filters('wp_installer_buy_url', $url);
1017
-
1018
- $url = esc_url($url);
1019
-
1020
- return $url;
1021
-
1022
- }
1023
-
1024
- public function save_site_key($args = array()){
1025
-
1026
- $error = '';
1027
-
1028
- $repository_id = isset($args['repository_id']) ? $args['repository_id'] : (isset($_POST['repository_id']) ? $_POST['repository_id'] : false);
1029
- $nonce = isset($args['nonce']) ? $args['nonce'] : (isset($_POST['nonce']) ? $_POST['nonce'] : '');
1030
- $site_key = isset($args['site_key']) ? $args['site_key'] : $_POST['site_key_' . $repository_id];
1031
-
1032
- $site_key = preg_replace("/[^A-Za-z0-9]/", '', $site_key);
1033
-
1034
- if($repository_id && $nonce && wp_create_nonce('save_site_key_' . $repository_id) == $nonce){
1035
-
1036
- try {
1037
- $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REGISTRATION );
1038
-
1039
- if ( $subscription_data ) {
1040
- $this->settings['repositories'][$repository_id]['subscription'] = array('key' => $site_key, 'data' => $subscription_data);
1041
- $this->save_settings();
1042
- } else {
1043
- $error = __( 'Invalid site key for the current site.', 'installer' );
1044
- }
1045
-
1046
- } catch (Exception $e ){
1047
- $error = $e->getMessage();
1048
- if( preg_match('#Could not resolve host: (.*)#', $error, $matches) || preg_match('#Couldn\'t resolve host \'(.*)\'#', $error, $matches) ){
1049
- $error = sprintf(__("%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer'),
1050
- '<strong><i>' . $this->get_generic_product_name($repository_id) . '</i></strong>',
1051
- '<strong><i>' . $matches[1]. '</i></strong>'
1052
- ) ;
1053
- }
1054
- }
1055
-
1056
- }
1057
-
1058
- $return = array('error' => $error);
1059
-
1060
- if($this->api_debug){
1061
- $return['debug'] = $this->api_debug;
1062
- }
1063
-
1064
- if(!empty($args['return'])){
1065
- return $return;
1066
- }else{
1067
- echo json_encode($return);
1068
- exit;
1069
- }
1070
-
1071
- }
1072
-
1073
- public function get_site_key($repository_id){
1074
-
1075
- if(isset($this->settings['repositories'][$repository_id]['subscription'])){
1076
- $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1077
- }else{
1078
- $site_key = false;
1079
- }
1080
-
1081
- return $site_key;
1082
- }
1083
-
1084
- public function remove_site_key(){
1085
- if($_POST['nonce'] == wp_create_nonce('remove_site_key_' . $_POST['repository_id'])){
1086
- unset($this->settings['repositories'][$_POST['repository_id']]['subscription']);
1087
- $this->save_settings();
1088
-
1089
- $this->refresh_repositories_data();
1090
- }
1091
- exit;
1092
- }
1093
-
1094
- public function validate_repository_subscription(){
1095
- $repository_id = isset($_GET['validate_repository']) ? $_GET['validate_repository'] : false;
1096
- if($repository_id){
1097
-
1098
- $site_key = $this->get_site_key($repository_id);
1099
- if($site_key) {
1100
- $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION);
1101
- if(empty($subscription_data)){
1102
- unset($this->settings['repositories'][$repository_id]['subscription']);
1103
- delete_site_transient('update_plugins');
1104
- $this->save_settings();
1105
- }
1106
- }
1107
-
1108
- wp_redirect($this->menu_url() . '#repository-' . $repository_id);
1109
- exit;
1110
-
1111
- }
1112
-
1113
- }
1114
-
1115
- public function update_site_key(){
1116
-
1117
- $error = '';
1118
-
1119
- if($_POST['nonce'] == wp_create_nonce('update_site_key_' . $_POST['repository_id'])){
1120
-
1121
- $repository_id = $_POST['repository_id'];
1122
- $site_key = $this->get_site_key($_POST['repository_id']);
1123
-
1124
- if($site_key){
1125
- try {
1126
- $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK );
1127
-
1128
- if ( $subscription_data ) {
1129
- $this->settings['repositories'][$repository_id]['subscription'] = array('key' => $site_key, 'data' => $subscription_data);
1130
-
1131
- //also refresh products information
1132
- $this->refresh_repositories_data();
1133
-
1134
- $this->save_settings();
1135
-
1136
- } else {
1137
- unset($this->settings['repositories'][$repository_id]['subscription']);
1138
- $error = __( 'Invalid site key for the current site. If the error persists, try to unregister first and then register again with the same site key.', 'installer' );
1139
- }
1140
-
1141
-
1142
- } catch (Exception $e ){
1143
- $error = $e->getMessage();
1144
- if( preg_match('#Could not resolve host: (.*)#', $error, $matches) || preg_match('#Couldn\'t resolve host \'(.*)\'#', $error, $matches) ){
1145
- $error = sprintf(__("%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer'),
1146
- '<strong><i>' . $this->get_generic_product_name($repository_id) . '</i></strong>',
1147
- '<strong><i>' . $matches[1]. '</i></strong>'
1148
- ) ;
1149
- }
1150
- }
1151
-
1152
- }
1153
-
1154
- }
1155
-
1156
- echo json_encode(array('error' => $error));
1157
-
1158
- exit;
1159
- }
1160
-
1161
- public function api_debug_log($text){
1162
-
1163
- if(defined('WPML_DEBUG_INSTALLER') && WPML_DEBUG_INSTALLER){
1164
-
1165
- if(!is_scalar($text)){
1166
- $text = print_r($text, 1);
1167
- }
1168
-
1169
- $this->api_debug .= $text . "\n";
1170
-
1171
- }
1172
-
1173
- }
1174
-
1175
- public function fetch_subscription_data( $repository_id, $site_key, $source = self::SITE_KEY_VALIDATION_SOURCE_OTHER ){
1176
-
1177
- $subscription_data = false;
1178
-
1179
- $args['body'] = array(
1180
- 'action' => 'site_key_validation',
1181
- 'site_key' => $site_key,
1182
- 'site_url' => $this->get_installer_site_url( $repository_id ),
1183
- 'source' => $source
1184
- );
1185
-
1186
- if($repository_id == 'wpml'){
1187
- $args['body']['using_icl'] = $this->_using_icl;
1188
- $args['body']['wpml_version'] = $this->_wpml_version;
1189
- }
1190
-
1191
- $args['body']['installer_version'] = WP_INSTALLER_VERSION;
1192
- $args['body']['theme'] = wp_get_theme()->get( 'Name' );
1193
- $args['body']['site_name'] = get_bloginfo( 'name' );
1194
-
1195
- $args['body']['versions'] = $this->get_local_product_versions( $repository_id );
1196
-
1197
- $args['timeout'] = 45;
1198
-
1199
- // Add extra parameters for custom Installer packages
1200
- if( !empty($this->package_source) ){
1201
- $extra = $this->get_extra_url_parameters();
1202
- if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
1203
- unset($extra['repository']);
1204
- foreach($extra as $key => $val){
1205
- $args['body'][$key] = $val;
1206
- }
1207
- }
1208
- }
1209
-
1210
- $response = wp_remote_post($this->repositories[$repository_id]['api-url'], $args);
1211
-
1212
- $this->api_debug_log("POST {$this->repositories[$repository_id]['api-url']}");
1213
- $this->api_debug_log($args);
1214
-
1215
- $this->log("POST {$this->repositories[$repository_id]['api-url']} - fetch subscription data");
1216
-
1217
- if( !is_wp_error($response) ){
1218
- $datas = wp_remote_retrieve_body($response);
1219
-
1220
- if(is_serialized($datas)){
1221
- $data = unserialize($datas);
1222
- $this->api_debug_log($data);
1223
- }else{
1224
- $this->api_debug_log($datas);
1225
- }
1226
-
1227
- if(!empty($data->subscription_data)){
1228
- $subscription_data = $data->subscription_data;
1229
- }
1230
-
1231
- do_action( 'installer_fetched_subscription_data', $data, $repository_id);
1232
-
1233
- }else{
1234
-
1235
- $this->api_debug_log($response);
1236
- throw new Exception( $response->get_error_message() );
1237
- }
1238
-
1239
- return $subscription_data;
1240
-
1241
- }
1242
-
1243
- function get_local_product_versions( $repository_id ){
1244
-
1245
- $versions = array();
1246
-
1247
- foreach( $this->settings['repositories'][$repository_id]['data']['packages'] as $package_id => $package ){
1248
-
1249
- foreach( $package['products'] as $product_id => $product ){
1250
-
1251
- foreach( $product['plugins'] as $plugin_slug ){
1252
-
1253
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1254
-
1255
- if( empty( $versions[$download['slug']] ) ) {
1256
- $v = $this->get_plugin_installed_version($download['name'], $download['slug']);
1257
- if($v){
1258
- $versions[$download['slug']] = $v;
1259
- }
1260
- }
1261
-
1262
- }
1263
-
1264
- }
1265
-
1266
- }
1267
-
1268
- return $versions;
1269
- }
1270
-
1271
- public function get_repository_site_key($repository_id){
1272
- $site_key = false;
1273
-
1274
- if(!empty($this->settings['repositories'][$repository_id]['subscription']['key'])){
1275
- $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1276
- }
1277
-
1278
- return $site_key;
1279
- }
1280
-
1281
- public function repository_has_valid_subscription($repository_id){
1282
-
1283
- $valid = false;
1284
-
1285
- if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1286
-
1287
- $subscription = $this->settings['repositories'][$repository_id]['subscription']['data'];
1288
- $valid = ( $subscription->status == 1 && (strtotime($subscription->expires) > time() || empty($subscription->expires)) ) || $subscription->status == 4;
1289
-
1290
- }
1291
- return $valid;
1292
-
1293
- }
1294
-
1295
- public function repository_has_subscription($repository_id){
1296
- $key = false;
1297
- if(!empty($this->settings['repositories'][$repository_id]['subscription']['key'])){
1298
- $key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1299
- }
1300
-
1301
- return $key;
1302
-
1303
- }
1304
-
1305
- public function repository_has_expired_subscription($repository_id){
1306
-
1307
- return $this->repository_has_subscription($repository_id) && !$this->repository_has_valid_subscription($repository_id);
1308
-
1309
- }
1310
-
1311
- public function get_generic_product_name($repository_id){
1312
-
1313
- return $this->settings['repositories'][$repository_id]['data']['product-name'];
1314
-
1315
- }
1316
-
1317
- public function show_subscription_renew_warning($repository_id, $subscription_id){
1318
-
1319
- $show = false;
1320
-
1321
- $data = $this->settings['repositories'][$repository_id]['data'];
1322
- if(!empty($data['subscriptions_meta'])){
1323
- if(isset($data['subscriptions_meta']['expiration'])){
1324
-
1325
- if(!empty($data['subscriptions_meta']['expiration'][$subscription_id])){
1326
-
1327
- $days = $data['subscriptions_meta']['expiration'][$subscription_id]['days_warning'];
1328
- $message = $data['subscriptions_meta']['expiration'][$subscription_id]['warning_message'];
1329
-
1330
- }else{
1331
-
1332
- //defaults
1333
- $days = 30;
1334
- $message = __('You will have to renew your subscription in order to continue getting the updates and support.', 'installer');
1335
-
1336
- }
1337
-
1338
- if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1339
- $subscription = $this->settings['repositories'][$repository_id]['subscription'];
1340
-
1341
- if($subscription['data']->subscription_type == $subscription_id && !empty($subscription['data']->expires)){
1342
-
1343
- if(strtotime($subscription['data']->expires) < strtotime(sprintf("+%d day", $days))){
1344
-
1345
- $days_to_expiration = ceil((strtotime($subscription['data']->expires) - time()) / 86400);
1346
-
1347
- echo '<div><p class="installer-warn-box">' .
1348
- sprintf(_n('Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer'), $days_to_expiration) .
1349
- '<br />' . $message .
1350
- '</p></div>';
1351
-
1352
- $show = true;
1353
-
1354
- }
1355
-
1356
- }
1357
-
1358
- }
1359
-
1360
-
1361
- }
1362
- }
1363
-
1364
-
1365
- return $show;
1366
-
1367
- }
1368
-
1369
- public function setup_plugins_renew_warnings(){
1370
-
1371
- $plugins = get_plugins();
1372
-
1373
- $subscriptions_with_warnings = array();
1374
- foreach($this->settings['repositories'] as $repository_id => $repository){
1375
-
1376
- if($this->repository_has_valid_subscription($repository_id)){
1377
- $subscription_type = $this->settings['repositories'][$repository_id]['subscription']['data']->subscription_type;
1378
- $expires = $this->settings['repositories'][$repository_id]['subscription']['data']->expires;
1379
-
1380
- $never_expires = isset($this->settings['repositories'][$repository_id]['subscription'])
1381
- && empty($this->settings['repositories'][$repository_id]['subscription']['data']->expires)
1382
- && (
1383
- $this->settings['repositories'][$repository_id]['subscription']['data']->status == 4 ||
1384
- $this->settings['repositories'][$repository_id]['subscription']['data']->status == 1
1385
- );
1386
-
1387
- if(!$never_expires){
1388
- if(isset($this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type])){
1389
-
1390
- $days_warning = $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type]['days_warning'];
1391
- $custom_message = $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type]['warning_message'];
1392
-
1393
- }else{
1394
- //defaults
1395
- $days_warning = 30;
1396
- $custom_message = __('You will have to renew your subscription in order to continue getting the updates and support.', 'installer');
1397
- }
1398
-
1399
- if(strtotime($expires) < strtotime(sprintf('+%d day', $days_warning)) ){
1400
-
1401
- $days_to_expiration = ceil((strtotime($expires) - time()) / 86400);
1402
-
1403
- $message = sprintf(_n('Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer'), $days_to_expiration);
1404
- $subscriptions_with_warnings[$subscription_type] = $message . ' ' . $custom_message;
1405
-
1406
- }
1407
- }
1408
-
1409
- }
1410
-
1411
- }
1412
-
1413
-
1414
-
1415
- foreach($plugins as $plugin_id => $plugin){
1416
-
1417
- $slug = dirname($plugin_id);
1418
- if(empty($slug)) continue;
1419
-
1420
- foreach($this->settings['repositories'] as $repository_id => $repository){
1421
-
1422
- if($this->repository_has_valid_subscription($repository_id)){
1423
-
1424
- foreach($repository['data']['packages'] as $package){
1425
-
1426
- foreach($package['products'] as $product){
1427
-
1428
- foreach($product['plugins'] as $plugin_slug){
1429
-
1430
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1431
-
1432
- if($download['slug'] == $slug || $download['name'] == $plugin['Name'] || $download['name'] == $plugin['Title']){ //match order: slug, name, title
1433
-
1434
- if(isset($subscriptions_with_warnings[$product['subscription_type']])){
1435
-
1436
- $this->_plugins_renew_warnings[$plugin_id] = $subscriptions_with_warnings[$product['subscription_type']];
1437
-
1438
- }
1439
-
1440
- }
1441
-
1442
- }
1443
-
1444
- }
1445
-
1446
- }
1447
-
1448
- }
1449
-
1450
- }
1451
-
1452
- }
1453
-
1454
- }
1455
-
1456
- public function queue_plugins_renew_warnings() {
1457
-
1458
- if(!empty($this->_plugins_renew_warnings)){
1459
-
1460
- foreach($this->_plugins_renew_warnings as $plugin_id => $message){
1461
-
1462
- add_action( "after_plugin_row_" . $plugin_id, array($this, 'plugins_renew_warning'), 10, 3 );
1463
- }
1464
-
1465
- }
1466
-
1467
- }
1468
-
1469
- public function plugins_renew_warning($plugin_file, $plugin_data, $status){
1470
-
1471
- if(empty($this->_plugins_renew_warnings[$plugin_file])) return;
1472
-
1473
- $wp_list_table = _get_list_table('WP_Plugins_List_Table');
1474
- ?>
1475
-
1476
- <tr class="plugin-update-tr"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
1477
- <div class="update-message">
1478
- <?php
1479
- echo $this->_plugins_renew_warnings[$plugin_file]. ' ';
1480
- printf(__('%sRenew here%s.', 'installer'),
1481
- '<a href="' . $this->menu_url() . '">', '</a>');
1482
- ?>
1483
- </div>
1484
- </tr>
1485
-
1486
- <?php
1487
-
1488
- }
1489
-
1490
- public function get_subscription_type_for_repository($repository_id){
1491
-
1492
- $subscription_type = false;
1493
-
1494
- if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1495
- $subscription_type = $this->settings['repositories'][$repository_id]['subscription']['data']->subscription_type;
1496
- }
1497
-
1498
- return $subscription_type;
1499
-
1500
- }
1501
-
1502
- public function have_superior_subscription($subscription_type, $product){
1503
-
1504
- $have = false;
1505
-
1506
- if(is_array($product['upgrades'])){
1507
- foreach($product['upgrades'] as $u){
1508
- if($u['subscription_type'] == $subscription_type){
1509
- $have = true;
1510
- break;
1511
- }
1512
- }
1513
- }
1514
-
1515
- return $have;
1516
- }
1517
-
1518
- public function is_product_available_for_download($product_name, $repository_id){
1519
-
1520
- $available = false;
1521
-
1522
- $subscription_type = $this->get_subscription_type_for_repository($repository_id);
1523
- $expired = $this->repository_has_expired_subscription($repository_id);
1524
-
1525
- if($this->repository_has_subscription($repository_id) && !$expired){
1526
-
1527
- $this->set_hierarchy_and_order();
1528
-
1529
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package_id => $package){
1530
-
1531
- $has_top_package = false;
1532
-
1533
- foreach($package['products'] as $product){
1534
-
1535
- if($subscription_type == $product['subscription_type']){
1536
- $has_top_package = true;
1537
- if($product['name'] == $product_name){
1538
- return $available = true;
1539
- }
1540
- }
1541
-
1542
- }
1543
-
1544
- if(!empty($package['sub-packages'])){
1545
- foreach($package['sub-packages'] as $sub_package){
1546
- foreach($sub_package['products'] as $product){
1547
- if($product['name'] == $product_name && ($subscription_type == $product['subscription_type'] || $has_top_package)){
1548
- return $available = true;
1549
- }
1550
- }
1551
- }
1552
- }
1553
-
1554
- }
1555
- }
1556
-
1557
- return $available;
1558
-
1559
- }
1560
-
1561
- public function get_upgrade_options($repository_id){
1562
- $all_upgrades = array();
1563
-
1564
- //get all products: packages and subpackages
1565
- $all_products = array();
1566
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
1567
- foreach($package['products'] as $product) {
1568
- $all_products[] = $product;
1569
- }
1570
- if(!empty($package['sub-packages'])){
1571
- foreach($package['sub-packages'] as $subpackage){
1572
- foreach($subpackage['products'] as $product) {
1573
- $all_products[] = $product;
1574
- }
1575
-
1576
- }
1577
-
1578
- }
1579
-
1580
- }
1581
-
1582
- foreach($all_products as $product) {
1583
- if ($product['upgrades']) {
1584
- foreach ($product['upgrades'] as $upgrade) {
1585
- if ($this->repository_has_valid_subscription($repository_id) || ($this->repository_has_subscription($repository_id) && $upgrade['including_expired'])) {
1586
- $all_upgrades[$upgrade['subscription_type']][$product['subscription_type']] = $upgrade;
1587
- }
1588
- }
1589
- }
1590
- }
1591
-
1592
- return $all_upgrades;
1593
-
1594
- }
1595
-
1596
- public function append_site_key_to_download_url($url, $key, $repository_id){
1597
-
1598
- $url_params['site_key'] = $key;
1599
- $url_params['site_url'] = $this->get_installer_site_url( $repository_id );
1600
-
1601
-
1602
- // Add extra parameters for custom Installer packages
1603
- if( !empty($this->package_source) ){
1604
- $extra = $this->get_extra_url_parameters();
1605
- if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
1606
- unset($extra['repository']);
1607
- foreach($extra as $key => $val){
1608
- $url_params[$key] = $val;
1609
- }
1610
- }
1611
- }
1612
-
1613
- $url = add_query_arg($url_params, $url);
1614
-
1615
- if($repository_id == 'wpml'){
1616
- $url = add_query_arg(array('using_icl' => $this->_using_icl, 'wpml_version' => $this->_wpml_version), $url);
1617
- }
1618
-
1619
- return $url;
1620
-
1621
- }
1622
-
1623
- public function plugin_is_installed($name, $slug, $version = null){
1624
-
1625
- $is = false;
1626
-
1627
- $plugins = get_plugins();
1628
-
1629
- foreach($plugins as $plugin_id => $plugin){
1630
-
1631
- $wp_plugin_slug = dirname($plugin_id);
1632
-
1633
- // Exception: embedded plugins
1634
- if( $wp_plugin_slug == $slug || $plugin['Name'] == $name || $plugin['Title'] == $name || ( $wp_plugin_slug == $slug . '-embedded' || $plugin['Name'] == $name . ' Embedded' ) ){
1635
- if($version){
1636
- if(version_compare($plugin['Version'], $version, '>=')){
1637
- $is = $plugin['Version'];
1638
- }
1639
- }else{
1640
- $is = $plugin['Version'];
1641
- }
1642
-
1643
- break;
1644
- }
1645
-
1646
- }
1647
-
1648
- //exception: Types name difference
1649
- if(!$is && $name == 'Types'){
1650
- return $this->plugin_is_installed('Types - Complete Solution for Custom Fields and Types', $slug, $version);
1651
- }
1652
-
1653
- return $is;
1654
- }
1655
-
1656
- public function plugin_is_embedded_version($name, $slug){
1657
- $is = false;
1658
-
1659
- $plugins = get_plugins();
1660
-
1661
- //false if teh full version is also installed
1662
- $is_full_installed = false;
1663
- foreach($plugins as $plugin_id => $plugin){
1664
-
1665
- if(($plugin['Name'] == $name && !preg_match("#-embedded$#", $slug)) ){
1666
- $is_full_installed = true;
1667
- break;
1668
- }
1669
-
1670
- }
1671
-
1672
- if($is_full_installed){
1673
- return false;
1674
- }
1675
-
1676
- foreach($plugins as $plugin_id => $plugin){
1677
-
1678
- // TBD
1679
- $wp_plugin_slug = dirname($plugin_id);
1680
- if( $wp_plugin_slug == $slug . '-embedded' && $plugin['Name'] == $name . ' Embedded'){
1681
- $is = true;
1682
- break;
1683
- }
1684
-
1685
- }
1686
-
1687
- return $is;
1688
-
1689
- }
1690
-
1691
- //Alias for plugin_is_installed
1692
- public function get_plugin_installed_version($name, $slug){
1693
-
1694
- return $this->plugin_is_installed($name, $slug);
1695
-
1696
- }
1697
-
1698
- public function get_plugin_repository_version($repository_id, $slug){
1699
- $version = false;
1700
-
1701
- if(!empty($this->settings['repositories'][$repository_id]['data']['packages'])){
1702
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
1703
- foreach($package['products'] as $product) {
1704
-
1705
- foreach($product['plugins'] as $plugin_slug){
1706
-
1707
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1708
-
1709
- if($download['slug'] == $slug){
1710
- $version = $download['version'];
1711
- break (3);
1712
- }
1713
-
1714
- }
1715
-
1716
- }
1717
- }
1718
- }
1719
-
1720
- return $version;
1721
- }
1722
-
1723
- public function is_uploading_allowed(){
1724
-
1725
- //_deprecated_function ( __FUNCTION__, '1.7.3', 'Installer_Dependencies::' . __FUNCTION__ );
1726
- return $this->dependencies->is_uploading_allowed();
1727
-
1728
- }
1729
-
1730
- public function download_plugin_ajax_handler(){
1731
-
1732
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1733
- require_once $this->plugin_path() . '/includes/installer-upgrader-skins.php';
1734
-
1735
- if(isset($_POST['data'])){
1736
-
1737
- $data = json_decode( base64_decode( $_POST['data'] ), true );
1738
-
1739
- }
1740
-
1741
- $ret = false;
1742
- $plugin_id = false;
1743
- $message = '';
1744
-
1745
- //validate subscription
1746
- $site_key = $this->get_repository_site_key($data['repository_id']);
1747
- $subscription_data = $this->fetch_subscription_data( $data['repository_id'], $site_key , self::SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT);
1748
-
1749
- if($subscription_data && !is_wp_error($subscription_data) && $this->repository_has_valid_subscription($data['repository_id'])){
1750
-
1751
- if($data['nonce'] == wp_create_nonce('install_plugin_' . $data['url'])){
1752
-
1753
- $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1754
- $upgrader = new Plugin_Upgrader($upgrader_skins);
1755
-
1756
- remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
1757
-
1758
- $plugins = get_plugins();
1759
-
1760
- //upgrade or install?
1761
- foreach($plugins as $id => $plugin){
1762
- $wp_plugin_slug = dirname($id);
1763
- $is_embedded = $this->plugin_is_embedded_version(preg_replace('/ Embedded$/', '', $plugin['Name']), preg_replace('/-embedded$/', '', $wp_plugin_slug));
1764
-
1765
- if($wp_plugin_slug == $data['slug'] || $is_embedded && preg_replace('/-embedded$/', '', $wp_plugin_slug) == $data['slug']){
1766
- $plugin_id = $id;
1767
- break;
1768
- }
1769
- }
1770
-
1771
- if($plugin_id && empty($is_embedded)){ //upgrade
1772
- $response['upgrade'] = 1;
1773
-
1774
- $plugin_is_active = is_plugin_active($plugin_id);
1775
-
1776
- $ret = $upgrader->upgrade($plugin_id);
1777
-
1778
- if(!$ret && !empty($upgrader->skin->installer_error)){
1779
- if(is_wp_error($upgrader->skin->installer_error)){
1780
- $message = $upgrader->skin->installer_error->get_error_message() .
1781
- ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1782
- }
1783
- }
1784
-
1785
- if($plugin_is_active){
1786
- //prevent redirects
1787
- add_filter('wp_redirect', '__return_false');
1788
- activate_plugin($plugin_id);
1789
- }
1790
-
1791
- }else{ //install
1792
-
1793
- if($is_embedded){
1794
- delete_plugins(array($plugin_id));
1795
- }
1796
-
1797
- $response['install'] = 1;
1798
- $ret = $upgrader->install($data['url']);
1799
- if(!$ret && !empty($upgrader->skin->installer_error)){
1800
- if(is_wp_error($upgrader->skin->installer_error)){
1801
- $message = $upgrader->skin->installer_error->get_error_message() .
1802
- ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1803
- }
1804
- }
1805
- }
1806
-
1807
- $plugins = get_plugins(); //read again
1808
-
1809
- if($ret && !empty($_POST['activate'])){
1810
- foreach($plugins as $id => $plugin){
1811
- $wp_plugin_slug = dirname($id);
1812
- if($wp_plugin_slug == $data['slug']){
1813
- $plugin_version = $plugin['Version'];
1814
- $plugin_id = $id;
1815
- break;
1816
- }
1817
- }
1818
-
1819
- }
1820
-
1821
- }
1822
-
1823
- } else { //subscription not valid
1824
-
1825
- $ret = false;
1826
- $message = __('Your subscription appears to no longer be valid. Please try to register again using a valid site key.', 'installer');
1827
- }
1828
-
1829
- $response['version'] = isset($plugin_version) ? $plugin_version : 0;
1830
- $response['plugin_id'] = $plugin_id;
1831
- $response['nonce'] = wp_create_nonce('activate_' . $plugin_id);
1832
- $response['success'] = $ret;
1833
- $response['message'] = $message;
1834
-
1835
- echo json_encode( $response );
1836
- exit;
1837
-
1838
- }
1839
-
1840
- public function download_plugin($slug, $url){
1841
-
1842
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1843
- require_once $this->plugin_path() . '/includes/installer-upgrader-skins.php';
1844
-
1845
- $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1846
- $upgrader = new Plugin_Upgrader($upgrader_skins);
1847
-
1848
- remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
1849
-
1850
- $plugins = get_plugins();
1851
-
1852
- $plugin_id = false;
1853
-
1854
- //upgrade or install?
1855
- foreach($plugins as $id => $plugin){
1856
- $wp_plugin_slug = dirname($id);
1857
- if($wp_plugin_slug == $slug){
1858
- $plugin_id = $id;
1859
- break;
1860
- }
1861
- }
1862
-
1863
- if($plugin_id){ //upgrade
1864
-
1865
- $plugin_is_active = is_plugin_active($plugin_id);
1866
-
1867
- $ret = $upgrader->upgrade($plugin_id);
1868
-
1869
- if($plugin_is_active){
1870
- activate_plugin($plugin_id);
1871
- }
1872
-
1873
- }else{ //install
1874
- $ret = $upgrader->install($url);
1875
- }
1876
-
1877
- return $ret;
1878
-
1879
- }
1880
-
1881
- public function activate_plugin(){
1882
-
1883
- $error = '';
1884
-
1885
- if(isset($_POST['nonce']) && isset($_POST['plugin_id']) && $_POST['nonce'] == wp_create_nonce('activate_' . $_POST['plugin_id'])){
1886
-
1887
- $plugin_id = $_POST['plugin_id'];
1888
-
1889
- // Deactivate any embedded version
1890
- $plugin_slug = dirname($plugin_id);
1891
- $active_plugins = get_option('active_plugins');
1892
- foreach($active_plugins as $plugin){
1893
- $wp_plugin_slug = dirname($plugin);
1894
- if($wp_plugin_slug == $plugin_slug . '-embedded'){
1895
- deactivate_plugins(array($plugin));
1896
- break;
1897
- }
1898
- }
1899
-
1900
- //prevent redirects
1901
- add_filter('wp_redirect', '__return_false', 10000);
1902
-
1903
- $return = activate_plugin($plugin_id);
1904
-
1905
- if(is_wp_error($return)){
1906
- $error = $return->get_error_message();
1907
- }
1908
-
1909
- }else{
1910
- $error = 'error';
1911
- }
1912
-
1913
- $ret = array('error' => $error);
1914
-
1915
- echo json_encode($ret);
1916
- exit;
1917
-
1918
- }
1919
-
1920
- public function custom_plugins_api_call($false, $action, $args){
1921
-
1922
- if($action == 'plugin_information'){
1923
-
1924
- $slug = $args->slug;
1925
-
1926
- foreach($this->settings['repositories'] as $repository_id => $repository){
1927
-
1928
- if(!$this->repository_has_valid_subscription($repository_id)){
1929
- $site_key = false;
1930
- }else{
1931
- $site_key = $repository['subscription']['key'];
1932
- }
1933
-
1934
- foreach($repository['data']['packages'] as $package){
1935
-
1936
- foreach($package['products'] as $product){
1937
-
1938
- foreach($product['plugins'] as $plugin_slug){
1939
-
1940
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1941
-
1942
- if($download['slug'] == $slug){
1943
-
1944
- $res = new stdClass();
1945
- $res->external = true;
1946
-
1947
- $res->name = $download['name'];
1948
- $res->slug = $slug;
1949
- $res->version = $download['version'];
1950
- $res->author = '';
1951
- $res->author_profile = '';
1952
- $res->last_updated = $download['date'];
1953
- //$res->homepage = $download['url'];
1954
-
1955
- if($site_key){
1956
- $res->download_link = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
1957
- }else{
1958
- // if(!empty($download['free-on-wporg'])
1959
- return false; //try somewhere else. e.g. wordpress.org
1960
- }
1961
-
1962
- $res->homepage = $repository['data']['url'];
1963
- $res->sections = array('Description' => $download['description'], 'Changelog' => $download['changelog']);
1964
-
1965
- return $res;
1966
-
1967
- }
1968
-
1969
- }
1970
-
1971
- }
1972
-
1973
- }
1974
-
1975
- }
1976
-
1977
- }
1978
-
1979
- return $false;
1980
-
1981
- }
1982
-
1983
- public function plugins_upgrade_check($update_plugins){
1984
-
1985
- if(!empty($this->settings['repositories'])){
1986
-
1987
- $plugins = get_plugins();
1988
-
1989
- foreach($plugins as $plugin_id => $plugin){
1990
-
1991
- $slug = dirname($plugin_id);
1992
- if(empty($slug)) continue;
1993
-
1994
- $version = $plugin['Version'];
1995
- $name = $plugin['Name'];
1996
-
1997
- foreach($this->settings['repositories'] as $repository_id => $repository){
1998
-
1999
-
2000
- if(!$this->repository_has_valid_subscription($repository_id)){
2001
- $site_key = false;
2002
- }else{
2003
- $site_key = $repository['subscription']['key'];
2004
- //$subscription_type = $this->get_subscription_type_for_repository($repository_id);
2005
- }
2006
-
2007
- foreach($repository['data']['packages'] as $package){
2008
-
2009
- foreach($package['products'] as $product){
2010
-
2011
- foreach($product['plugins'] as $plugin_slug){
2012
-
2013
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2014
-
2015
- if(!empty($download['free-on-wporg'])) {
2016
- continue;
2017
- }
2018
-
2019
- if(empty($update_plugins->response[$plugin_id]) && ($download['slug'] == $slug || $download['name'] == $name ) && version_compare($download['version'], $version, '>')){
2020
-
2021
- $response = new stdClass();
2022
- $response->id = 0;
2023
- $response->slug = $slug;
2024
- $response->plugin = $plugin_id;
2025
- $response->new_version = $download['version'];
2026
- $response->upgrade_notice = '';
2027
- $response->url = $download['url'];
2028
- if($site_key){
2029
- $response->package = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
2030
- }
2031
- $update_plugins->checked[$plugin_id] = $version;
2032
- $update_plugins->response[$plugin_id] = $response;
2033
-
2034
- }
2035
-
2036
- }
2037
-
2038
- }
2039
-
2040
- }
2041
-
2042
- }
2043
-
2044
- }
2045
-
2046
- }
2047
-
2048
- return $update_plugins;
2049
-
2050
- }
2051
-
2052
- public function setup_plugins_page_notices(){
2053
-
2054
- $plugins = get_plugins();
2055
-
2056
- foreach($plugins as $plugin_id => $plugin){
2057
-
2058
- $slug = dirname($plugin_id);
2059
- if(empty($slug)) continue;
2060
-
2061
- $name = $plugin['Name'];
2062
-
2063
- foreach($this->settings['repositories'] as $repository_id => $repository){
2064
-
2065
- if(!$this->repository_has_valid_subscription($repository_id)){
2066
- $site_key = false;
2067
- }else{
2068
- $site_key = $repository['subscription']['key'];
2069
- }
2070
-
2071
- foreach($repository['data']['packages'] as $package){
2072
-
2073
- foreach($package['products'] as $product){
2074
-
2075
- foreach($product['plugins'] as $plugin_slug){
2076
-
2077
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2078
-
2079
- if(!empty($download['free-on-wporg'])) {
2080
- continue;
2081
- }
2082
-
2083
- if( $download['slug'] == $slug || $download['name'] == $name ){
2084
-
2085
- if( !$site_key || !$this->plugin_is_registered($repository_id, $download['slug']) ){
2086
- add_action( "after_plugin_row_" . $plugin_id, array($this, 'show_purchase_notice_under_plugin'), 10, 3 );
2087
- }
2088
-
2089
- }
2090
-
2091
- }
2092
-
2093
- }
2094
-
2095
- }
2096
-
2097
- }
2098
-
2099
- }
2100
-
2101
- }
2102
-
2103
- public function show_purchase_notice_under_plugin($plugin_file, $plugin_data, $status){
2104
-
2105
- $wp_list_table = _get_list_table('WP_Plugins_List_Table');
2106
- ?>
2107
-
2108
- <tr class="plugin-update-tr"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
2109
- <div class="update-message installer-q-icon">
2110
- <?php
2111
- printf(__('You need to have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s.', 'installer'),
2112
- '<a href="' . $this->menu_url() . '">', '</a>');
2113
- ?>
2114
- </div>
2115
- </tr>
2116
-
2117
- <?php
2118
-
2119
- }
2120
-
2121
- public function localize_strings(){
2122
-
2123
- if(!empty($this->settings['repositories'])){
2124
- foreach($this->settings['repositories'] as $repository_id => $repository){
2125
- //set name as call2action when don't have any
2126
- //products
2127
- foreach($repository['data']['packages'] as $package_id => $package){
2128
- foreach($package['products'] as $product_id => $product){
2129
- if(empty($product['call2action'])){
2130
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['call2action'] = $product['name'];
2131
- }
2132
-
2133
- foreach($product['upgrades'] as $idx => $upg){
2134
- if(empty($upg['call2action'])){
2135
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$idx]['call2action'] = $upg['name'];
2136
- }
2137
- }
2138
-
2139
- foreach($product['renewals'] as $idx => $rnw){
2140
- if(empty($rnw['call2action'])){
2141
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['renewals'][$idx]['call2action'] = $rnw['name'];
2142
- }
2143
-
2144
- }
2145
-
2146
- }
2147
- }
2148
- }
2149
- }
2150
-
2151
- global $sitepress;
2152
- if(is_null($sitepress)){
2153
- return;
2154
- }
2155
-
2156
- // default strings are always in English
2157
- $user_admin_language = $sitepress->get_admin_language();
2158
-
2159
- if($user_admin_language != 'en'){
2160
- foreach($this->settings['repositories'] as $repository_id => $repository){
2161
-
2162
- $localization = $repository['data']['localization'];
2163
-
2164
- //packages
2165
- foreach($repository['data']['packages'] as $package_id => $package){
2166
-
2167
- if( isset($localization['packages'][$package_id]['name'][$user_admin_language]) ){
2168
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['name'] = $localization['packages'][$package_id]['name'][$user_admin_language];
2169
- }
2170
- if( isset($localization['packages'][$package_id]['description'][$user_admin_language]) ){
2171
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['description'] = $localization['packages'][$package_id]['description'][$user_admin_language];
2172
- }
2173
-
2174
- }
2175
-
2176
- //products
2177
- foreach($repository['data']['packages'] as $package_id => $package){
2178
- foreach($package['products'] as $product_id => $product){
2179
-
2180
- if( isset($localization['products'][$product_id]['name'][$user_admin_language]) ){
2181
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['name']
2182
- = $localization['products'][$product_id]['name'][$user_admin_language];
2183
- }
2184
- if( isset($localization['products'][$product_id]['description'][$user_admin_language]) ){
2185
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['description']
2186
- = $localization['products'][$product_id]['description'][$user_admin_language];
2187
- }
2188
- if( isset($localization['products'][$product_id]['call2action'][$user_admin_language]) ){
2189
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['name']
2190
- = $localization['products'][$product_id]['call2action'][$user_admin_language];
2191
- }
2192
-
2193
-
2194
- }
2195
- }
2196
-
2197
- //subscription info
2198
- if(isset($repository['data']['subscriptions_meta']['expiration'])){
2199
- foreach($repository['data']['subscriptions_meta']['expiration'] as $subscription_id => $note){
2200
- if(isset($localization['subscriptions-notes'][$subscription_id]['expiration-warning'][$user_admin_language])){
2201
- $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_id]['warning_message']
2202
- = $localization['subscriptions-notes'][$subscription_id]['expiration-warning'][$user_admin_language];
2203
- }
2204
- }
2205
- }
2206
-
2207
- }
2208
- }
2209
-
2210
- }
2211
-
2212
- public function get_matching_cp($repository, $args = array()){
2213
- $match = false;
2214
-
2215
-
2216
- $cp_name = $cp_author = false;
2217
-
2218
- if(isset($this->config['src_name']) && isset($this->config['src_author'])){
2219
-
2220
- $cp_name = $this->config['src_name'];
2221
- $cp_author = $this->config['src_author'];
2222
-
2223
- }elseif(isset($args['src_name']) && isset($args['src_author'])){
2224
-
2225
- $cp_name = $args['src_name'];
2226
- $cp_author = $args['src_author'];
2227
-
2228
- }
2229
-
2230
- if(isset($repository['data']['marketing_cp'])){
2231
-
2232
- foreach($repository['data']['marketing_cp'] as $cp){
2233
-
2234
- if(!empty($cp['exp']) && time() > $cp['exp']){
2235
- continue;
2236
- }
2237
-
2238
- //Use theme_name for plugins too
2239
- if(!empty($cp['theme_name'])){
2240
- if($cp['author_name'] == $cp_author && $cp['theme_name'] == $cp_name){
2241
- $match = $cp;
2242
- continue;
2243
- }
2244
- }else{
2245
- if($cp['author_name'] == $cp_author){
2246
- $match = $cp;
2247
- continue;
2248
- }
2249
- }
2250
-
2251
- }
2252
-
2253
- }
2254
-
2255
- return $match;
2256
- }
2257
-
2258
- public function set_filtered_prices($args = array()){
2259
-
2260
- foreach($this->settings['repositories'] as $repository_id => $repository){
2261
-
2262
- $match = $this->get_matching_cp($repository, $args);
2263
-
2264
- if(empty($match)) continue;
2265
-
2266
- foreach($repository['data']['packages'] as $package_id => $package){
2267
-
2268
- foreach($package['products'] as $product_id => $product){
2269
-
2270
- if($match['dtp'] == '%'){
2271
- $fprice = round( $product['price'] * (1 - $match['amt']/100), 2 );
2272
- $fprice = $fprice != round($fprice) ? sprintf('%.2f', $fprice) : round($fprice, 0);
2273
- }elseif($match['dtp'] == '-'){
2274
- $fprice = $product['price'] - $match['amt'];
2275
- }else{
2276
- $fprice = $product['price'];
2277
- }
2278
-
2279
- if($fprice){
2280
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['price_disc'] = $fprice;
2281
-
2282
- $url_glue = false !== strpos($this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['url'], '?') ? '&' : '?';
2283
- $cpndata = base64_encode(json_encode(array('theme_author' => $match['author_name'], 'theme_name' => $match['theme_name'], 'vlc' => $match['vlc'])));
2284
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['url'] .= $url_glue . 'cpn=' . $cpndata;
2285
-
2286
- foreach($product['upgrades'] as $upgrade_id => $upgrade){
2287
-
2288
- $fprice = false;
2289
- if($match['dtp'] == '%'){
2290
- $fprice = round( $upgrade['price'] * (1 - $match['amt']/100), 2 );
2291
- $fprice = $fprice != round($fprice) ? sprintf('%.2f', $fprice) : round($fprice, 0);
2292
- }elseif($match['dtp'] == '-'){
2293
- $fprice = $upgrade['price'] - $match['amt'];
2294
- }
2295
- if($fprice){
2296
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$upgrade_id]['price_disc'] = $fprice;
2297
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$upgrade_id]['url'] .= $url_glue . 'cpn=' . $cpndata;
2298
- }
2299
-
2300
-
2301
- }
2302
-
2303
- }
2304
-
2305
- }
2306
-
2307
- }
2308
-
2309
- }
2310
-
2311
- }
2312
-
2313
- public function set_hierarchy_and_order(){
2314
-
2315
- //2 levels
2316
- if(!empty($this->settings['repositories'])) {
2317
- foreach ($this->settings['repositories'] as $repository_id => $repository) {
2318
-
2319
- if( empty( $repository['data']['packages'] ) ) continue;
2320
-
2321
- $all_packages = $repository['data']['packages'];
2322
- $ordered_packages = array();
2323
-
2324
- //backward compatibility - 'order'
2325
- foreach($all_packages as $k => $v){
2326
- if(!isset($v['order'])){
2327
- $all_packages[$k]['order'] = 0;
2328
- }
2329
- }
2330
-
2331
- //select parents
2332
- foreach ($all_packages as $package_id => $package) {
2333
- if(empty($package['parent'])){
2334
- $ordered_packages[$package_id] = $package;
2335
- }
2336
- }
2337
-
2338
- //add sub-packages
2339
- foreach($all_packages as $package_id => $package){
2340
- if(!empty($package['parent'])) {
2341
- if(isset($ordered_packages[$package['parent']])){
2342
- $ordered_packages[$package['parent']]['sub-packages'][$package_id] = $package;
2343
- }
2344
- }
2345
- }
2346
-
2347
- // order parents
2348
- usort($ordered_packages, array($this, '_order_packages_callback'));
2349
- //order sub-packages
2350
- foreach($ordered_packages as $package_id => $package){
2351
- if(!empty($package['sub-packages'])) {
2352
- usort($ordered_packages[$package_id]['sub-packages'], create_function('$a, $b', 'return $a[\'order\'] > $b[\'order\'];'));
2353
- }
2354
- }
2355
-
2356
- $this->settings['repositories'][$repository_id]['data']['packages'] = $ordered_packages;
2357
-
2358
-
2359
- }
2360
- }
2361
-
2362
-
2363
- }
2364
-
2365
- public function _order_packages_callback($a, $b){
2366
- return $a['order'] > $b['order'];
2367
- }
2368
-
2369
- public function get_support_tag_by_name( $name, $repository ){
2370
-
2371
- if( is_array($this->settings['repositories'][$repository]['data']['support_tags'] )){
2372
- foreach( $this->settings['repositories'][$repository]['data']['support_tags'] as $support_tag){
2373
- if( $support_tag['name'] == $name ){
2374
- return $support_tag['url'];
2375
- }
2376
- }
2377
- }
2378
-
2379
- return false;
2380
- }
2381
-
2382
- public function plugin_upgrade_custom_errors(){
2383
-
2384
- if ( isset($_REQUEST['action']) ) {
2385
-
2386
- $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
2387
-
2388
- //bulk mode
2389
- if('update-selected' == $action) {
2390
-
2391
- global $plugins;
2392
-
2393
- if(isset($plugins) && is_array($plugins)) {
2394
-
2395
- foreach ($plugins as $k => $plugin) {
2396
- $plugin_repository = false;
2397
-
2398
- $wp_plugin_slug = dirname($plugin);
2399
-
2400
- foreach ($this->settings['repositories'] as $repository_id => $repository) {
2401
-
2402
- foreach ($repository['data']['packages'] as $package) {
2403
-
2404
- foreach ($package['products'] as $product) {
2405
-
2406
- foreach ($product['plugins'] as $plugin_slug) {
2407
-
2408
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2409
-
2410
- if ($download['slug'] == $wp_plugin_slug) {
2411
- $plugin_repository = $repository_id;
2412
- $product_name = $repository['data']['product-name'];
2413
- $plugin_name = $download['name'];
2414
- $free_on_wporg = !empty($download['free-on-wporg']);
2415
- break;
2416
- }
2417
-
2418
- }
2419
-
2420
- }
2421
-
2422
- }
2423
-
2424
- }
2425
-
2426
- if ($plugin_repository) {
2427
-
2428
- //validate subscription
2429
- static $sub_cache = array();
2430
-
2431
- if(empty($sub_cache[$plugin_repository])){
2432
- $site_key = $this->get_repository_site_key($plugin_repository);
2433
- if ($site_key) {
2434
- $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2435
- }
2436
-
2437
- $sub_cache[$plugin_repository]['site_key'] = $site_key;
2438
- $sub_cache[$plugin_repository]['subscription_data'] = isset($subscription_data) ? $subscription_data : false;
2439
- }else{
2440
-
2441
- $site_key = $sub_cache[$plugin_repository]['site_key'];
2442
- $subscription_data = $sub_cache[$plugin_repository]['subscription_data'];
2443
-
2444
- }
2445
-
2446
- if(!$site_key && !empty($free_on_wporg)){ // allow the download from wp.org
2447
- continue;
2448
- }
2449
-
2450
- if (empty($site_key) || empty($subscription_data)) {
2451
-
2452
-
2453
- $error_message = sprintf(__("%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer'),
2454
- '<strong>' . $plugin_name . '</strong>', '<a target="_top" href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2455
- '#repository-' . $plugin_repository . '">', $product_name, '</a>');
2456
-
2457
- echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2458
-
2459
- unset($plugins[$k]);
2460
-
2461
-
2462
- }
2463
-
2464
- }
2465
-
2466
- }
2467
-
2468
- }
2469
-
2470
- }
2471
-
2472
-
2473
- if( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
2474
-
2475
- $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
2476
-
2477
- $wp_plugin_slug = dirname($plugin);
2478
-
2479
- $plugin_repository = false;
2480
-
2481
- foreach($this->settings['repositories'] as $repository_id => $repository){
2482
-
2483
- foreach($repository['data']['packages'] as $package){
2484
-
2485
- foreach($package['products'] as $product){
2486
-
2487
- foreach($product['plugins'] as $plugin_slug){
2488
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2489
-
2490
- //match by folder, will change to match by name and folder
2491
- if($download['slug'] == $wp_plugin_slug) {
2492
- $plugin_repository = $repository_id;
2493
- $product_name = $repository['data']['product-name'];
2494
- $plugin_name = $download['name'];
2495
- $free_on_wporg = !empty($download['free-on-wporg']);
2496
- break;
2497
- }
2498
-
2499
- }
2500
-
2501
- }
2502
-
2503
- }
2504
-
2505
- }
2506
-
2507
- if($plugin_repository) {
2508
-
2509
- //validate subscription
2510
- $site_key = $this->get_repository_site_key($plugin_repository);
2511
- if ($site_key) {
2512
- $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2513
- }
2514
-
2515
- if ( (empty($site_key) || empty($subscription_data)) && empty($free_on_wporg)) {
2516
-
2517
- $error_message = sprintf(__("%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer'),
2518
- '<strong>'.$plugin_name . '</strong>', '<a href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2519
- '#repository-' . $plugin_repository . '">', $product_name, '</a>');
2520
-
2521
- if(defined('DOING_AJAX')){ //WP 4.2
2522
-
2523
- $status = array(
2524
- 'update' => 'plugin',
2525
- 'plugin' => $plugin,
2526
- 'slug' => sanitize_key( $_POST['slug'] ),
2527
- 'oldVersion' => '',
2528
- 'newVersion' => '',
2529
- );
2530
-
2531
- $status['errorCode'] = 'wp_installer_invalid_subscription';
2532
- $status['error'] = $error_message;
2533
-
2534
- wp_send_json_error( $status );
2535
-
2536
- } else { // WP 4.1.1
2537
- echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2538
-
2539
-
2540
- echo '<div class="wrap">';
2541
- echo '<h2>' . __('Update Plugin') . '</h2>';
2542
- echo '<a href="' . admin_url('plugins.php') . '">' . __('Return to the plugins page') . '</a>';
2543
- echo '</div>';
2544
- require_once(ABSPATH . 'wp-admin/admin-footer.php');
2545
- exit;
2546
-
2547
- }
2548
-
2549
- }
2550
-
2551
-
2552
- }
2553
-
2554
- }
2555
- }
2556
-
2557
- }
2558
-
2559
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/includes/translation-service-info.class.php DELETED
@@ -1,35 +0,0 @@
1
- <?php
2
-
3
- class TranslationServiceInfo{
4
-
5
- function __construct(){
6
-
7
- add_action('installer_fetched_subscription_data',array($this, 'save_info'), 10, 2);
8
-
9
- }
10
-
11
- function save_info($data, $repository_id) {
12
-
13
- $ts_info = isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info'] ) ?
14
- WP_Installer()->settings['repositories'][$repository_id]['ts_info'] : false;
15
-
16
- $save_settings = false;
17
- if(isset($data->ts_info['preferred']) && empty($ts_info['preferred'])){
18
- WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $data->ts_info['preferred'];
19
- $save_settings = true;
20
- }
21
-
22
- if(isset($data->ts_info['referal']) && empty($ts_info['referal'])){
23
- WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'] = $data->ts_info['referal'];
24
- $save_settings = true;
25
- }
26
-
27
- if($save_settings){
28
- WP_Installer()->save_settings();
29
- }
30
-
31
- }
32
-
33
- }
34
-
35
- new TranslationServiceInfo();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/installer.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
- define('WP_INSTALLER_VERSION', '1.7.8');
3
-
4
- include_once dirname(__FILE__) . '/includes/installer.class.php';
5
-
6
- function WP_Installer() {
7
- return WP_Installer::instance();
8
- }
9
-
10
-
11
- WP_Installer();
12
-
13
- include_once WP_Installer()->plugin_path() . '/includes/installer-api.php';
14
- include_once WP_Installer()->plugin_path() . '/includes/translation-service-info.class.php';
15
- include_once WP_Installer()->plugin_path() . '/includes/class-installer-dependencies.php';
16
-
17
- // Ext function
18
- function WP_Installer_Show_Products($args = array()){
19
-
20
- WP_Installer()->show_products($args);
21
-
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/loader.php DELETED
@@ -1,151 +0,0 @@
1
- <?php
2
-
3
- if ( ! defined( 'ABSPATH' ) ) {
4
- exit; // Exit if accessed directly
5
- }
6
-
7
- //It should only be loaded on the admin side
8
- if( !is_admin() ){
9
- if(!function_exists('WP_Installer_Setup')){ function WP_Installer_Setup(){} }
10
- $wp_installer_instance = null;
11
- return;
12
- }
13
-
14
-
15
- $wp_installer_instance = dirname(__FILE__) . '/installer.php';
16
-
17
-
18
- // Global stack of instances
19
- global $wp_installer_instances;
20
- $wp_installer_instances[$wp_installer_instance] = array(
21
- 'bootfile' => $wp_installer_instance,
22
- 'version' => '1.7.8'
23
- );
24
-
25
-
26
- /* EXCEPTIONS ********************************************************************************************/
27
- // Exception: When WPML prior 3.2 is used, that instance must be used regardless of another newer instance
28
- // Case 1: WPML loaded before Types - eliminate other instances
29
- if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.2', '<') ) {
30
- foreach($wp_installer_instances as $key => $instance) {
31
- if(isset($instance['args']['site_key_nags'])){
32
- $wp_installer_instances[$key]['version'] = '9.9';
33
- }else{
34
- $wp_installer_instances[$key]['version'] = '0';
35
- }
36
- }
37
- }
38
-
39
- // Exception: Types 1.8.9 (Installer 1.7.0) with WPML before 3.3 (Installer before 1.7.0)
40
- // New products file http://d2salfytceyqoe.cloudfront.net/wpml-products33.json overrides the old one
41
- // while the WPML's instance is being used
42
- // => Force using the new Installer Instance
43
- if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.3.1', '<') ) {
44
-
45
- // if Installer 1.7.0+ is present, unregister Installer from old WPML
46
- // Force Installer 1.7.0+ being used over older Installer versions
47
- $installer_171_plus_on = false;
48
- foreach($wp_installer_instances as $key => $instance) {
49
- if( version_compare( $instance['version'], '1.7.1', '>=' ) ){
50
- $installer_171_plus_on = true;
51
- break;
52
- }
53
- }
54
-
55
- if( $installer_171_plus_on ){
56
- foreach($wp_installer_instances as $key => $instance) {
57
-
58
- if( version_compare( $instance['version'], '1.7.0', '<' ) ){
59
- unset( $wp_installer_instances[$key] );
60
- }
61
-
62
- }
63
- }
64
-
65
- }
66
-
67
- // Exception: When using the embedded plugins module allow the set up to run completely with the
68
- // Installer instance that triggers it
69
- if( isset( $_POST['installer_instance'] ) && isset( $wp_installer_instances[$_POST['installer_instance']] ) ){
70
- $wp_installer_instances[$_POST['installer_instance']]['version'] = '999';
71
- }
72
- /* EXCEPTIONS ********************************************************************************************/
73
-
74
-
75
- // Only one of these in the end
76
- remove_action('after_setup_theme', 'wpml_installer_instance_delegator', 1);
77
- add_action('after_setup_theme', 'wpml_installer_instance_delegator', 1);
78
-
79
- // When all plugins load pick the newest version
80
- if(!function_exists('wpml_installer_instance_delegator')){
81
- function wpml_installer_instance_delegator(){
82
- global $wp_installer_instances;
83
-
84
- // version based election
85
- foreach($wp_installer_instances as $instance){
86
-
87
- if(!isset($delegate)){
88
- $delegate = $instance;
89
- continue;
90
- }
91
-
92
- if(version_compare($instance['version'], $delegate['version'], '>')){
93
- $delegate = $instance;
94
- }
95
- }
96
-
97
- // priority based election
98
- $highest_priority = null;
99
- foreach($wp_installer_instances as $instance) {
100
- if(isset($instance['args']['high_priority'])){
101
- if(is_null($highest_priority) || $instance['args']['high_priority'] <= $highest_priority){
102
- $highest_priority = $instance['args']['high_priority'];
103
- $delegate = $instance;
104
- }
105
- }
106
- }
107
-
108
- // Exception: When WPML prior 3.2 is used, that instance must be used regardless of another newer instance
109
- // Case 2: WPML loaded after Types
110
- if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.2', '<') ) {
111
- foreach($wp_installer_instances as $key => $instance) {
112
- if(isset($instance['args']['site_key_nags'])){
113
- $delegate = $instance;
114
- $wp_installer_instances = array($key => $delegate); //Eliminate other instances
115
- break;
116
- }
117
- }
118
- }
119
-
120
- include_once $delegate['bootfile'];
121
-
122
- // set configuration
123
- if(strpos(realpath($delegate['bootfile']), realpath(TEMPLATEPATH)) === 0){
124
- $delegate['args']['in_theme_folder'] = dirname(ltrim(str_replace(realpath(TEMPLATEPATH), '', realpath($delegate['bootfile'])), '\\/'));
125
- }
126
- if(isset($delegate['args']) && is_array($delegate['args'])){
127
- foreach($delegate['args'] as $key => $value){
128
- WP_Installer()->set_config($key, $value);
129
- }
130
- }
131
-
132
- }
133
- }
134
-
135
- if(!function_exists('WP_Installer_Setup')){
136
-
137
- // $args:
138
- // plugins_install_tab = true|false (default: true)
139
- // repositories_include = array() (default: all)
140
- // repositories_exclude = array() (default: none)
141
- // template = name (default: default)
142
- //
143
- // Ext function
144
- function WP_Installer_Setup($wp_installer_instance, $args = array()){
145
- global $wp_installer_instances;
146
-
147
- $wp_installer_instances[$wp_installer_instance]['args'] = $args;
148
-
149
- }
150
-
151
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/locale/installer-ar.mo DELETED
Binary file
embedded/installer/locale/installer-de_DE.mo DELETED
Binary file
embedded/installer/locale/installer-el.mo DELETED
Binary file
embedded/installer/locale/installer-es_ES.mo DELETED
Binary file
embedded/installer/locale/installer-fr_FR.mo DELETED
Binary file
embedded/installer/locale/installer-he_IL.mo DELETED
Binary file
embedded/installer/locale/installer-it_IT.mo DELETED
Binary file
embedded/installer/locale/installer-ja.mo DELETED
Binary file
embedded/installer/locale/installer-ko_KR.mo DELETED
Binary file
embedded/installer/locale/installer-nl_NL.mo DELETED
Binary file
embedded/installer/locale/installer-pl_PL.mo DELETED
Binary file
embedded/installer/locale/installer-pt_BR.mo DELETED
Binary file
embedded/installer/locale/installer-pt_PT.mo DELETED
Binary file
embedded/installer/locale/installer-ru_RU.mo DELETED
Binary file
embedded/installer/locale/installer-sv_SE.mo DELETED
Binary file
embedded/installer/locale/installer-uk_UA.mo DELETED
Binary file
embedded/installer/locale/installer-vi.mo DELETED
Binary file
embedded/installer/locale/installer-zh_CN.mo DELETED
Binary file
embedded/installer/locale/installer-zh_TW.mo DELETED
Binary file
embedded/installer/locale/orig/installer.po DELETED
@@ -1,230 +0,0 @@
1
- # This file was generated by WPML
2
- # WPML is a WordPress plugin that can turn any WordPress site into a full featured multilingual content management system.
3
- # https://wpml.org
4
- msgid ""
5
- msgstr ""
6
- "Content-Type: text/plain; charset=utf-8\n"
7
- "Content-Transfer-Encoding: 8bit\n"
8
- "Project-Id-Version:WPML_EXPORT\n"
9
- "POT-Creation-Date: \n"
10
- "PO-Revision-Date: \n"
11
- "Last-Translator: \n"
12
- "Language-Team: \n"
13
- "Language:en\n"
14
- "MIME-Version: 1.0\n"
15
-
16
- msgid "Installer"
17
- msgstr ""
18
-
19
- msgid "Registered"
20
- msgstr ""
21
-
22
- msgid "Register"
23
- msgstr ""
24
-
25
- msgid "To get automatic updates, you need to register %s for this site. %sRegister %s%s"
26
- msgstr ""
27
-
28
- msgid "Dismiss"
29
- msgstr ""
30
-
31
- msgid "Commercial"
32
- msgstr ""
33
-
34
- msgid "Installer cannot contact our updates server to get information about the available products and check for new versions. If you are seeing this message for the first time, you can ignore it, as it may be a temporary communication problem. If the problem persists and your WordPress admin is slowing down, you can disable automated version checks. Add the following line to your wp-config.php file:"
35
- msgstr ""
36
-
37
- msgid "No repositories defined."
38
- msgstr ""
39
-
40
- msgid "%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates."
41
- msgstr ""
42
-
43
- msgid "Invalid site key for the current site."
44
- msgstr ""
45
-
46
- msgid "You will have to renew your subscription in order to continue getting the updates and support."
47
- msgstr ""
48
-
49
- msgid "%sRenew here%s."
50
- msgstr ""
51
-
52
- msgid "Your subscription appears to no longer be valid. Please try to register again using a valid site key."
53
- msgstr ""
54
-
55
- msgid "You need to have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s."
56
- msgstr ""
57
-
58
- msgid "%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first."
59
- msgstr ""
60
-
61
- msgid "Update Plugin"
62
- msgstr ""
63
-
64
- msgid "Return to the plugins page"
65
- msgstr ""
66
-
67
- msgid "Your subscription expires in %d day."
68
- msgstr ""
69
-
70
- msgid "Your subscription expires in %d days."
71
- msgstr ""
72
-
73
- msgid "Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s."
74
- msgstr ""
75
-
76
- msgid "Plugin"
77
- msgstr ""
78
-
79
- msgid "downloading..."
80
- msgstr ""
81
-
82
- msgid "failed!"
83
- msgstr ""
84
-
85
- msgid "downloaded"
86
- msgstr ""
87
-
88
- msgid "activating"
89
- msgstr ""
90
-
91
- msgid "activated"
92
- msgstr ""
93
-
94
- msgid "Activate after download"
95
- msgstr ""
96
-
97
- msgid "Operation complete!"
98
- msgstr ""
99
-
100
- msgid "Download failed!\n\nClick OK to revalidate your subscription or CANCEL to try again."
101
- msgstr ""
102
-
103
- msgid "Available"
104
- msgstr ""
105
-
106
- msgid "Installed"
107
- msgstr ""
108
-
109
- msgid "Downloading"
110
- msgstr ""
111
-
112
- msgid "Activate"
113
- msgstr ""
114
-
115
- msgid "Download"
116
- msgstr ""
117
-
118
- msgid "Downloads:"
119
- msgstr ""
120
-
121
- msgid "Current version"
122
- msgstr ""
123
-
124
- msgid "Released"
125
- msgstr ""
126
-
127
- msgid "Installed version"
128
- msgstr ""
129
-
130
- msgid "(embedded)"
131
- msgstr ""
132
-
133
- msgid "installing..."
134
- msgstr ""
135
-
136
- msgid "updating..."
137
- msgstr ""
138
-
139
- msgid "installed"
140
- msgstr ""
141
-
142
- msgid "updated"
143
- msgstr ""
144
-
145
- msgid "Download failed!\n\nPlease refresh the page and try again."
146
- msgstr ""
147
-
148
- msgid "Incorrect setup"
149
- msgstr ""
150
-
151
- msgid "Invalid product"
152
- msgstr ""
153
-
154
- msgid "Unknown repository"
155
- msgstr ""
156
-
157
- msgid " Your current site key (%s) does not match the selected product (%s)."
158
- msgstr ""
159
-
160
- msgid "Buy %s"
161
- msgstr ""
162
-
163
- msgid "Already bought %s?"
164
- msgstr ""
165
-
166
- msgid "Renew %s"
167
- msgstr ""
168
-
169
- msgid "Remove current site key (%s)"
170
- msgstr ""
171
-
172
- msgid "%s support on wpml.org"
173
- msgstr ""
174
-
175
- msgid "Enter site key"
176
- msgstr ""
177
-
178
- msgid "Subscription is expired."
179
- msgstr ""
180
-
181
- msgid "Add"
182
- msgstr ""
183
-
184
- msgid "Are you sure you want to remove this site key?"
185
- msgstr ""
186
-
187
- msgid "Register %s"
188
- msgstr ""
189
-
190
- msgid "1. Go to your %s%s account%s and add this site URL: %s"
191
- msgstr ""
192
-
193
- msgid "Unregister %s from this site"
194
- msgstr ""
195
-
196
- msgid "%s is registered on this site. You will receive automatic updates until %s"
197
- msgstr ""
198
-
199
- msgid "%s is registered on this site. Your Lifetime account gives you updates for life."
200
- msgstr ""
201
-
202
- msgid "This page lets you install plugins and update existing plugins. To remove any of these plugins, go to the %splugins%s page and if you have the permission to remove plugins you should be able to do this."
203
- msgstr ""
204
-
205
- msgid "Already bought?"
206
- msgstr ""
207
-
208
- msgid "2. Enter your site key"
209
- msgstr ""
210
-
211
- msgid "Subscription is expired. You need to either purchase a new subscription or upgrade if available."
212
- msgstr ""
213
-
214
- msgid "Check for updates"
215
- msgstr ""
216
-
217
- msgid "Individual components"
218
- msgstr ""
219
-
220
- msgid "OK"
221
- msgstr ""
222
-
223
- msgid "Cancel"
224
- msgstr ""
225
-
226
- msgid "Are you sure you want to unregister?"
227
- msgstr ""
228
-
229
- msgid "Click to see individual components options."
230
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/repositories.xml DELETED
@@ -1,13 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <repositories>
3
- <repository>
4
- <id>wpml</id>
5
- <apiurl>https://api.wpml.org/</apiurl>
6
- <products>http://d2salfytceyqoe.cloudfront.net/wpml33-products.json</products>
7
- </repository>
8
- <repository>
9
- <id>toolset</id>
10
- <apiurl>https://api.wp-types.com/</apiurl>
11
- <products>http://d7j863fr5jhrr.cloudfront.net/toolset33-products.json</products>
12
- </repository>
13
- </repositories>
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/res/css/admin.css DELETED
@@ -1,186 +0,0 @@
1
- .otgsi_site_key_form{
2
- display:none;
3
- /*display:inline;*/
4
- }
5
-
6
- .installer-status-installing, .installer-status-installed, .installer-status-updating, .installer-status-updated, .installer-status-activating, .installer-status-activated, .installer-status-success{
7
- display: none;
8
- }
9
- .installer-status-installing{color: #FF9900; }
10
- .installer-status-installed{color: #003300; font-weight: bold; }
11
- .installer-status-updating{color: #FF9900; }
12
- .installer-status-updated{color: #003300; font-weight: bold; }
13
-
14
- .installer-status-activating{color: #996666 }
15
- .installer-status-activated{color: #333366; font-weight: bold; }
16
-
17
- .js-status-success p{
18
- color: #FF9900;
19
- padding: 4px;
20
- }
21
-
22
- .installer-green-text{
23
- color:#006600;
24
- font-weight:bold;
25
- }
26
-
27
- .installer-red-text{
28
- color:#b22121;
29
- font-weight:bold;
30
- }
31
-
32
- .installer-products-list li{
33
- display: inline;
34
- margin-right: 20px;
35
- }
36
-
37
- .otgs_wp_installer_table a.disabled{
38
- color:#888;
39
- }
40
-
41
- .otgs_wp_installer_subtable{
42
- clear: both;
43
- margin-left:-20px;
44
- }
45
- .otgs_wp_installer_subtable td p{
46
- font-size: 92%;
47
- }
48
-
49
- .installer-status-error{
50
- color: #f00;
51
- }
52
-
53
- .installer-status-note{
54
- color: #6F6E6D;
55
- font-style: italic;
56
- }
57
-
58
- .installer-warn-box{
59
- -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #962722;background-color:#F5C8C6;
60
- color: #333;
61
- padding: 5px;
62
- }
63
- .installer-warn-box span.details{
64
- font-style: italic;
65
- color:#777;
66
- }
67
-
68
- .installer-error-box{
69
- color:#962722;
70
- margin-top: 10px;
71
- }
72
- .installer-error-box p{
73
- margin: 10px 0 10px 0;
74
- -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #962722;background-color:#F5C8C6;
75
- color: #333;
76
- padding: 5px;
77
- text-align: center;
78
- }
79
-
80
- .spinner-inline{
81
- float: none;
82
- display: inline-block;
83
- visibility: visible;
84
- }
85
-
86
- .installer-q-icon:before{
87
- content: '\f223' !important;
88
- }
89
-
90
- .otgsi_yellow_bg{
91
- background-color: #f2f46b;
92
- }
93
-
94
- .otgs_wp_installer_table_compact{
95
- width:480px;
96
- border: solid 1px #999;
97
- padding:10px;
98
- border-radius: 5px;
99
- }
100
-
101
- .installer-plugins-list-compact{
102
- background-color: #fff;
103
- border-collapse: collapse;
104
- border:solid 1px #C1DAD7;
105
- width:100%;
106
- }
107
-
108
- .installer-plugins-list-compact tr th{
109
- padding-top:3px;
110
- background-color: #ccc;
111
- }
112
-
113
- .installer-plugins-list-compact tr{
114
- background-color: #ddd;
115
- }
116
-
117
- .installer-plugins-list-compact tr.even{
118
- background-color: #eee;
119
- }
120
-
121
- .installer-plugins-list-compact td{
122
- padding:2px 5px 2px 5px;
123
- border-right: 1px solid #C1DAD7;
124
- border-bottom: 1px solid #C1DAD7;
125
- }
126
-
127
- .installer-plugins-list-compact td.twelve{
128
- width:16px;
129
- }
130
-
131
- .otgs_wp_installer_table_compact .installer-status-downloading,
132
- .otgs_wp_installer_table_compact .installer-status-downloaded,
133
- .otgs_wp_installer_table_compact .installer-status-activating,
134
- .otgs_wp_installer_table_compact .installer-status-activated{
135
- display: none;
136
- color:transparent; width: 12px; padding:2px;
137
- }
138
-
139
- .otgs_wp_installer_table_compact .installer-status-success,
140
- .otgs_wp_installer_table_compact .installer-status-fail{
141
- display: none;
142
- }
143
-
144
- .installer-status-success{
145
- float: right;
146
- color: #006600;
147
- }
148
-
149
- .otgs_wp_installer_table_compact .installer-status-downloading{background: url(../img/dn.gif) no-repeat center; }
150
- .otgs_wp_installer_table_compact .installer-status-downloaded{background: url(../img/complete.png) no-repeat center;}
151
- .otgs_wp_installer_table_compact .installer-status-activating{background: url(../img/dn.gif) no-repeat center; }
152
- .otgs_wp_installer_table_compact .installer-status-activated{background: url(../img/complete.png) no-repeat center; }
153
- .otgs_wp_installer_table_compact .installer-status-error{background: url(../img/icon_error.gif) no-repeat center; }
154
-
155
- .installer_highlight{
156
- color:#c5510b;
157
- }
158
-
159
- .installer_highlight_package{
160
- background-color: #fff9c0;
161
- }
162
-
163
- .plugin_progress{
164
- font-style: italic;
165
- color: #777
166
- }
167
-
168
- .installer-download-progress-status{
169
- display: none;
170
- float:right;
171
- color: #006600;
172
- font-style: italic;
173
- background: url('../img/spinner.gif') no-repeat;
174
- padding-left:24px;
175
- }
176
-
177
- .otgs-is-dismissible {
178
- position: relative;
179
- padding-right: 38px;
180
- }
181
- .otgs-is-dismissible .notice-dismiss {
182
- text-decoration: none;
183
- }
184
- .otgs-is-dismissible p [class*="button-"] {
185
- margin: -5px 5px;
186
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/res/img/complete.png DELETED
Binary file
embedded/installer/res/img/computer.png DELETED
Binary file
embedded/installer/res/img/dn.gif DELETED
Binary file
embedded/installer/res/img/dn2.gif DELETED
Binary file
embedded/installer/res/img/globe.png DELETED
Binary file
embedded/installer/res/img/icon_error.gif DELETED
Binary file
embedded/installer/res/img/on.png DELETED
Binary file
embedded/installer/res/img/spinner.gif DELETED
Binary file
embedded/installer/res/js/admin.js DELETED
@@ -1,403 +0,0 @@
1
- var otgs_wp_installer = {
2
-
3
- init: function(){
4
-
5
- jQuery('.otgs_wp_installer_table').on('click', '.enter_site_key_js', otgs_wp_installer.show_site_key_form);
6
- jQuery('.otgs_wp_installer_table').on('click', '.cancel_site_key_js', otgs_wp_installer.hide_site_key_form);
7
-
8
- jQuery('.otgs_wp_installer_table').on('click', '.remove_site_key_js', otgs_wp_installer.remove_site_key);
9
- jQuery('.otgs_wp_installer_table').on('click', '.update_site_key_js', otgs_wp_installer.update_site_key);
10
-
11
- jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_site_key_form', otgs_wp_installer.save_site_key);
12
- jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_downloads_form', otgs_wp_installer.download_downloads);
13
- jQuery('.otgs_wp_installer_table').on('change', '.otgsi_downloads_form :checkbox[name="downloads[]"]', otgs_wp_installer.update_downloads_form);
14
-
15
- jQuery('.installer-dismiss-nag').click(otgs_wp_installer.dismiss_nag);
16
-
17
- jQuery('.otgs_wp_installer_table').on('click', '.installer_expand_button', otgs_wp_installer.toggle_subpackages);
18
-
19
- otgs_wp_installer.scroll_to_repository();
20
-
21
- if( typeof pagenow != 'undefined' && pagenow == 'plugins'){
22
-
23
- jQuery(document).ajaxSuccess(function(event, xhr, settings) {
24
- var data = otgs_wp_installer.getQueryParameters(settings.data);
25
- if(typeof data.action != 'undefined' && data.action == 'update-plugin'){
26
- response = xhr.responseJSON.data;
27
- console.log(typeof response.error);
28
- if(typeof response.error != 'undefined'){
29
- var default_error = jQuery('#' + response.slug + '-update .update-message').html();
30
- jQuery('#' + response.slug + '-update .update-message').html(default_error + ' &raquo;<span class="installer-red-text"> ' + response.error + '</span>');
31
- }
32
- }
33
- return false;
34
- });
35
-
36
- }
37
-
38
- },
39
-
40
- getQueryParameters : function(str) {
41
- return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
42
- },
43
-
44
- reset_errors: function(){
45
- jQuery('.installer-error-box').html('').hide();
46
- },
47
-
48
- show_error: function(repo, text){
49
- jQuery('#installer_repo_' + repo).find('.installer-error-box').html(text).show();
50
- },
51
-
52
- show_site_key_form: function(){
53
- otgs_wp_installer.reset_errors();
54
-
55
- var form = jQuery(this).parent().find('form.otgsi_site_key_form');
56
- jQuery(this).prev().hide();
57
- jQuery(this).hide();
58
- form.css('display', 'inline');
59
- form.find('input[name^=site_key_]').focus().val('');
60
- form.find('input').removeAttr('disabled');
61
-
62
- form.closest('.otgsi_register_product_wrap').addClass('otgsi_yellow_bg');
63
-
64
- return false;
65
- },
66
-
67
- hide_site_key_form: function(){
68
- var form = jQuery(this).closest('form');
69
- form.hide();
70
- form.parent().find('.enter_site_key_js').show();
71
- form.parent().find('.enter_site_key_js').prev().show();
72
-
73
- form.closest('.otgsi_register_product_wrap').removeClass('otgsi_yellow_bg');
74
- otgs_wp_installer.reset_errors();
75
- return false;
76
- },
77
-
78
- save_site_key: function(){
79
-
80
- var thisf = jQuery(this);
81
- var data = jQuery(this).serialize();
82
- jQuery(this).find('input').attr('disabled', 'disabled');
83
-
84
- var spinner = jQuery('<span class="spinner"></span>');
85
- spinner.css({display: 'inline-block', float: 'none'}).prependTo(jQuery(this));
86
-
87
- otgs_wp_installer.reset_errors();
88
-
89
- jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
90
- function(ret){
91
- if(!ret.error){
92
- otgs_wp_installer.saved_site_key();
93
- }else{
94
- otgs_wp_installer.show_error(thisf.find('[name=repository_id]').val(), ret.error);
95
- thisf.find('input').removeAttr('disabled');
96
- }
97
-
98
- if(typeof ret.debug != 'undefined'){
99
- thisf.append('<textarea style="width:100%" rows="20">' + ret.debug + '</textarea>');
100
- }
101
-
102
- spinner.remove();
103
- }
104
- });
105
-
106
- return false;
107
-
108
- },
109
-
110
- saved_site_key: function(){
111
- location.reload();
112
- },
113
-
114
- remove_site_key: function(){
115
-
116
- if(confirm(jQuery(this).data('confirmation'))){
117
-
118
- jQuery('<span class="spinner"></span>').css({visibility: 'visible', float: 'none'}).prependTo(jQuery(this).parent());
119
- data = {action: 'remove_site_key', repository_id: jQuery(this).data('repository'), nonce: jQuery(this).data('nonce')}
120
- jQuery.ajax({url: ajaxurl, type: 'POST', data: data, success: otgs_wp_installer.removed_site_key});
121
- }
122
-
123
- return false;
124
- },
125
-
126
- removed_site_key: function(){
127
- location.reload();
128
- },
129
-
130
- update_site_key: function(){
131
- var error_wrap = jQuery(this).closest('.otgsi_register_product_wrap').find('.installer-error-box');
132
- error_wrap.html('');
133
-
134
- var spinner = jQuery('<span class="spinner"></span>');
135
-
136
- spinner.css({visibility: 'visible', float: 'none'}).prependTo(jQuery(this).parent());
137
- data = {action: 'update_site_key', repository_id: jQuery(this).data('repository'), nonce: jQuery(this).data('nonce')}
138
- jQuery.ajax({
139
- url: ajaxurl,
140
- type: 'POST',
141
- data: data,
142
- dataType: 'json',
143
- complete: function( event, xhr, settings ){
144
- var error = '';
145
- if(xhr == 'success') {
146
- var ret = event.responseJSON;
147
- if(ret.error){
148
- error = ret.error;
149
- }else{
150
- otgs_wp_installer.updated_site_key(ret);
151
- }
152
- }else{
153
- error = 'Error processing request (' + xhr + '). Please try again!';
154
- }
155
-
156
- if( error ){
157
- error_wrap.html('<p>' + error + '</p>').show();
158
- spinner.remove();
159
- }
160
-
161
- }
162
- });
163
-
164
- return false;
165
-
166
- },
167
-
168
- updated_site_key: function(ret){
169
- location.reload();
170
- },
171
-
172
- update_downloads_form: function(){
173
-
174
- var checked = jQuery('.otgsi_downloads_form :checkbox:checked[name="downloads[]"]').length;
175
-
176
- if(checked){
177
- jQuery(this).closest('form').find(':submit, :checkbox[name=activate]').removeAttr('disabled');
178
- }else{
179
- jQuery(this).closest('form').find(':submit, :checkbox[name=activate]').attr('disabled', 'disabled');
180
- }
181
-
182
-
183
- },
184
-
185
- download_downloads: function(){
186
-
187
- var activate = jQuery(this).find(":checkbox:checked[name=activate]").val(),
188
- action_button = jQuery(this).find('input[type="submit"]');
189
- downloads_form = jQuery(this),
190
- idx = 0,
191
- checkboxes = [];
192
-
193
- jQuery(this).find(':checkbox:checked[name="downloads[]"]').each(function(){
194
- if(jQuery(this).attr('disabled')) return;
195
- checkboxes[idx] = jQuery(this);
196
- idx++;
197
- jQuery(this).attr('disabled', 'disabled');
198
- });
199
-
200
- idx = 0;
201
-
202
- if( typeof checkboxes[idx] != 'undefined' ){
203
- download_and_activate( checkboxes[idx] );
204
- action_button.attr('disabled', 'disabled');
205
- }
206
-
207
- function download_and_activate( elem ){
208
-
209
- var this_tr = elem.closest('tr');
210
- var is_update = this_tr.find('.installer-red-text').length;
211
- if(is_update){
212
- var installing = this_tr.find('.installer-status-updating');
213
- var installed = this_tr.find('.installer-status-updated');
214
- }else{
215
- var installing = this_tr.find('.installer-status-installing');
216
- var installed = this_tr.find('.installer-status-installed');
217
-
218
- }
219
- if(activate){
220
- var activating = this_tr.find('.installer-status-activating');
221
- var activated = this_tr.find('.installer-status-activated');
222
- }
223
-
224
- if( this_tr.find('.for_spinner_js .spinner').length > 0 ){
225
- var spinner = this_tr.find('.for_spinner_js .spinner');
226
- }else{
227
- var spinner = this_tr.find('.installer-status-downloading');
228
- }
229
-
230
- otgs_wp_installer.reset_errors();
231
- downloads_form.find('div.installer-status-success').hide();
232
- spinner.css('visibility', 'visible');
233
- installing.show();
234
-
235
- var plugin_name = this_tr.find('.installer_plugin_name').html();
236
- if(is_update){
237
- otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.updating.replace('%s', plugin_name));
238
- }else{
239
- otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.installing.replace('%s', plugin_name));
240
- }
241
-
242
-
243
- data = {action: 'installer_download_plugin', data: elem.val(), activate: activate}
244
-
245
- jQuery.ajax({
246
- url: ajaxurl,
247
- type: 'POST',
248
- dataType: 'json',
249
- data: data,
250
- success: function(ret){
251
- installing.hide();
252
-
253
- if(!ret.success){
254
- installed.addClass('installer-status-error');
255
- installed.html(installed.data('fail'));
256
-
257
- if(ret.message){
258
- installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + ret.message + '</p>').show();
259
- }else{
260
- installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + downloads_form.find('.installer-revalidate-message').html() + '</p>').show();
261
- }
262
-
263
-
264
- }
265
-
266
- installed.show();
267
- spinner.fadeOut();
268
-
269
- if(ret.version){
270
- this_tr.find('.installer_version_installed').html('<span class="installer-green-text">' + ret.version + '</span>');
271
- }
272
-
273
- if(ret.success && activate){
274
-
275
- otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.activating.replace('%s', plugin_name));
276
- activating.show();
277
- spinner.show();
278
- this_tr.find('.installer-red-text').removeClass('installer-red-text').addClass('installer-green-text').html(ret.version);
279
-
280
- jQuery.ajax({
281
- url: ajaxurl,
282
- type: 'POST',
283
- dataType: 'json',
284
- data: {action: 'installer_activate_plugin', plugin_id: ret.plugin_id, nonce: ret.nonce},
285
- success: function(ret){
286
- activating.hide();
287
- if(!ret.error ){
288
- activated.show();
289
- }
290
-
291
- spinner.fadeOut();
292
-
293
- idx++;
294
- if( typeof checkboxes[idx] != 'undefined' ){
295
- download_and_activate( checkboxes[idx] );
296
- }else{
297
- otgs_wp_installer.hide_download_progress_status(downloads_form);
298
- downloads_form.find('div.installer-status-success').show();
299
- action_button.removeAttr('disabled');
300
- }
301
- }
302
- });
303
- }else{
304
- idx++;
305
- if( typeof checkboxes[idx] != 'undefined' ){
306
- download_and_activate( checkboxes[idx] );
307
- }else{
308
- otgs_wp_installer.hide_download_progress_status(downloads_form);
309
- downloads_form.find('div.installer-status-success').show();
310
- action_button.removeAttr('disabled');
311
- }
312
- }
313
- }
314
-
315
- });
316
-
317
- };
318
-
319
- return false;
320
- },
321
-
322
-
323
- show_download_progress_status: function(downloads_form, text){
324
-
325
- downloads_form.find('.installer-download-progress-status').html(text).fadeIn();
326
-
327
- },
328
-
329
- hide_download_progress_status: function(downloads_form){
330
-
331
- downloads_form.find('.installer-download-progress-status').html('').fadeOut();
332
-
333
- },
334
-
335
- dismiss_nag: function(){
336
-
337
- var thisa = jQuery(this);
338
-
339
- data = {action: 'installer_dismiss_nag', repository: jQuery(this).data('repository')}
340
-
341
- jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
342
- function(ret){
343
- thisa.closest('.otgs-is-dismissible').remove();
344
- }
345
- });
346
-
347
- return false;
348
- },
349
-
350
- toggle_subpackages: function(){
351
- var list = jQuery(this).closest('td').find('.otgs_wp_installer_subtable');
352
-
353
- if(list.is(':visible')){
354
- list.slideUp('fast');
355
- }else{
356
- list.slideDown('fast');
357
- }
358
-
359
-
360
- return false;
361
-
362
- },
363
-
364
- scroll_to_repository: function(){
365
-
366
- var ref = window.location.hash.replace('#', '');
367
-
368
- if(ref) {
369
- var split = ref.split('/');
370
- var repo = split[0];
371
-
372
- if(typeof split[1] != 'undefined'){
373
- var package = split[1];
374
- var repo_element = jQuery('#repository-' + repo);
375
-
376
-
377
-
378
- if(repo_element.length){
379
-
380
- jQuery('html, body').animate({
381
- scrollTop: repo_element.offset().top
382
- }, 1000);
383
-
384
- var package_element = jQuery('#repository-' + repo +'_' + package);
385
-
386
- if(package_element.length && !package_element.is(':visible')){
387
- package_element.parents('.otgs_wp_installer_subtable').slideDown();
388
- package_element.addClass('installer_highlight_package');
389
- }
390
-
391
- package_element.find('.button-secondary').removeClass('button-secondary').addClass('button-primary');
392
- }
393
- }
394
-
395
- }
396
-
397
- }
398
-
399
-
400
- }
401
-
402
-
403
- jQuery(document).ready(otgs_wp_installer.init);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/res/js/iframeResizer.min.js DELETED
@@ -1,10 +0,0 @@
1
- /*! iFrame Resizer (iframeSizer.min.js ) - v2.6.1 - 2014-09-03
2
- * Desc: Force cross domain iframes to size to content.
3
- * Requires: iframeResizer.contentWindow.min.js to be loaded into the target frame.
4
- * Copyright: (c) 2014 David J. Bradshaw - dave@bradshaw.net
5
- * License: MIT
6
- */
7
-
8
- !function(){"use strict";function a(a,b,c){"addEventListener"in window?a.addEventListener(b,c,!1):"attachEvent"in window&&a.attachEvent("on"+b,c)}function b(){var a,b=["moz","webkit","o","ms"];for(a=0;a<b.length&&!w;a+=1)w=window[b[a]+"RequestAnimationFrame"];w||c(" RequestAnimationFrame not supported")}function c(a){y.log&&"object"==typeof console&&console.log(s+"[Host page"+u+"]"+a)}function d(a){function b(){function a(){h(z),f(),y.resizedCallback(z)}i(a,z,"resetPage")}function d(a){var b=a.id;c(" Removing iFrame: "+b),a.parentNode.removeChild(a),y.closedCallback(b),c(" --")}function e(){var a=x.substr(t).split(":");return{iframe:document.getElementById(a[0]),id:a[0],height:a[1],width:a[2],type:a[3]}}function j(a){var b=Number(y["max"+a]),d=Number(y["min"+a]),e=a.toLowerCase(),f=Number(z[e]);if(d>b)throw new Error("Value for min"+a+" can not be greater than max"+a);c(" Checking "+e+" is in range "+d+"-"+b),d>f&&(f=d,c(" Set "+e+" to min value")),f>b&&(f=b,c(" Set "+e+" to max value")),z[e]=""+f}function k(){var b=a.origin,d=z.iframe.src.split("/").slice(0,3).join("/");if(y.checkOrigin&&(c(" Checking connection is from: "+d),""+b!="null"&&b!==d))throw new Error("Unexpected message received from: "+b+" for "+z.iframe.id+". Message was: "+a.data+". This error can be disabled by adding the checkOrigin: false option.");return!0}function l(){return s===(""+x).substr(0,t)}function m(){var a=z.type in{"true":1,"false":1};return a&&c(" Ignoring init message from meta parent page"),a}function n(){var a=x.substr(x.indexOf(":")+r+6);c(" MessageCallback passed: {iframe: "+z.iframe.id+", message: "+a+"}"),y.messageCallback({iframe:z.iframe,message:a}),c(" --")}function o(){if(null===z.iframe)throw new Error("iFrame ("+z.id+") does not exist on "+u);return!0}function q(){c(" Reposition requested from iFrame"),v={x:z.width,y:z.height},f()}function w(){switch(z.type){case"close":d(z.iframe),y.resizedCallback(z);break;case"message":n();break;case"scrollTo":q();break;case"reset":g(z);break;case"init":b(),y.initCallback(z.iframe);break;default:b()}}var x=a.data,z={};l()&&(c(" Received: "+x),z=e(),j("Height"),j("Width"),!m()&&o()&&k()&&(w(),p=!1))}function e(){null===v&&(v={x:void 0!==window.pageXOffset?window.pageXOffset:document.documentElement.scrollLeft,y:void 0!==window.pageYOffset?window.pageYOffset:document.documentElement.scrollTop},c(" Get position: "+v.x+","+v.y))}function f(){null!==v&&(window.scrollTo(v.x,v.y),c(" Set position: "+v.x+","+v.y),v=null)}function g(a){function b(){h(a),j("reset","reset",a.iframe)}c(" Size reset requested by "+("init"===a.type?"host page":"iFrame")),e(),i(b,a,"init")}function h(a){function b(b){a.iframe.style[b]=a[b]+"px",c(" IFrame ("+a.iframe.id+") "+b+" set to "+a[b]+"px")}y.sizeHeight&&b("height"),y.sizeWidth&&b("width")}function i(a,b,d){d!==b.type&&w?(c(" Requesting animation frame"),w(a)):a()}function j(a,b,d){c("["+a+"] Sending msg to iframe ("+b+")"),d.contentWindow.postMessage(s+b,"*")}function k(){function b(){function a(a){1/0!==y[a]&&0!==y[a]&&(k.style[a]=y[a]+"px",c(" Set "+a+" = "+y[a]+"px"))}a("maxHeight"),a("minHeight"),a("maxWidth"),a("minWidth")}function d(a){return""===a&&(k.id=a="iFrameResizer"+o++,c(" Added missing iframe ID: "+a+" ("+k.src+")")),a}function e(){c(" IFrame scrolling "+(y.scrolling?"enabled":"disabled")+" for "+l),k.style.overflow=!1===y.scrolling?"hidden":"auto",k.scrolling=!1===y.scrolling?"no":"yes"}function f(){("number"==typeof y.bodyMargin||"0"===y.bodyMargin)&&(y.bodyMarginV1=y.bodyMargin,y.bodyMargin=""+y.bodyMargin+"px")}function h(){return l+":"+y.bodyMarginV1+":"+y.sizeWidth+":"+y.log+":"+y.interval+":"+y.enablePublicMethods+":"+y.autoResize+":"+y.bodyMargin+":"+y.heightCalculationMethod+":"+y.bodyBackground+":"+y.bodyPadding+":"+y.tolerance}function i(b){a(k,"load",function(){var a=p;j("iFrame.onload",b,k),!a&&y.heightCalculationMethod in x&&g({iframe:k,height:0,width:0,type:"init"})}),j("init",b,k)}var k=this,l=d(k.id);e(),b(),f(),i(h())}function l(a){if("object"!=typeof a)throw new TypeError("Options is not an object.")}function m(){function a(a){if("IFRAME"!==a.tagName.toUpperCase())throw new TypeError("Expected <IFRAME> tag, found <"+a.tagName+">.");k.call(a)}function b(a){a=a||{},l(a);for(var b in z)z.hasOwnProperty(b)&&(y[b]=a.hasOwnProperty(b)?a[b]:z[b])}return function(c,d){b(c),Array.prototype.forEach.call(document.querySelectorAll(d||"iframe"),a)}}function n(a){a.fn.iFrameResize=function(b){return b=b||{},l(b),y=a.extend({},z,b),this.filter("iframe").each(k).end()}}var o=0,p=!0,q="message",r=q.length,s="[iFrameSizer]",t=s.length,u="",v=null,w=window.requestAnimationFrame,x={max:1,scroll:1,bodyScroll:1,documentElementScroll:1},y={},z={autoResize:!0,bodyBackground:null,bodyMargin:null,bodyMarginV1:8,bodyPadding:null,checkOrigin:!0,enablePublicMethods:!1,heightCalculationMethod:"offset",interval:32,log:!1,maxHeight:1/0,maxWidth:1/0,minHeight:0,minWidth:0,scrolling:!1,sizeHeight:!0,sizeWidth:!1,tolerance:0,closedCallback:function(){},initCallback:function(){},messageCallback:function(){},resizedCallback:function(){}};b(),a(window,"message",d),"jQuery"in window&&n(jQuery),"function"==typeof define&&define.amd?define(function(){return m()}):window.iFrameResize=m()}();
9
- //# sourceMappingURL=../src/iframeResizer.map
10
-
 
 
 
 
 
 
 
 
 
 
embedded/installer/res/js/installer_theme_install.js DELETED
@@ -1,97 +0,0 @@
1
- jQuery( document ).ready( function( $ ) {
2
-
3
- /** Append OTGS Theme tab */
4
- var js_array= installer_theme_install_localize.js_array_installer;
5
-
6
- if (!($.isEmptyObject(js_array))) {
7
- //Unempty
8
- for(var key in js_array) {
9
- //Dont append if we are on commercial plugins tab page and if there are no themes
10
- if ((!(js_array[key]['is_commercial_plugin_tab'])) && (!(installer_theme_install_localize.no_associated_themes))) {
11
- $('div.wp-filter ul.filter-links').append('<li><a data-sort="'+key+'" href="#">'+ js_array[key]['the_hyperlink_text'] +'</a></li>');
12
- }
13
- }
14
- }
15
-
16
- /** Page load event tab selected identifier */
17
- var loaded_browsing_tab=installer_theme_extended_object.getParameterByName('browse');
18
- if (loaded_browsing_tab.length > 0) {
19
-
20
- var frontend_tab_selected_tab = loaded_browsing_tab;
21
-
22
- } else if (0 == loaded_browsing_tab.length){
23
-
24
- //WordPress defaults to 'Featured' when theme install is loaded without the browse parameter
25
- var frontend_tab_selected_tab = 'featured';
26
- }
27
-
28
- /** Prepare data on page load event for AJAX */
29
- var data = {
30
- action: 'installer_theme_frontend_selected_tab',
31
- installer_theme_frontend_selected_tab_nonce: installer_theme_install_localize.installer_theme_frontend_selected_tab_nonce,
32
- frontend_tab_selected :frontend_tab_selected_tab
33
- };
34
-
35
- //Call AJAX
36
- installer_theme_extended_object.doAJAX(data,frontend_tab_selected_tab,js_array);
37
-
38
- /** When user clicks on any tab */
39
- $(document).on('click','.filter-links li > a',function () {
40
-
41
- //Get data_sort
42
- var data_sort =$(this).attr('data-sort');
43
-
44
- if (data_sort) {
45
- //data_sort is set, prepare data
46
- var data = {
47
- action: 'installer_theme_frontend_selected_tab',
48
- installer_theme_frontend_selected_tab_nonce: installer_theme_install_localize.installer_theme_frontend_selected_tab_nonce,
49
- frontend_tab_selected : data_sort
50
- };
51
-
52
- //Call AJAX
53
- installer_theme_extended_object.doAJAX(data,data_sort,js_array);
54
-
55
- }
56
- });
57
-
58
- var fullhash = window.location.hash;
59
- if (fullhash.length > 0) {
60
- var product_selector=fullhash+' '+'.enter_site_key_js';
61
- if ($(product_selector).length ) {
62
- $(product_selector).click();
63
- }
64
- }
65
- });
66
-
67
- //Installer theme extended JS object for methods
68
- var installer_theme_extended_object = {
69
-
70
- getParameterByName: function(name) {
71
- name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
72
- var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
73
- results = regex.exec(location.search);
74
- return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
75
- },
76
-
77
- doAJAX: function(data,data_sort,js_array) {
78
-
79
- //We only want to post to AJAX if its an OTGS tab
80
- jQuery.post(installer_theme_install_localize.ajaxurl, data, function(response) {
81
- //AJAX response
82
- var myObject = jQuery.parseJSON(response);
83
- if (typeof myObject != "undefined") {
84
- if(myObject.hasOwnProperty("output")){
85
- var tab_selected= myObject.output;
86
- if (data_sort in js_array) {
87
- if (!(installer_theme_install_localize.js_array_installer[tab_selected]['registration_status'])) {
88
- //Not registered, no theme response
89
- var unregistered_message= myObject.unregistered_messages;
90
- jQuery('.no-themes').html(unregistered_message);
91
- }
92
- }
93
- }
94
- }
95
- });
96
- }
97
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/templates/downloads-list-compact.php DELETED
@@ -1,80 +0,0 @@
1
-
2
- <form method="post" class="otgsi_downloads_form">
3
-
4
- <table class="installer-plugins-list-compact">
5
- <thead>
6
- <tr>
7
- <th>&nbsp;</th>
8
- <th><?php _e('Plugin', 'installer') ?></th>
9
- <th><img src="<?php echo $this->plugin_url() ?>/res/img/globe.png" alt="<?php esc_attr_e('Available', 'installer') ?>" width="16" height="16"></th>
10
- <th><img src="<?php echo $this->plugin_url() ?>/res/img/computer.png" alt="<?php esc_attr_e('Installed', 'installer') ?>" width="16" height="16"></th>
11
- <th><img src="<?php echo $this->plugin_url() ?>/res/img/dn2.gif" alt="<?php esc_attr_e('Downloading', 'installer') ?>" width="16" height="16"></th>
12
- <th><img src="<?php echo $this->plugin_url() ?>/res/img/on.png" alt="<?php esc_attr_e('Activate', 'installer') ?>" width="16" height="16"></th>
13
- </tr>
14
- </thead>
15
- <tbody>
16
- <?php foreach($product['downloads'] as $download): ?>
17
- <?php if(empty($tr_oddeven) || $tr_oddeven == 'even') $tr_oddeven = 'odd'; else $tr_oddeven = 'even'; ?>
18
- <tr class="<?php echo $tr_oddeven ?>">
19
- <td>
20
- <label>
21
- <?php
22
- $url = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id );
23
-
24
- $download_data = array(
25
- 'url' => $url,
26
- 'slug' => $download['slug'],
27
- 'nonce' => wp_create_nonce('install_plugin_' . $url),
28
- 'repository_id' => $repository_id
29
- );
30
-
31
- $disabled = $expired ||
32
- (
33
- $this->plugin_is_installed($download['name'], $download['slug'], $download['version']) &&
34
- !$this->plugin_is_embedded_version($download['name'], $download['slug'])
35
- ) || WP_Installer()->dependencies->cant_download( $repository_id );
36
-
37
- ?>
38
- <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" <?php
39
- if($disabled): ?>disabled="disabled"<?php endif; ?> />&nbsp;
40
-
41
- </label>
42
- </td>
43
- <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
44
- <td><?php echo $download['version'] ?></td>
45
- <td class="installer_version_installed">
46
- <?php if($v = $this->plugin_is_installed($download['name'], $download['slug'])):
47
- $class = version_compare($v, $download['version'], '>=') ? 'installer-green-text' : 'installer-red-text'; ?>
48
- <span class="<?php echo $class ?>"><?php echo $v; ?></span>
49
- <?php endif; ?>
50
- </td>
51
- <td class="twelve">
52
- <div class="installer-status-downloading"><?php _e('downloading...', 'installer') ?></div>
53
- <div class="installer-status-downloaded" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('downloaded', 'installer') ?></div>
54
- </td>
55
- <td class="twelve">
56
- <div class="installer-status-activating"><?php _e('activating', 'installer') ?></div>
57
- <div class="installer-status-activated"><?php _e('activated', 'installer') ?></div>
58
- </td>
59
- </tr>
60
- <?php endforeach; ?>
61
- </tbody>
62
- </table>
63
-
64
- <?php if( !WP_Installer()->dependencies->is_uploading_allowed() ): ?>
65
- <p class="installer-error-box"><?php printf(__('Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s.', 'installer'),
66
- '<a href="http://codex.wordpress.org/Changing_File_Permissions">', '</a>') ?></p>
67
- <?php elseif( WP_Installer()->dependencies->is_win_paths_exception($repository_id) ): ?>
68
- <p><?php echo WP_Installer()->dependencies->win_paths_exception_message() ?></p>
69
- <?php endif;?>
70
-
71
- <br />
72
- <input type="submit" class="button-secondary" value="<?php esc_attr_e('Download', 'installer') ?>" disabled="disabled" />
73
- &nbsp;
74
- <label><input name="activate" type="checkbox" value="1" disabled="disabled" />&nbsp;<?php _e('Activate after download', 'installer') ?></label>
75
-
76
- <div class="installer-download-progress-status"></div>
77
- <div class="installer-status-success"><?php _e('Operation complete!', 'installer') ?></div>
78
-
79
- <span class="installer-revalidate-message hidden"><?php _e("Download failed!\n\nClick OK to revalidate your subscription or CANCEL to try again.", 'installer') ?></span>
80
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/templates/downloads-list.php DELETED
@@ -1,85 +0,0 @@
1
- <br clear="all" /><br />
2
- <strong><?php _e('Downloads:', 'installer') ?></strong>
3
-
4
- <form method="post" class="otgsi_downloads_form">
5
-
6
- <table class="widefat">
7
- <thead>
8
- <tr>
9
- <th>&nbsp;</th>
10
- <th><?php _e('Plugin', 'installer') ?></th>
11
- <th><?php _e('Current version', 'installer') ?></th>
12
- <th><?php _e('Released', 'installer') ?></th>
13
- <th><?php _e('Installed version', 'installer') ?></th>
14
- <th>&nbsp;</th>
15
- <th>&nbsp;</th>
16
- <th>&nbsp;</th>
17
- </tr>
18
- </thead>
19
- <tbody>
20
- <?php
21
- foreach($package['downloads'] as $download): ?>
22
- <tr>
23
- <td>
24
- <label>
25
- <?php
26
- $url = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
27
-
28
- $download_data = array(
29
- 'url' => $url,
30
- 'slug' => $download['slug'],
31
- 'nonce' => wp_create_nonce('install_plugin_' . $url),
32
- 'repository_id' => $repository_id
33
- );
34
- ?>
35
- <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" <?php
36
- if($this->plugin_is_installed($download['name'], $download['slug'], $download['version']) && !$this->plugin_is_embedded_version($download['name'], $download['slug']) || WP_Installer()->dependencies->cant_download($repository_id) ): ?>disabled="disabled"<?php endif; ?> />&nbsp;
37
-
38
- </label>
39
- </td>
40
- <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
41
- <td><?php echo $download['version'] ?></td>
42
- <td><?php echo date_i18n('F j, Y', strtotime($download['date'])) ?></td>
43
- <td class="installer_version_installed">
44
- <?php if($v = $this->plugin_is_installed($download['name'], $download['slug'])): $class = version_compare($v, $download['version'], '>=') ? 'installer-green-text' : 'installer-red-text'; ?>
45
- <span class="<?php echo $class ?>"><?php echo $v; ?></span>
46
- <?php if($this->plugin_is_embedded_version($download['name'], $download['slug'])): ?>&nbsp;<?php _e('(embedded)', 'installer'); ?><?php endif; ?>
47
- <?php endif; ?>
48
- </td>
49
- <td>
50
- <span class="installer-status-installing"><?php _e('installing...', 'installer') ?></span>
51
- <span class="installer-status-updating"><?php _e('updating...', 'installer') ?></span>
52
- <span class="installer-status-installed" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('installed', 'installer') ?></span>
53
- <span class="installer-status-updated" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('updated', 'installer') ?></span>
54
- </td>
55
- <td>
56
- <span class="installer-status-activating"><?php _e('activating', 'installer') ?></span>
57
- <span class="installer-status-activated"><?php _e('activated', 'installer') ?></span>
58
- </td>
59
- <td class="for_spinner_js"><span class="spinner"></span></td>
60
- </tr>
61
- <?php endforeach; ?>
62
- </tbody>
63
- </table>
64
-
65
- <br />
66
-
67
- <div class="installer-error-box">
68
- <?php if( !WP_Installer()->dependencies->is_uploading_allowed() ): ?>
69
- <p><?php printf(__('Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s.', 'installer'),
70
- '<a href="http://codex.wordpress.org/Changing_File_Permissions">', '</a>') ?></p>
71
- <?php elseif( WP_Installer()->dependencies->is_win_paths_exception($repository_id) ): ?>
72
- <p><?php echo WP_Installer()->dependencies->win_paths_exception_message() ?></p>
73
- <?php endif; ?>
74
- </div>
75
-
76
- <input type="submit" class="button-secondary" value="<?php esc_attr_e('Download', 'installer') ?>" disabled="disabled" />
77
- &nbsp;
78
- <label><input name="activate" type="checkbox" value="1" disabled="disabled" />&nbsp;<?php _e('Activate after download', 'installer') ?></label>
79
-
80
- <div class="installer-download-progress-status"></div>
81
-
82
- <div class="installer-status-success"><?php _e('Operation complete!', 'installer') ?></div>
83
-
84
- <span class="installer-revalidate-message hidden"><?php _e("Download failed!\n\nPlease refresh the page and try again.", 'installer') ?></span>
85
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/templates/products-compact.php DELETED
@@ -1,129 +0,0 @@
1
- <h3><?php echo $args['box_title'] ?></h3>
2
-
3
- <?php
4
- if(empty($args['repository']) || empty($args['package']) || empty($args['product'])){
5
- echo __('Incorrect setup', 'installer');
6
- return;
7
- }
8
-
9
- $product = false;
10
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package_idx => $package){
11
-
12
- //pre 1.3 backwardds compatibility
13
- if(!isset($package['id'])){
14
- $package['id'] = sanitize_title_with_dashes($package['name']);
15
- }
16
-
17
- if($package['id'] == $args['package']){
18
- $product = $this->settings['repositories'][$repository_id]['data']['packages'][$package_idx]['products'][$args['product']];
19
- break;
20
- }
21
- }
22
-
23
-
24
- if(!$product){
25
- echo __('Invalid product', 'installer');
26
- return;
27
- }
28
-
29
- if(isset($this->settings['repositories'][$repository_id])){
30
- if(isset($this->settings['repositories'][$repository_id]['subscription']['key'])){
31
- $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
32
- }else{
33
- $site_key = false;
34
- }
35
- }else{
36
- echo __('Unknown repository', 'installer');
37
- return;
38
- }
39
-
40
- $subscription_type = $this->get_subscription_type_for_repository($repository_id);
41
- $expired = false;
42
-
43
- if($subscription_type != $product['subscription_type'] && !$this->have_superior_subscription($subscription_type, $product) && $site_key){
44
- $subscription_no_match = sprintf(__(' Your current site key (%s) does not match the selected product (%s).', 'installer'), $site_key, $product['name']);
45
- }
46
-
47
- if(!isset($args['product_name'])) $args['product_name'] = $product['name'];
48
-
49
- ?>
50
-
51
- <div class="otgs_wp_installer_table otgs_wp_installer_table_compact">
52
-
53
- <p><?php echo $args['box_description'] ?></p>
54
-
55
-
56
- <?php if(!$this->repository_has_subscription($repository_id) || !empty($subscription_no_match)): ?>
57
-
58
- <?php if(!empty($subscription_no_match)): ?>
59
- <div class="installer-warn-box">
60
- <?php echo $subscription_no_match; ?>
61
- </div>
62
- <br />
63
- <?php endif; ?>
64
-
65
- <a class="button-primary" href="<?php echo $this->append_parameters_to_buy_url($product['url'], $repository_id, $args) ?>"><?php printf(__('Buy %s', 'installer'), $args['product_name']) ?></a>
66
-
67
- <div>
68
- <br />
69
- <?php printf(__('Already bought %s?', 'installer'), $args['product_name']) ?>
70
- <a class="enter_site_key_js" href="#"><?php _e('Enter site key', 'installer') ?></a>&nbsp;&nbsp;
71
-
72
- <form class="otgsi_site_key_form" method="post">
73
- <input type="hidden" name="action" value="save_site_key" />
74
- <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('save_site_key_' . $repository_id) ?>" />
75
- <input type="hidden" name="repository_id" value="<?php echo $repository_id ?>">
76
- <input type="text" size="10" name="site_key_<?php echo $repository_id ?>" />
77
- <input class="button-secondary" type="submit" value="<?php esc_attr_e('Add', 'installer') ?>" />
78
- </form>
79
- <div class="installer-error-box hidden" style="margin-top:10px;"></div>
80
- </div>
81
-
82
- <?php else: ?>
83
-
84
- <?php if($this->repository_has_expired_subscription($repository_id)): $expired = true; ?>
85
-
86
- <div><p class="installer-warn-box"><?php _e('Subscription is expired.', 'installer') ?></p></div>
87
-
88
- <?php else: ?>
89
-
90
- <?php if($this->show_subscription_renew_warning($repository_id, $subscription_type)): ?>
91
-
92
- <ul class="installer-products-list">
93
- <?php foreach($product['renewals'] as $renewal): ?>
94
- <li>
95
- <a href="<?php echo $this->append_parameters_to_buy_url($renewal['url'], $repository_id, $args) ?>"><?php printf(__('Renew %s', 'installer'), $args['product_name']) ?></a>
96
- </li>
97
- <?php endforeach; ?>
98
- </ul>
99
-
100
- <?php endif; ?>
101
-
102
- <?php endif; ?>
103
-
104
- <center>
105
- <a class="remove_site_key_js" href="#" data-repository=<?php echo $repository_id ?> data-confirmation="<?php esc_attr_e('Are you sure you want to remove this site key?', 'installer') ?>" data-nonce="<?php echo wp_create_nonce('remove_site_key_' . $repository_id) ?>"><?php printf(__("Remove current site key (%s)", 'installer'), $site_key) ?></a>
106
- </center>
107
- <br />
108
-
109
- <?php include $this->plugin_path() . '/templates/downloads-list-compact.php'; ?>
110
-
111
-
112
-
113
- <?php endif; ?>
114
-
115
- <?php
116
- if( isset( $args[ 'name' ] ) ):
117
- $support_link = $this->get_support_tag_by_name($args['name'], $args['repository']); ?>
118
-
119
- <?php if($support_link): ?>
120
- <p><a href="<?php echo $support_link ?>" target="_blank"><?php printf(__('%s support on wpml.org', 'installer'), $args['name'] ) ?></a></p>
121
-
122
- <?php endif; ?>
123
- <?php
124
- // compatibility for installer 1.1
125
- elseif( isset( $args[ 'support_link' ] ) ): ?>
126
- <p><?php echo $args[ 'support_link' ]; ?></p>
127
- <?php endif; ?>
128
-
129
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/installer/templates/repository-listing.php DELETED
@@ -1,179 +0,0 @@
1
- <?php if((!$this->repository_has_subscription($repository_id) && $match = $this->get_matching_cp($repository)) && $match['exp']): ?>
2
- <p class="alignright installer_highlight"><strong><?php printf('Price offers available until %s', date_i18n(get_option( 'date_format' ), $match['exp'])) ?></strong></p>
3
- <?php endif; ?>
4
-
5
- <h3 id="repository-<?php echo $repository_id ?>"><?php echo $repository['data']['name'] ?></h3>
6
- <?php
7
- $generic_product_name = $this->settings['repositories'][$repository_id]['data']['product-name'];
8
- ?>
9
- <table class="widefat otgs_wp_installer_table" id="installer_repo_<?php echo $repository_id ?>">
10
-
11
- <tr>
12
- <td>&nbsp;</td>
13
- <td class="otgsi_register_product_wrap" align="center" valign="top">
14
- <?php // IF NO SUBSCRIPTION ?>
15
- <?php if(!$this->repository_has_subscription($repository_id)): ?>
16
-
17
- <div style="text-align: right;">
18
- <span><?php _e('Already bought?', 'installer'); ?>&nbsp;</span>
19
- <a class="enter_site_key_js button-primary" href="#"><?php printf(__('Register %s', 'installer'), $generic_product_name); ?></a>&nbsp;&nbsp;
20
- <form class="otgsi_site_key_form" method="post">
21
- <input type="hidden" name="action" value="save_site_key" />
22
- <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('save_site_key_' . $repository_id) ?>" />
23
- <input type="hidden" name="repository_id" value="<?php echo $repository_id ?>">
24
- <?php _e('2. Enter your site key', 'installer'); ?>
25
- <input type="text" size="10" name="site_key_<?php echo $repository_id ?>" placeholder="<?php echo esc_attr('site key') ?>" />
26
- <input class="button-primary" type="submit" value="<?php esc_attr_e('OK', 'installer') ?>" />
27
- <input class="button-secondary cancel_site_key_js" type="button" value="<?php esc_attr_e('Cancel', 'installer') ?>" />
28
-
29
- <div class="alignleft" style="margin-top:6px;"><?php printf(__('1. Go to your %s%s account%s and add this site URL: %s', 'installer'),
30
- '<a href="' . $this->settings['repositories'][$repository_id]['data']['site_keys_management_url'] . '?add='.urlencode($this->get_installer_site_url( $repository_id )).'">',
31
- $generic_product_name, '</a>', $this->get_installer_site_url( $repository_id )); ?></div>
32
- </form>
33
-
34
-
35
- </div>
36
-
37
- <?php
38
- $site_key = false;
39
-
40
- // IF SUBSCRIPTION
41
- else:
42
-
43
- $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
44
- $subscription_type = $this->get_subscription_type_for_repository($repository_id);
45
-
46
- $upgrade_options = $this->get_upgrade_options($repository_id);
47
- $expired = false;
48
-
49
- ?>
50
-
51
- <?php if($this->repository_has_expired_subscription($repository_id)): $expired = true; ?>
52
- <div>
53
- <p class="installer-warn-box">
54
- <?php _e('Subscription expired. You need to either purchase a new subscription or upgrade if available.', 'installer') ?>
55
- <span class="alignright">
56
- <a class="update_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-nonce="<?php echo wp_create_nonce('update_site_key_' . $repository_id) ?>">
57
- <?php _e('Revalidate subscription', 'installer'); ?>
58
- </a>
59
- </span>
60
- <br />
61
- <span class="details"><?php _e("If you have already purchased or renewed your subscription and you can still see this message, please revalidate your subscription", 'installer') ?></span>
62
- </p>
63
- </div>
64
- <?php else: ?>
65
- <?php $this->show_subscription_renew_warning($repository_id, $subscription_type); ?>
66
- <?php endif; ?>
67
-
68
- <div class="alignright">
69
- <a class="remove_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-confirmation="<?php esc_attr_e('Are you sure you want to unregister?', 'installer') ?>" data-nonce="<?php echo wp_create_nonce('remove_site_key_' . $repository_id) ?>"><?php printf(__("Unregister %s from this site", 'installer'), $generic_product_name) ?></a>&nbsp;
70
- <a class="update_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-nonce="<?php echo wp_create_nonce('update_site_key_' . $repository_id) ?>">
71
- <?php _e('Check for updates', 'installer'); ?>
72
- </a>
73
- </div>
74
-
75
- <?php if(empty($expired)): ?>
76
- <div class="alignleft">
77
- <?php if($expires = $this->settings['repositories'][$repository_id]['subscription']['data']->expires): ?>
78
- <?php printf(__('%s is registered on this site. You will receive automatic updates until %s', 'installer'), $generic_product_name, date_i18n('F j, Y', strtotime($expires))); ?>
79
- <?php else: ?>
80
- <?php printf(__('%s is registered on this site. Your Lifetime account gives you updates for life.', 'installer'), $generic_product_name); ?>
81
- <?php endif; ?>
82
- </div>
83
- <?php endif; //if(empty($expired)) ?>
84
-
85
- <?php endif; // if(!repository_has_subscription) ?>
86
- <br clear="all" />
87
- <div class="installer-error-box hidden"></div>
88
-
89
- </td>
90
- </tr>
91
-
92
- <?php
93
-
94
- $subscription_type = isset($subscription_type) ? $subscription_type : null;
95
- $expired = isset($expired) ? $expired : null;
96
- $upgrade_options = isset($upgrade_options) ? $upgrade_options : null;
97
- $packages = $this->_render_product_packages($repository['data']['packages'], $subscription_type, $expired, $upgrade_options, $repository_id);
98
- if(empty($subscription_type) || $expired){
99
- $subpackages_expandable = true;
100
- }else{
101
- $subpackages_expandable = false;
102
- }
103
-
104
- ?>
105
-
106
- <?php foreach($packages as $package): ?>
107
- <tr id="repository-<?php echo $repository_id ?>_<?php echo $package['id'] ?>">
108
- <td><img width="140" height="140" src="<?php echo $package['image_url'] ?>" /></td>
109
- <td>
110
- <p><strong><?php echo $package['name'] ?></strong></p>
111
- <p><?php echo $package['description'] ?></p>
112
-
113
- <?php if($package['products']): ?>
114
- <?php foreach($package['products'] as $product): ?>
115
- <ul class="installer-products-list" style="display:inline">
116
- <li>
117
- <a class="button-secondary" href="<?php echo $product['url'] ?>"><?php echo $product['label'] ?></a>
118
- </li>
119
- </ul>
120
- <?php endforeach; ?>
121
- <?php endif; ?>
122
-
123
- <?php if($package['downloads']): ?>
124
- <?php include $this->plugin_path() . '/templates/downloads-list.php'; ?>
125
- <?php endif; ?>
126
-
127
- <?php if(!empty($package['sub-packages'])): ?>
128
-
129
- <?php $subpackages = $this->_render_product_packages($package['sub-packages'], $subscription_type, $expired, $upgrade_options, $repository_id); ?>
130
-
131
- <?php if($subpackages): ?>
132
-
133
- <?php if($subpackages_expandable): ?>
134
- <h5><a class="installer_expand_button" href="#" title="<?php esc_attr_e('Click to see individual components options.', 'installer') ?>"><?php _e('Individual components', 'installer') ?></a></h5>
135
- <?php endif; ?>
136
-
137
- <table class="otgs_wp_installer_subtable" style="<?php if($subpackages_expandable) echo 'display:none' ?>">
138
- <?php foreach($subpackages as $package): ?>
139
- <tr id="repository-<?php echo $repository_id ?>_<?php echo $package['id'] ?>">
140
- <td><img width="70" height="70" src="<?php echo $package['image_url'] ?>" /></td>
141
- <td>
142
- <p><strong><?php echo $package['name'] ?></strong></p>
143
- <p><?php echo $package['description'] ?></p>
144
-
145
- <?php if($package['products']): ?>
146
- <?php foreach($package['products'] as $product): ?>
147
- <ul class="installer-products-list" style="display:inline">
148
- <li>
149
- <a class="button-secondary" href="<?php echo $product['url'] ?>"><?php echo $product['label'] ?></a>
150
- </li>
151
- </ul>
152
- <?php endforeach; ?>
153
- <?php endif; ?>
154
-
155
- <?php if($package['downloads']): ?>
156
- <?php include $this->plugin_path() . '/templates/downloads-list.php'; ?>
157
- <?php endif; ?>
158
- </td>
159
- </tr>
160
- <?php endforeach; ?>
161
- </table>
162
- <?php endif; ?>
163
-
164
- <?php endif; ?>
165
-
166
-
167
- </td>
168
- </tr>
169
-
170
- <?php endforeach; ?>
171
-
172
- </table>
173
-
174
-
175
- <p><i><?php printf(__('This page lets you install plugins and update existing plugins. To remove any of these plugins, go to the %splugins%s page and if you have the permission to remove plugins you should be able to do this.', 'installer'), '<a href="' . admin_url('plugins.php') . '">' , '</a>'); ?></i></p>
176
-
177
-
178
-
179
- <br />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/otgs/installer/changelog.txt CHANGED
@@ -1,136 +1,139 @@
1
- = 1.7.9 =
2
- * Save the client_id value from the site_key_validation API call response and make it available via WP_Installer_API::get_ts_client_id API call
3
-
4
- = 1.7.8 =
5
- * Small fix for hiding the WPML registration notice
6
-
7
- = 1.7.7 =
8
- * Fixed js error showing up during registration
9
- * Styles update for unified WPML messages
10
-
11
- = 1.7.6 =
12
- * Updated error messages when validating site keys and stopped removing site keys in case of communication errors
13
- * Added a note for users who renewed or purchased new subscriptions and who need to revalidate their subscription from their websites
14
- * Fixed a problem with the registrations for multi-site setups when WordPress was installed in a separate folder
15
-
16
- = 1.7.5 =
17
- * Fixed a bug causing registration to not be recognized for the entire network in the multi-site mode
18
-
19
- = 1.7.4 =
20
- * Use https for wp-types API
21
-
22
- = 1.7.3 =
23
- * Added a dependencies class and check for the windows paths length exception
24
- * Bug fix: all downloads showed up twice on the plugins list whe upgrading from WPML 3.3
25
-
26
- = 1.7.2 =
27
- * Added an exception to handle the case when Types embedded is installer from Toolset Installer and its included Installer version overrides the one running the Toolset setup wizard
28
-
29
- = 1.7.1 =
30
- * Added an exception for the case of Types 1.8.9 (Installer 1.7.0) together with older WPML (older Installer)
31
-
32
- = 1.7.0 =
33
- * New format for the products data file.
34
- * Other fixes
35
-
36
- = 1.6.8 =
37
- * Sanitized an input that was a potential security issue
38
-
39
- = 1.6.7 =
40
- * Fixed a bug causing repeated calls to the Toolset api to validate the user subscription
41
- * Use https for API urls
42
-
43
- = 1.6.6 =
44
- * Fixed the 'Call to undefined function get_plugins()' issue
45
-
46
- = 1.6.5 =
47
- * Added configuration file for composer
48
- * Updated how free plugins are shown on the plugins list (commercial tab)
49
- * API calls for manipulating translation service preferences
50
- * Support for hosting custom Installer packages on wpml.org
51
- * Fixed a warning that was showing when using the OTGS_DISABLE_AUTO_UPDATES constant before any product data was downloaded
52
- * Changed the frequency with which product updates are checked automatically (24 hours)
53
- * Improved reporting for version numbers
54
-
55
- = 1.6.4 =
56
- * Enabled the OTGS_DISABLE_AUTO_UPDATES constant for theme update checks
57
- * Fixed a bug that was causing Register links to show for all installed plugins
58
-
59
- = 1.6.3 =
60
- * Fixed performance issue related to themes upgrade logic
61
-
62
- = 1.6 =
63
- * Improved the way plugins are matched: not just by the folder name (slug) but also by name
64
- * Added support for installing and upgrading themes from repositories (currently: Toolset themes)
65
- * Added support for 'alias' plugins on the toolset and wpml repositories (currently: Types)
66
- * Enhanced the progress animation during plugins downloading
67
-
68
- = 1.5.6 =
69
- * Updated the translations
70
- * Fix for WPML 3.2 conditional upgrade logic
71
-
72
- = 1.5.5 =
73
- * Fixed the logic for the high_priority parameter
74
- * Fixed js bug causing a conflict with NextGen
75
- * Fixed bug preventing users to install and upgrade Types when they didn't have a Toolset subscription
76
- * Fixed bug preventing users to upgrade from the embedded Types to the full version
77
-
78
- = 1.5.4 =
79
- * Option to disable auto-updates
80
- * Escaped urls generated with add_query_arg
81
-
82
- = 1.5.3 =
83
- * Fixed bug in WP_Installer::custom_plugins_api_call (filter for plugins_api) causing conflicts with other filters for plugins_api
84
-
85
- = 1.5.2 =
86
- * More meaningful errors when plugin downloads fail
87
- * WordPress 4.2 compatibility
88
- * Performance improvements (will not load in places where it's not needed and not make unnecessary requests to the CDN)
89
- * Support putting deps.xml config file in the theme folder (root)
90
- * Included code for importing data for toolset plugins
91
- * Use CloudFront urls for products list files
92
-
93
- = 1.5.1 =
94
- * Fix for allowing embedded plugins to be updated
95
- * Logic for the migration from embedded plugins to full plugins
96
-
97
- = 1.5 =
98
- * Support for embedded plugins
99
- * Bug fix: When user registers site key with trailing slash, downloads might not work
100
- * Tweak: Set a higher timeout limit for the http requests to CDN and API
101
- * API function: link to specific repository
102
- * API function: get product price
103
- * New method for defining affiliate info (with backwards compatibility)
104
-
105
- = 1.4 =
106
- * Show explicit error in case of connectivity issues while validating a key.
107
- * Bug fix: Downloading plugins in bulk was broken by plugin that had a redirect after activation
108
- * Display friendly error message when WordPress does not have permissions to write to the plugins folder
109
- * Added support for configuration files to auto-download required plugins and theme keys
110
- * Changed the "Update this info" button to "Check for updates" (it refreshes the subscription info and checks for updates)
111
- * Support for high_priority parameter that allows setting priority for an Installer instance when more with the same version number exist.
112
- * Config files from different instances are combined (define repositories in different instances)
113
- * Updated support for conditional updates display for ICL users
114
- * More friendly error reporting and handling when using an invalid site key or the plugins archives are not valid.
115
-
116
-
117
- = 1.3.1 =
118
- * Support for conditional release notification (ICanLocalize)
119
-
120
- = 1.3 =
121
- * Added a new repository: Toolset
122
- * The product packages can be displayed hierarchically and ordered
123
- * The link to automatically create site keys will follow through login on the account site (e.g. wpml.org, wp-types.com)
124
- * Fixed animation issues (not showing in most browsers) when downloading plugins.
125
- * Created an admin screen on the repository end (icl-mpp) to sho registration stats (site keys, site keys usage, components usage etc..).
126
- * Bug fix: Renew and Upgrade buttons were not entirely clickable
127
- * Bug fix: Action buttons (buy, renew, upgrade) were not displayed correctly when WPML was not active (Installer embedded in theme)
128
- * Support for site-wide registration. Products can be registered on the network instead of on each site separately.
129
- * Users are able to add either http or https version for any site urls. There will be one site key that will work with both http and https versions.
130
-
131
- = 1.2 =
132
- * Added pagination for site keys list of Account -> My Sites
133
- * Reversed the order in which the site keys are displayed.
134
- * Fixed problem with WPML registration information (site key) not being saved when the option_value field in the wp_options table used a different charset than the default WordPress charset defined in wp-config.php
135
- * Allow registering new sites by clicking a link in the WordPress admin instead of copying and pasting the site url in the Account -> My Sites section
136
- * Display more detailed debug information related to connectivity issues with the WPML repository
 
 
 
1
+ = 1.7.10 =
2
+ * Fixed a notice that was appearing when the site key registration failed
3
+
4
+ = 1.7.9 =
5
+ * Save the client_id value from the site_key_validation API call response and make it available via WP_Installer_API::get_ts_client_id API call
6
+
7
+ = 1.7.8 =
8
+ * Small fix for hiding the WPML registration notice
9
+
10
+ = 1.7.7 =
11
+ * Fixed js error showing up during registration
12
+ * Styles update for unified WPML messages
13
+
14
+ = 1.7.6 =
15
+ * Updated error messages when validating site keys and stopped removing site keys in case of communication errors
16
+ * Added a note for users who renewed or purchased new subscriptions and who need to revalidate their subscription from their websites
17
+ * Fixed a problem with the registrations for multi-site setups when WordPress was installed in a separate folder
18
+
19
+ = 1.7.5 =
20
+ * Fixed a bug causing registration to not be recognized for the entire network in the multi-site mode
21
+
22
+ = 1.7.4 =
23
+ * Use https for wp-types API
24
+
25
+ = 1.7.3 =
26
+ * Added a dependencies class and check for the windows paths length exception
27
+ * Bug fix: all downloads showed up twice on the plugins list whe upgrading from WPML 3.3
28
+
29
+ = 1.7.2 =
30
+ * Added an exception to handle the case when Types embedded is installer from Toolset Installer and its included Installer version overrides the one running the Toolset setup wizard
31
+
32
+ = 1.7.1 =
33
+ * Added an exception for the case of Types 1.8.9 (Installer 1.7.0) together with older WPML (older Installer)
34
+
35
+ = 1.7.0 =
36
+ * New format for the products data file.
37
+ * Other fixes
38
+
39
+ = 1.6.8 =
40
+ * Sanitized an input that was a potential security issue
41
+
42
+ = 1.6.7 =
43
+ * Fixed a bug causing repeated calls to the Toolset api to validate the user subscription
44
+ * Use https for API urls
45
+
46
+ = 1.6.6 =
47
+ * Fixed the 'Call to undefined function get_plugins()' issue
48
+
49
+ = 1.6.5 =
50
+ * Added configuration file for composer
51
+ * Updated how free plugins are shown on the plugins list (commercial tab)
52
+ * API calls for manipulating translation service preferences
53
+ * Support for hosting custom Installer packages on wpml.org
54
+ * Fixed a warning that was showing when using the OTGS_DISABLE_AUTO_UPDATES constant before any product data was downloaded
55
+ * Changed the frequency with which product updates are checked automatically (24 hours)
56
+ * Improved reporting for version numbers
57
+
58
+ = 1.6.4 =
59
+ * Enabled the OTGS_DISABLE_AUTO_UPDATES constant for theme update checks
60
+ * Fixed a bug that was causing Register links to show for all installed plugins
61
+
62
+ = 1.6.3 =
63
+ * Fixed performance issue related to themes upgrade logic
64
+
65
+ = 1.6 =
66
+ * Improved the way plugins are matched: not just by the folder name (slug) but also by name
67
+ * Added support for installing and upgrading themes from repositories (currently: Toolset themes)
68
+ * Added support for 'alias' plugins on the toolset and wpml repositories (currently: Types)
69
+ * Enhanced the progress animation during plugins downloading
70
+
71
+ = 1.5.6 =
72
+ * Updated the translations
73
+ * Fix for WPML 3.2 conditional upgrade logic
74
+
75
+ = 1.5.5 =
76
+ * Fixed the logic for the high_priority parameter
77
+ * Fixed js bug causing a conflict with NextGen
78
+ * Fixed bug preventing users to install and upgrade Types when they didn't have a Toolset subscription
79
+ * Fixed bug preventing users to upgrade from the embedded Types to the full version
80
+
81
+ = 1.5.4 =
82
+ * Option to disable auto-updates
83
+ * Escaped urls generated with add_query_arg
84
+
85
+ = 1.5.3 =
86
+ * Fixed bug in WP_Installer::custom_plugins_api_call (filter for plugins_api) causing conflicts with other filters for plugins_api
87
+
88
+ = 1.5.2 =
89
+ * More meaningful errors when plugin downloads fail
90
+ * WordPress 4.2 compatibility
91
+ * Performance improvements (will not load in places where it's not needed and not make unnecessary requests to the CDN)
92
+ * Support putting deps.xml config file in the theme folder (root)
93
+ * Included code for importing data for toolset plugins
94
+ * Use CloudFront urls for products list files
95
+
96
+ = 1.5.1 =
97
+ * Fix for allowing embedded plugins to be updated
98
+ * Logic for the migration from embedded plugins to full plugins
99
+
100
+ = 1.5 =
101
+ * Support for embedded plugins
102
+ * Bug fix: When user registers site key with trailing slash, downloads might not work
103
+ * Tweak: Set a higher timeout limit for the http requests to CDN and API
104
+ * API function: link to specific repository
105
+ * API function: get product price
106
+ * New method for defining affiliate info (with backwards compatibility)
107
+
108
+ = 1.4 =
109
+ * Show explicit error in case of connectivity issues while validating a key.
110
+ * Bug fix: Downloading plugins in bulk was broken by plugin that had a redirect after activation
111
+ * Display friendly error message when WordPress does not have permissions to write to the plugins folder
112
+ * Added support for configuration files to auto-download required plugins and theme keys
113
+ * Changed the "Update this info" button to "Check for updates" (it refreshes the subscription info and checks for updates)
114
+ * Support for high_priority parameter that allows setting priority for an Installer instance when more with the same version number exist.
115
+ * Config files from different instances are combined (define repositories in different instances)
116
+ * Updated support for conditional updates display for ICL users
117
+ * More friendly error reporting and handling when using an invalid site key or the plugins archives are not valid.
118
+
119
+
120
+ = 1.3.1 =
121
+ * Support for conditional release notification (ICanLocalize)
122
+
123
+ = 1.3 =
124
+ * Added a new repository: Toolset
125
+ * The product packages can be displayed hierarchically and ordered
126
+ * The link to automatically create site keys will follow through login on the account site (e.g. wpml.org, wp-types.com)
127
+ * Fixed animation issues (not showing in most browsers) when downloading plugins.
128
+ * Created an admin screen on the repository end (icl-mpp) to sho registration stats (site keys, site keys usage, components usage etc..).
129
+ * Bug fix: Renew and Upgrade buttons were not entirely clickable
130
+ * Bug fix: Action buttons (buy, renew, upgrade) were not displayed correctly when WPML was not active (Installer embedded in theme)
131
+ * Support for site-wide registration. Products can be registered on the network instead of on each site separately.
132
+ * Users are able to add either http or https version for any site urls. There will be one site key that will work with both http and https versions.
133
+
134
+ = 1.2 =
135
+ * Added pagination for site keys list of Account -> My Sites
136
+ * Reversed the order in which the site keys are displayed.
137
+ * Fixed problem with WPML registration information (site key) not being saved when the option_value field in the wp_options table used a different charset than the default WordPress charset defined in wp-config.php
138
+ * Allow registering new sites by clicking a link in the WordPress admin instead of copying and pasting the site url in the Account -> My Sites section
139
+ * Display more detailed debug information related to connectivity issues with the WPML repository
embedded/otgs/installer/includes/class-installer-dependencies.php CHANGED
@@ -1,278 +1,278 @@
1
- <?php
2
-
3
- class Installer_Dependencies{
4
-
5
- private $uploading_allowed = null;
6
- private $is_win_paths_exception = array();
7
-
8
-
9
- function __construct(){
10
-
11
- add_action( 'admin_init', array( $this, 'prevent_plugins_update_on_plugins_page' ), 100);
12
-
13
-
14
-
15
- global $pagenow;
16
- if($pagenow == 'update.php'){
17
- if(isset($_GET['action']) && $_GET['action'] == 'update-selected'){
18
- add_action('admin_head', array($this, 'prevent_plugins_update_on_updates_screen')); //iframe/bulk
19
- }else{
20
- add_action('all_admin_notices', array($this, 'prevent_plugins_update_on_updates_screen')); //regular/singular
21
- }
22
- }
23
- add_action('wp_ajax_update-plugin', array($this, 'prevent_plugins_update_on_updates_screen'), 0); // high priority, before WP
24
-
25
- }
26
-
27
- public function is_win_paths_exception($repository_id){
28
-
29
- if(!isset($this->is_win_paths_exception[$repository_id])) {
30
-
31
- $this->is_win_paths_exception[$repository_id] = false;
32
-
33
- if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
34
-
35
- $windows_max_path_length = 256;
36
- $longest_path['wpml'] = 109;
37
- $longest_path['toolset'] = 99;
38
-
39
- $margin = 15;
40
-
41
- $upgrade_path_length = strlen( WP_CONTENT_DIR . '/upgrade' );
42
-
43
- $installer_settings = WP_Installer()->settings;
44
-
45
- if ( is_array( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] ) ) {
46
- $a_plugin = current( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] );
47
- $url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
48
- $tmpfname = wp_tempnam( $url );
49
-
50
- $tmpname_length = strlen( basename( $tmpfname ) ) - 4; // -.tmp
51
-
52
- if ( $upgrade_path_length + $tmpname_length + $longest_path[$repository_id] + $margin > $windows_max_path_length ) {
53
-
54
- $this->is_win_paths_exception[$repository_id] = true;
55
-
56
- }
57
-
58
- }
59
-
60
-
61
- }
62
-
63
- }
64
-
65
- return $this->is_win_paths_exception[$repository_id];
66
-
67
- }
68
-
69
- public function is_uploading_allowed(){
70
-
71
- if(!isset($this->uploading_allowed)){
72
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
73
- require_once WP_Installer()->plugin_path() . '/includes/installer-upgrader-skins.php';
74
-
75
- $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
76
- $upgrader = new Plugin_Upgrader($upgrader_skins);
77
-
78
- ob_start();
79
- $res = $upgrader->fs_connect( array(WP_CONTENT_DIR, WP_PLUGIN_DIR) );
80
- ob_end_clean();
81
-
82
- if ( ! $res || is_wp_error( $res ) ) {
83
- $this->uploading_allowed = false;
84
- }else{
85
- $this->uploading_allowed = true;
86
- }
87
- }
88
-
89
- return $this->uploading_allowed;
90
-
91
- }
92
-
93
- public function cant_download($repository_id){
94
-
95
- return !$this->is_uploading_allowed() || $this->is_win_paths_exception($repository_id);
96
-
97
- }
98
-
99
- public function win_paths_exception_message(){
100
- return __('Downloading is not possible. WordPress cannot create required folders because of the
101
- 256 characters limitation of the current Windows environment.', 'installer');
102
- }
103
-
104
- public function prevent_plugins_update_on_plugins_page(){
105
-
106
- $plugins = get_site_transient( 'update_plugins' );
107
- if ( isset($plugins->response) && is_array($plugins->response) ) {
108
- $plugins_with_updates = array_keys( $plugins->response );
109
- }
110
-
111
- if( !empty($plugins_with_updates) ) {
112
-
113
- $plugins = get_plugins();
114
-
115
- $installer_settings = WP_Installer()->settings;
116
- foreach ($installer_settings['repositories'] as $repository_id => $repository) {
117
-
118
- if ($this->is_win_paths_exception($repository_id)) {
119
-
120
- $repositories_plugins = array();
121
- foreach ($repository['data']['packages'] as $package) {
122
- foreach ($package['products'] as $product) {
123
- foreach ($product['plugins'] as $plugin_slug) {
124
- $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
125
- if ( empty($download['free-on-wporg']) ) {
126
- $repositories_plugins[$download['slug']] = $download['name'];
127
- }
128
- }
129
- }
130
- }
131
-
132
- foreach ($plugins as $plugin_id => $plugin) {
133
-
134
- if( in_array( $plugin_id, $plugins_with_updates ) ) {
135
-
136
- $wp_plugin_slug = dirname($plugin_id);
137
- if (empty($wp_plugin_slug)) {
138
- $wp_plugin_slug = basename($plugin_id, '.php');
139
- }
140
-
141
- foreach ($repositories_plugins as $slug => $name) {
142
- if ($wp_plugin_slug == $slug || $name == $plugin['Name'] || $name == $plugin['Title']) { //match order: slug, name, title
143
-
144
- remove_action("after_plugin_row_$plugin_id", 'wp_plugin_update_row', 10, 2);
145
- add_action("after_plugin_row_$plugin_id", array($this, 'wp_plugin_update_row_win_exception'), 10, 2);
146
-
147
- }
148
- }
149
-
150
- }
151
-
152
- }
153
-
154
- }
155
-
156
-
157
- }
158
-
159
- }
160
-
161
- }
162
-
163
- public function wp_plugin_update_row_win_exception(){
164
- $wp_list_table = _get_list_table('WP_Plugins_List_Table');
165
- echo '<tr class="plugin-update-tr">';
166
- echo '<td class="plugin-update colspanchange" colspan="' . esc_attr( $wp_list_table->get_column_count() ) .
167
- '"><div class="update-message">' . $this->win_paths_exception_message() . '</div></td>';
168
- echo '</tr>';
169
- }
170
-
171
- public function prevent_plugins_update_on_updates_screen(){
172
-
173
- if ( isset($_REQUEST['action']) ) {
174
-
175
- $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
176
-
177
- $installer_settings = WP_Installer()->settings;
178
-
179
- //bulk mode
180
- if('update-selected' == $action) {
181
-
182
- global $plugins;
183
-
184
- if(isset($plugins) && is_array($plugins)) {
185
-
186
- foreach ($plugins as $k => $plugin) {
187
-
188
- $wp_plugin_slug = dirname($plugin);
189
-
190
- foreach ($installer_settings['repositories'] as $repository_id => $repository) {
191
-
192
- if( $this->is_win_paths_exception($repository_id) ){
193
-
194
- foreach ($repository['data']['packages'] as $package) {
195
-
196
- foreach ($package['products'] as $product) {
197
-
198
- foreach ($product['plugins'] as $plugin_slug) {
199
-
200
- $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
201
-
202
- if ($download['slug'] == $wp_plugin_slug && empty($download['free-on-wporg']) ) {
203
-
204
- echo '<div class="updated error"><p>' . $this->win_paths_exception_message() .
205
- ' <strong>(' . $download['name'] . ')</strong>' . '</p></div>';
206
- unset($plugins[$k]);
207
-
208
- break(3);
209
-
210
- }
211
-
212
- }
213
-
214
- }
215
-
216
- }
217
-
218
-
219
- }
220
-
221
- }
222
-
223
- }
224
-
225
- }
226
-
227
- }
228
-
229
-
230
- if( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
231
-
232
- $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
233
-
234
- $wp_plugin_slug = dirname($plugin);
235
-
236
- foreach($installer_settings['repositories'] as $repository_id => $repository){
237
-
238
- if( $this->is_win_paths_exception( $repository_id ) ) {
239
- foreach ($repository['data']['packages'] as $package) {
240
-
241
- foreach($package['products'] as $product) {
242
-
243
- foreach($product['plugins'] as $plugin_slug) {
244
- $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
245
-
246
- //match by folder, will change to match by name and folder
247
- if ( $download['slug'] == $wp_plugin_slug && empty ($download['free-on-wporg'] ) ) {
248
-
249
- echo '<div class="updated error"><p>' . $this->win_paths_exception_message() . '</p></div>';
250
-
251
- echo '<div class="wrap">';
252
- echo '<h2>' . __('Update Plugin') . '</h2>';
253
- echo '<a href="' . admin_url('update-core.php') . '">' . __('Return to the updates page', 'installer') . '</a>';
254
- echo '</div>';
255
- require_once(ABSPATH . 'wp-admin/admin-footer.php');
256
- exit;
257
-
258
- }
259
-
260
- }
261
-
262
- }
263
-
264
- }
265
- }
266
-
267
- }
268
-
269
- }
270
- }
271
-
272
- }
273
-
274
-
275
- }
276
-
277
-
278
-
1
+ <?php
2
+
3
+ class Installer_Dependencies{
4
+
5
+ private $uploading_allowed = null;
6
+ private $is_win_paths_exception = array();
7
+
8
+
9
+ function __construct(){
10
+
11
+ add_action( 'admin_init', array( $this, 'prevent_plugins_update_on_plugins_page' ), 100);
12
+
13
+
14
+
15
+ global $pagenow;
16
+ if($pagenow == 'update.php'){
17
+ if(isset($_GET['action']) && $_GET['action'] == 'update-selected'){
18
+ add_action('admin_head', array($this, 'prevent_plugins_update_on_updates_screen')); //iframe/bulk
19
+ }else{
20
+ add_action('all_admin_notices', array($this, 'prevent_plugins_update_on_updates_screen')); //regular/singular
21
+ }
22
+ }
23
+ add_action('wp_ajax_update-plugin', array($this, 'prevent_plugins_update_on_updates_screen'), 0); // high priority, before WP
24
+
25
+ }
26
+
27
+ public function is_win_paths_exception($repository_id){
28
+
29
+ if(!isset($this->is_win_paths_exception[$repository_id])) {
30
+
31
+ $this->is_win_paths_exception[$repository_id] = false;
32
+
33
+ if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
34
+
35
+ $windows_max_path_length = 256;
36
+ $longest_path['wpml'] = 109;
37
+ $longest_path['toolset'] = 99;
38
+
39
+ $margin = 15;
40
+
41
+ $upgrade_path_length = strlen( WP_CONTENT_DIR . '/upgrade' );
42
+
43
+ $installer_settings = WP_Installer()->settings;
44
+
45
+ if ( is_array( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] ) ) {
46
+ $a_plugin = current( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] );
47
+ $url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
48
+ $tmpfname = wp_tempnam( $url );
49
+
50
+ $tmpname_length = strlen( basename( $tmpfname ) ) - 4; // -.tmp
51
+
52
+ if ( $upgrade_path_length + $tmpname_length + $longest_path[$repository_id] + $margin > $windows_max_path_length ) {
53
+
54
+ $this->is_win_paths_exception[$repository_id] = true;
55
+
56
+ }
57
+
58
+ }
59
+
60
+
61
+ }
62
+
63
+ }
64
+
65
+ return $this->is_win_paths_exception[$repository_id];
66
+
67
+ }
68
+
69
+ public function is_uploading_allowed(){
70
+
71
+ if(!isset($this->uploading_allowed)){
72
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
73
+ require_once WP_Installer()->plugin_path() . '/includes/installer-upgrader-skins.php';
74
+
75
+ $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
76
+ $upgrader = new Plugin_Upgrader($upgrader_skins);
77
+
78
+ ob_start();
79
+ $res = $upgrader->fs_connect( array(WP_CONTENT_DIR, WP_PLUGIN_DIR) );
80
+ ob_end_clean();
81
+
82
+ if ( ! $res || is_wp_error( $res ) ) {
83
+ $this->uploading_allowed = false;
84
+ }else{
85
+ $this->uploading_allowed = true;
86
+ }
87
+ }
88
+
89
+ return $this->uploading_allowed;
90
+
91
+ }
92
+
93
+ public function cant_download($repository_id){
94
+
95
+ return !$this->is_uploading_allowed() || $this->is_win_paths_exception($repository_id);
96
+
97
+ }
98
+
99
+ public function win_paths_exception_message(){
100
+ return __('Downloading is not possible. WordPress cannot create required folders because of the
101
+ 256 characters limitation of the current Windows environment.', 'installer');
102
+ }
103
+
104
+ public function prevent_plugins_update_on_plugins_page(){
105
+
106
+ $plugins = get_site_transient( 'update_plugins' );
107
+ if ( isset($plugins->response) && is_array($plugins->response) ) {
108
+ $plugins_with_updates = array_keys( $plugins->response );
109
+ }
110
+
111
+ if( !empty($plugins_with_updates) ) {
112
+
113
+ $plugins = get_plugins();
114
+
115
+ $installer_settings = WP_Installer()->settings;
116
+ foreach ($installer_settings['repositories'] as $repository_id => $repository) {
117
+
118
+ if ($this->is_win_paths_exception($repository_id)) {
119
+
120
+ $repositories_plugins = array();
121
+ foreach ($repository['data']['packages'] as $package) {
122
+ foreach ($package['products'] as $product) {
123
+ foreach ($product['plugins'] as $plugin_slug) {
124
+ $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
125
+ if ( empty($download['free-on-wporg']) ) {
126
+ $repositories_plugins[$download['slug']] = $download['name'];
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+ foreach ($plugins as $plugin_id => $plugin) {
133
+
134
+ if( in_array( $plugin_id, $plugins_with_updates ) ) {
135
+
136
+ $wp_plugin_slug = dirname($plugin_id);
137
+ if (empty($wp_plugin_slug)) {
138
+ $wp_plugin_slug = basename($plugin_id, '.php');
139
+ }
140
+
141
+ foreach ($repositories_plugins as $slug => $name) {
142
+ if ($wp_plugin_slug == $slug || $name == $plugin['Name'] || $name == $plugin['Title']) { //match order: slug, name, title
143
+
144
+ remove_action("after_plugin_row_$plugin_id", 'wp_plugin_update_row', 10, 2);
145
+ add_action("after_plugin_row_$plugin_id", array($this, 'wp_plugin_update_row_win_exception'), 10, 2);
146
+
147
+ }
148
+ }
149
+
150
+ }
151
+
152
+ }
153
+
154
+ }
155
+
156
+
157
+ }
158
+
159
+ }
160
+
161
+ }
162
+
163
+ public function wp_plugin_update_row_win_exception(){
164
+ $wp_list_table = _get_list_table('WP_Plugins_List_Table');
165
+ echo '<tr class="plugin-update-tr">';
166
+ echo '<td class="plugin-update colspanchange" colspan="' . esc_attr( $wp_list_table->get_column_count() ) .
167
+ '"><div class="update-message">' . $this->win_paths_exception_message() . '</div></td>';
168
+ echo '</tr>';
169
+ }
170
+
171
+ public function prevent_plugins_update_on_updates_screen(){
172
+
173
+ if ( isset($_REQUEST['action']) ) {
174
+
175
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
176
+
177
+ $installer_settings = WP_Installer()->settings;
178
+
179
+ //bulk mode
180
+ if('update-selected' == $action) {
181
+
182
+ global $plugins;
183
+
184
+ if(isset($plugins) && is_array($plugins)) {
185
+
186
+ foreach ($plugins as $k => $plugin) {
187
+
188
+ $wp_plugin_slug = dirname($plugin);
189
+
190
+ foreach ($installer_settings['repositories'] as $repository_id => $repository) {
191
+
192
+ if( $this->is_win_paths_exception($repository_id) ){
193
+
194
+ foreach ($repository['data']['packages'] as $package) {
195
+
196
+ foreach ($package['products'] as $product) {
197
+
198
+ foreach ($product['plugins'] as $plugin_slug) {
199
+
200
+ $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
201
+
202
+ if ($download['slug'] == $wp_plugin_slug && empty($download['free-on-wporg']) ) {
203
+
204
+ echo '<div class="updated error"><p>' . $this->win_paths_exception_message() .
205
+ ' <strong>(' . $download['name'] . ')</strong>' . '</p></div>';
206
+ unset($plugins[$k]);
207
+
208
+ break(3);
209
+
210
+ }
211
+
212
+ }
213
+
214
+ }
215
+
216
+ }
217
+
218
+
219
+ }
220
+
221
+ }
222
+
223
+ }
224
+
225
+ }
226
+
227
+ }
228
+
229
+
230
+ if( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
231
+
232
+ $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
233
+
234
+ $wp_plugin_slug = dirname($plugin);
235
+
236
+ foreach($installer_settings['repositories'] as $repository_id => $repository){
237
+
238
+ if( $this->is_win_paths_exception( $repository_id ) ) {
239
+ foreach ($repository['data']['packages'] as $package) {
240
+
241
+ foreach($package['products'] as $product) {
242
+
243
+ foreach($product['plugins'] as $plugin_slug) {
244
+ $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
245
+
246
+ //match by folder, will change to match by name and folder
247
+ if ( $download['slug'] == $wp_plugin_slug && empty ($download['free-on-wporg'] ) ) {
248
+
249
+ echo '<div class="updated error"><p>' . $this->win_paths_exception_message() . '</p></div>';
250
+
251
+ echo '<div class="wrap">';
252
+ echo '<h2>' . __('Update Plugin') . '</h2>';
253
+ echo '<a href="' . admin_url('update-core.php') . '">' . __('Return to the updates page', 'installer') . '</a>';
254
+ echo '</div>';
255
+ require_once(ABSPATH . 'wp-admin/admin-footer.php');
256
+ exit;
257
+
258
+ }
259
+
260
+ }
261
+
262
+ }
263
+
264
+ }
265
+ }
266
+
267
+ }
268
+
269
+ }
270
+ }
271
+
272
+ }
273
+
274
+
275
+ }
276
+
277
+
278
+
embedded/otgs/installer/includes/class-installer-theme.php CHANGED
@@ -1,979 +1,979 @@
1
- <?php
2
- /**
3
- * Installer Class for Theme Support
4
- *
5
- * Supports automatic updates and installation of Toolset/WPML Themes
6
- *
7
- * @class Installer_Theme_Class
8
- * @version 1.6
9
- * @category Class
10
- * @author OnTheGoSystems
11
- */
12
-
13
- if ( !defined( 'ABSPATH' ) ) {
14
- exit;
15
- }
16
-
17
- /**
18
- * Installer_Theme_Class
19
- */
20
- class Installer_Theme_Class {
21
-
22
- /** Theme Repository */
23
- private $theme_repo;
24
-
25
- /** Repository API */
26
- private $repository_api;
27
-
28
- /** Repository Theme Products */
29
- private $repository_theme_products;
30
-
31
- /** Site URL */
32
- private $installer_site_url;
33
-
34
- /** Site Key */
35
- private $installer_site_key;
36
-
37
- /** The Themes Option */
38
- protected $installer_themes_option;
39
-
40
- /** Update settings */
41
- protected $installer_themes_available_updates;
42
-
43
- /** The Themes */
44
- protected $installer_themes = array();
45
-
46
- /** Repository with themes */
47
- protected $installer_repo_with_themes;
48
-
49
- /** Active tab */
50
- protected $installer_theme_active_tab;
51
-
52
- /** Theme user registration */
53
- protected $theme_user_registration;
54
-
55
- /** Client active subscription */
56
- protected $installer_theme_subscription_type;
57
-
58
- public function __construct() {
59
-
60
- /** Properties */
61
-
62
- //Get installer repositories
63
- $installer_repositories = WP_Installer()->get_repositories();
64
-
65
- //Get repos with themes
66
- $repos_with_themes = $this->installer_theme_reposities_that_has_themes( $installer_repositories );
67
-
68
- if ( is_array( $repos_with_themes ) ) {
69
- //Assign to property
70
- $this->installer_repo_with_themes = $repos_with_themes;
71
-
72
- //Let's looped through repos with themes
73
- foreach ( $repos_with_themes as $k => $repo ) {
74
-
75
- //$repo could be 'toolset' or 'wpml'
76
- //Assign each repo with theme to property
77
- $this->theme_repo[] = $repo;
78
-
79
- if ( (isset($installer_repositories[$repo]['api-url'])) && (isset($installer_repositories[$repo]['products'])) ) {
80
-
81
- //Define the rest of the properties based on the given repo
82
- $this->repository_api[$repo] = $installer_repositories[$repo]['api-url'];
83
- $this->repository_theme_products[$repo] = $installer_repositories[$repo]['products'];
84
- $this->installer_site_url[$repo] = WP_Installer()->get_installer_site_url( $repo );
85
- $this->installer_site_key[$repo] = WP_Installer()->get_site_key( $repo );
86
- $this->theme_user_registration[$repo] = false;
87
-
88
- if ( WP_Installer()->repository_has_valid_subscription( $repo ) ) {
89
-
90
- $this->installer_theme_subscription_type = WP_Installer()->get_subscription_type_for_repository( $repo );
91
- $this->installer_themes_option[$repo] = 'wp_installer_' . $repo . '_themes';
92
- $this->installer_themes_available_updates[$repo] = 'wp_installer_' . $repo . '_updated_themes';
93
- $this->installer_theme_active_tab = '';
94
-
95
- //We only set themes available to this validated subscription
96
- $this->installer_theme_available( $repo, $this->installer_theme_subscription_type );
97
-
98
- add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_sets_active_tab_on_init'), 10 );
99
- $this->theme_user_registration[$repo] = true;
100
- }
101
-
102
- /** We are ready.. let's initialize .... */
103
- $this->init();
104
- }
105
- }
106
- add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_loaded_hooks') );
107
- }
108
- }
109
-
110
- /** Init */
111
- public function init() {
112
- add_action( 'admin_enqueue_scripts', array($this, 'installer_theme_enqueue_scripts') );
113
- add_filter( 'themes_api', array($this, 'installer_theme_api_override'), 10, 3 );
114
- add_filter( 'themes_api_result', array($this, 'installer_theme_api_override_response'), 10, 3 );
115
- add_filter( 'site_transient_update_themes', array($this, 'installer_theme_upgrade_check'), 10, 1 );
116
- add_action( 'http_api_debug', array($this, 'installer_theme_sync_native_wp_api'), 10, 5 );
117
- add_filter( 'installer_theme_hook_response_theme', array($this, 'installer_theme_add_num_ratings'), 10, 1 );
118
- add_filter( 'themes_update_check_locales', array($this, 'installer_theme_sync_call_wp_theme_api'), 10, 1 );
119
- add_filter( 'admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 3 );
120
- add_filter( 'network_admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 2 );
121
- add_action( 'wp_ajax_installer_theme_frontend_selected_tab', array($this, 'installer_theme_frontend_selected_tab'), 0 );
122
- add_action( 'wp_loaded', array($this, 'installer_themes_support_set_up_func') );
123
- }
124
-
125
- /** Enqueue scripts */
126
- public function installer_theme_enqueue_scripts() {
127
- $current_screen = $this->installer_theme_current_screen();
128
- $commercial_plugin_screen = $this->installer_theme_is_commercial_plugin_screen( $current_screen );
129
- if ( ('theme-install' == $current_screen) || ($commercial_plugin_screen) || ('theme-install-network' == $current_screen) ) {
130
- $repo_with_themes = $this->installer_repo_with_themes;
131
- $js_array = array();
132
- if ( is_array( $repo_with_themes ) ) {
133
- foreach ( $repo_with_themes as $k => $v ) {
134
-
135
- //Hyperlink text
136
- $theme_repo_name = $this->installer_theme_get_repo_product_name( $v );
137
- $the_hyperlink_text = esc_js( $theme_repo_name );
138
-
139
- if ( is_multisite() ) {
140
- $admin_url_passed = network_admin_url();
141
- } else {
142
- $admin_url_passed = admin_url();
143
- }
144
-
145
- //Define
146
- $js_array[$v] = array(
147
- 'the_hyperlink_text' => $the_hyperlink_text,
148
- 'registration_status' => $this->theme_user_registration[$v],
149
- 'is_commercial_plugin_tab' => $commercial_plugin_screen,
150
- 'registration_url' => $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $v
151
- );
152
-
153
- }
154
- }
155
-
156
- if ( !(empty($js_array)) ) {
157
- wp_enqueue_script( 'installer-theme-install', WP_Installer()->res_url() . '/res/js/installer_theme_install.js', array('jquery', 'installer-admin'), WP_Installer()->version() );
158
- $installer_ajax_url = admin_url( 'admin-ajax.php' );
159
-
160
- if ( is_ssl() ) {
161
- $installer_ajax_url = str_replace( 'http://', 'https://', $installer_ajax_url );
162
- } else {
163
- $installer_ajax_url = str_replace( 'https://', 'http://', $installer_ajax_url );
164
- }
165
-
166
- //Case where user is subscribed to a subscription that does not have themes
167
- $subscription_js_check = $this->installer_theme_subscription_does_not_have_theme( $js_array );
168
-
169
- wp_localize_script( 'installer-theme-install', 'installer_theme_install_localize',
170
- array(
171
- 'js_array_installer' => $js_array,
172
- 'ajaxurl' => $installer_ajax_url,
173
- 'no_associated_themes' => $subscription_js_check,
174
- 'installer_theme_frontend_selected_tab_nonce' => wp_create_nonce( 'installer_theme_frontend_selected_tab' )
175
- )
176
- );
177
- }
178
- }
179
- }
180
-
181
- /** Case where user is subscribed to a subscription that does not have themes */
182
- protected function installer_theme_subscription_does_not_have_theme( $js_array ) {
183
-
184
- $any_subscription_has_theme = array();
185
- $number_of_registrations = array();
186
-
187
- //Step1, we looped through JS array
188
- foreach ( $js_array as $repo_slug => $js_details ) {
189
-
190
- //Step2, checked if user is registered
191
- if ( isset($this->theme_user_registration[$repo_slug]) ) {
192
- $registration_status = $this->theme_user_registration[$repo_slug];
193
- if ( $registration_status ) {
194
-
195
- //Registered
196
- $number_of_registrations[] = $repo_slug;
197
-
198
- //Step3, we checked if the $repo_slug has available theme
199
- $themes_available = false;
200
- if ( isset($this->installer_themes[$repo_slug]) ) {
201
- $themes_available = $this->installer_themes[$repo_slug];
202
- if ( !(empty($themes_available)) ) {
203
- //This subscription has theme
204
- $themes_available = true;
205
- }
206
- }
207
-
208
- if ( $themes_available ) {
209
- $any_subscription_has_theme[] = $repo_slug;
210
- }
211
- }
212
- }
213
-
214
- }
215
-
216
- //Step4, we are done looping, check if there are any repos that have themes
217
- if ( empty($registration_status) ) {
218
-
219
- //No registration on any repos
220
- return FALSE;
221
-
222
- } elseif ( !(empty($registration_status)) ) {
223
-
224
- //Has some registration on some repos
225
- //We then checked if this user has any active subscriptions
226
- if ( empty($any_subscription_has_theme) ) {
227
- //No subscription
228
- return TRUE;
229
- } else {
230
- //Has subscription found
231
- return FALSE;
232
- }
233
- }
234
- }
235
-
236
- /** Check if its the commercial plugin screen */
237
- private function installer_theme_is_commercial_plugin_screen( $current_screen ) {
238
- $commercial = false;
239
- if ( ('plugin-install' == $current_screen) || ('plugin-install-network' == $current_screen) ) {
240
- if ( isset($_GET['tab']) ) {
241
- $tab = $_GET['tab'];
242
- if ( 'commercial' == $tab ) {
243
- $commercial = true;
244
- }
245
- }
246
- }
247
- return $commercial;
248
- }
249
-
250
- /** Current screen */
251
- private function installer_theme_current_screen() {
252
-
253
- $current_screen_loaded = false;
254
-
255
- if ( function_exists( 'get_current_screen' ) ) {
256
-
257
- $screen_output = get_current_screen();
258
- $current_screen_loaded = $screen_output->id;
259
-
260
- }
261
-
262
- return $current_screen_loaded;
263
-
264
- }
265
-
266
- /** Override WordPress Themes API */
267
- public function installer_theme_api_override( $api_boolean, $action, $args ) {
268
-
269
- //Let's checked if user is browsing our themes
270
- if ( isset($args->browse) ) {
271
- $browse = $args->browse;
272
- if ( in_array( $browse, $this->theme_repo ) ) {
273
- //Uniquely validated for our Themes
274
- if ( 'query_themes' == $action ) {
275
- //User is querying or asking information about our themes, let's override
276
- $api_boolean = true;
277
- }
278
- }
279
- } elseif ( isset($args->slug) ) {
280
- //We are installing our themes
281
- $theme_to_install = $args->slug;
282
-
283
- //Lets uniquely validate if this belongs to us
284
- //Check if this is OTGS theme
285
- $validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
286
- if ( $validate_check ) {
287
- //Belongs to us
288
- if ( !(empty($theme_to_install)) ) {
289
- $api_boolean = true;
290
- }
291
- }
292
- }
293
-
294
- return $api_boolean;
295
- }
296
-
297
- /** Override WordPress Themes API response with our own themes API*/
298
- public function installer_theme_api_override_response( $res, $action, $args ) {
299
-
300
- if ( true === $res ) {
301
- if ( isset($args->browse) ) {
302
- $browse = $args->browse;
303
- if ( in_array( $browse, $this->theme_repo ) ) {
304
- //Uniquely validated for our themes
305
- if ( 'query_themes' == $action ) {
306
- //Client querying OTGS themes
307
- //Check for registration status
308
- if ( isset($this->theme_user_registration[$browse]) ) {
309
- //Set
310
- if ( !($this->theme_user_registration[$browse]) ) {
311
- //Not registered yet
312
- $res = new stdClass();
313
- $res->info = array();
314
- $res->themes = array();
315
- return $res;
316
- } else {
317
- //Registered
318
- $themes = $this->installer_theme_get_themes( '', $browse );
319
- $res = $this->installer_theme_format_response( $themes, $action );
320
- }
321
- }
322
- }
323
- }
324
- } elseif ( isset($args->slug) ) {
325
- //We are installing theme
326
- //Lets uniquely validate if this belongs to our theme
327
- $theme_to_install = $args->slug;
328
-
329
- //Lets uniquely validate if this belongs to us
330
- //Check if this is OTGS theme
331
- $validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
332
- if ( $validate_check ) {
333
- //Belongs to us
334
- if ( ($res) && ('theme_information' == $action) ) {
335
- $themes = $this->installer_theme_get_themes( '', $this->installer_theme_active_tab );
336
- $res = $this->installer_theme_format_response( $themes, $action, $args->slug );
337
- }
338
- }
339
- }
340
- return $res;
341
- } else {
342
- //Default WP Themes here
343
- $client_side_active_tab = get_option( 'wp_installer_clientside_active_tab' );
344
- if ( $client_side_active_tab ) {
345
- if ( !(in_array( $client_side_active_tab, $this->theme_repo )) ) {
346
- //Not OTGS tab
347
- return $res;
348
- }
349
- }
350
-
351
- }
352
- }
353
-
354
- /** Get Themes */
355
- private function installer_theme_get_themes( $product_url = '', $repo_source = '' ) {
356
-
357
- //Query API
358
- if ( empty($product_url) ) {
359
- //Not set
360
- if ( isset($this->repository_theme_products[$this->installer_theme_active_tab]) ) {
361
- $query_remote_url = $this->repository_theme_products[$this->installer_theme_active_tab];
362
- }
363
-
364
- } else {
365
- $query_remote_url = $product_url;
366
- }
367
-
368
- //Let's retrieved current installer settings so we won't be querying all the time
369
- $current_installer_settings = WP_Installer()->get_settings();
370
-
371
- //Set $themes to FALSE by default
372
- $themes = false;
373
-
374
- if ( (is_array( $current_installer_settings )) && (!(empty($current_installer_settings))) ) {
375
-
376
- //Set and already defined, retrieved $products
377
- if ( isset($current_installer_settings['repositories'][$repo_source]['data']) ) {
378
- $products = $current_installer_settings['repositories'][$repo_source]['data'];
379
- if ( isset($products['downloads']['themes']) ) {
380
- $themes = $products['downloads']['themes'];
381
- }
382
- }
383
-
384
- } else {
385
-
386
- //Call API
387
- $response = wp_remote_get( $query_remote_url );
388
-
389
- if ( is_wp_error( $response ) ) {
390
- //Error detected: http fallback
391
- $query_remote_url = preg_replace( "@^https://@", 'http://', $query_remote_url );
392
- $response = wp_remote_get( $query_remote_url );
393
- }
394
-
395
- if ( !(is_wp_error( $response )) ) {
396
- //Not WP error
397
- //Evaluate response
398
- if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
399
- //In this case, response is set and defined, proceed...
400
- $body = wp_remote_retrieve_body( $response );
401
- if ( $body ) {
402
- $products = json_decode( $body, true );
403
- if ( isset($products['downloads']['themes']) ) {
404
- $themes = $products['downloads']['themes'];
405
- }
406
- }
407
-
408
- }
409
- }
410
- }
411
-
412
- //Return themes, can be filtered by user subscription type
413
- return apply_filters( 'installer_theme_get_themes', $themes, $this->installer_theme_active_tab );
414
- }
415
-
416
- /** Format response in compatibility with WordPress Theme API response */
417
- private function installer_theme_format_response( $themes, $action, $slug = '' ) {
418
-
419
- //Let's append download link only when retrieving theme information for installation
420
- if ( ('theme_information' == $action) && (!(empty($slug))) ) {
421
-
422
- //Only return one result -> the theme to be installed
423
- foreach ( $themes as $k => $theme ) {
424
- if ( $slug == $theme['basename'] ) {
425
- $theme['download_link'] = WP_Installer()->append_site_key_to_download_url( $theme['url'], $this->installer_site_key[$this->installer_theme_active_tab], $this->installer_theme_active_tab );
426
- $theme = json_decode( json_encode( $theme ), FALSE );
427
- return $theme;
428
- }
429
- }
430
-
431
- } else {
432
-
433
- $res = new stdClass();
434
- $res->info = array();
435
- $res->themes = array();
436
-
437
- //Define info
438
- $res->info['page'] = 1;
439
- $res->info['pages'] = 10;
440
-
441
- //Let's count available themes ;
442
- $res->info['results'] = count( $themes );
443
-
444
- //Let's saved themes for easy access later on
445
- $this->installer_theme_savethemes_by_slug( $themes );
446
-
447
- //Let's defined available themes
448
- if ( isset($this->installer_theme_subscription_type) ) {
449
- //Has subscription type defined, let's saved what is associated with this subscription
450
- $this->installer_theme_available( $this->installer_theme_active_tab, $this->installer_theme_subscription_type );
451
- } else {
452
- $this->installer_theme_available( $this->installer_theme_active_tab );
453
- }
454
-
455
- //Let's add themes to the overriden WordPress API Theme response
456
- /** Installer 1.7.6: Update to compatible data format response from WP Theme API */
457
- $theme_compatible_array=array();
458
- if ((is_array($themes))) {
459
- foreach ($themes as $k=>$v) {
460
- $theme_compatible_array[]=(object)($v);
461
- }
462
- }
463
- $res->themes = $theme_compatible_array;
464
- $res->themes = apply_filters( 'installer_theme_hook_response_theme', $res->themes );
465
- return $res;
466
- }
467
- }
468
-
469
- /** Let's save all available themes by its slug after any latest API query */
470
- private function installer_theme_savethemes_by_slug( $themes, $doing_query = false ) {
471
-
472
- if ( !($doing_query) ) {
473
- $this->installer_themes[$this->installer_theme_active_tab] = array();
474
- }
475
-
476
- if ( !(empty($themes)) ) {
477
- $themes_for_saving = array();
478
- foreach ( $themes as $k => $theme ) {
479
- if ( !($doing_query) ) {
480
- if ( isset($theme['slug']) ) {
481
- $theme_slug = $theme['slug'];
482
- if ( !(empty($theme_slug)) ) {
483
- $themes_for_saving[] = $theme_slug;
484
- }
485
- }
486
- } else {
487
-
488
- if ( ((isset($theme['slug'])) && (isset($theme['version'])) &&
489
- (isset($theme['theme_page_url']))) && (isset($theme['url']))
490
- ) {
491
- $theme_slug = $theme['slug'];
492
- $theme_version = $theme['version'];
493
- $theme_page_url = $theme['theme_page_url'];
494
- $theme_url = $theme['url'];
495
- if ( (!(empty($theme_slug))) && (!(empty($theme_version))) &&
496
- (!(empty($theme_page_url))) && (!(empty($theme_url)))
497
- ) {
498
- //$theme_slug is unique for every theme
499
- $themes_for_saving[$theme_slug] = array(
500
- 'version' => $theme_version,
501
- 'theme_page_url' => $theme_page_url,
502
- 'url' => $theme_url
503
- );
504
-
505
- }
506
- }
507
- }
508
-
509
- }
510
-
511
- if ( !(empty($themes_for_saving)) ) {
512
- //Has themes for saving
513
- if ( !($doing_query) ) {
514
- //Not doing query
515
- $existing_themes = get_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
516
- if ( !($existing_themes) ) {
517
- //Does not yet exists
518
- delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
519
- update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
520
- } else {
521
- //exists, check if we need to update
522
- if ( $existing_themes == $themes_for_saving ) {
523
- //Equal, no need to update here
524
- } else {
525
- //Update
526
- delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
527
- update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
528
- }
529
- }
530
- } else {
531
- //Used for query purposes only, don't save anything
532
- return $themes_for_saving;
533
- }
534
- }
535
- }
536
- }
537
-
538
- /** Available themes */
539
- private function installer_theme_available( $repo, $subscription_type = '' ) {
540
-
541
- $subscription_type = intval( $subscription_type );
542
- if ( $subscription_type > 0 ) {
543
-
544
- //Here we have a case of validated subscription
545
- //We need to set themes that is available to this subscription
546
- $themes_associated_with_subscription = $this->installer_themes[$repo] = $this->installer_theme_get_themes_by_subscription( $subscription_type, $repo );
547
- if ( !(empty($themes_associated_with_subscription)) ) {
548
- //Has themes
549
- $this->installer_themes[$repo] = $themes_associated_with_subscription;
550
- }
551
- } else {
552
-
553
- //Get themes
554
- $this->installer_themes[$repo] = get_option( $this->installer_themes_option[$repo] );
555
- }
556
- }
557
-
558
- /** Theme upgrade check */
559
- public function installer_theme_upgrade_check( $the_value ) {
560
-
561
- //Step1: Let's looped through repos with themes and check if we have updates available for them.
562
- if ( (is_array( $this->installer_repo_with_themes )) && (!(empty($this->installer_repo_with_themes))) ) {
563
- foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
564
- //Step2: Let's checked if we have update for this theme
565
- $update_available = get_option( $this->installer_themes_available_updates[$repo_slug] );
566
- if ( $update_available ) {
567
- if ( (is_array( $update_available )) && (!(empty($update_available))) ) {
568
- //Has updates available coming from this specific theme repo
569
- //Let's loop through the themes that needs update
570
- foreach ( $update_available as $theme_slug => $v ) {
571
- //Add to response API
572
- $the_value->response [$theme_slug] = array(
573
- 'theme' => $theme_slug,
574
- 'new_version' => $v['new_version'],
575
- 'url' => $v['url'],
576
- 'package' => $v['package']
577
- );
578
- }
579
- }
580
- }
581
- }
582
- }
583
- //Return
584
- return $the_value;
585
- }
586
-
587
- /** Return repositories that has themes */
588
- private function installer_theme_reposities_that_has_themes( $repositories, $ret_value = true, $doing_api_query = false ) {
589
-
590
- $repositories_with_themes = array();
591
-
592
- if ( (is_array( $repositories )) && (!(empty($repositories))) ) {
593
-
594
- //Let's checked if we have something before
595
- $themes = get_option( 'installer_repositories_with_theme' );
596
-
597
- if ( (!($themes)) || ($doing_api_query) ) {
598
- //Not yet defined
599
- //Loop through each repositories and check whether they have themes
600
- foreach ( $repositories as $k => $v ) {
601
- if ( isset($v['products']) ) {
602
- $products_url = $v['products'];
603
- $themes = $this->installer_theme_get_themes( $products_url, $k );
604
- if ( (is_array( $themes )) && (!(empty($themes))) ) {
605
- //Repo has themes
606
- $repositories_with_themes[] = $k;
607
- }
608
- }
609
- }
610
- } else {
611
- //Already set
612
- $repositories_with_themes = $themes;
613
- }
614
-
615
- if ( (((is_array( $repositories_with_themes )) && (!(empty($repositories_with_themes)))) && (!($themes))) || ($doing_api_query) ) {
616
- //Save to db
617
- update_option( 'installer_repositories_with_theme', $repositories_with_themes );
618
- }
619
- }
620
-
621
- if ( $ret_value ) {
622
- return $repositories_with_themes;
623
- }
624
-
625
- }
626
-
627
- /** When WordPress queries its own Themes API, we sync with our own */
628
- public function installer_theme_sync_native_wp_api( $response, $responsetext, $class, $args, $url ) {
629
-
630
- $api_native_string = 'api.wordpress.org/themes/';
631
- if ( (strpos( $url, $api_native_string ) !== false) ) {
632
- //WordPress is querying its own themes API
633
- $installer_repositories = WP_Installer()->get_repositories();
634
-
635
- //Query our own API and update repository values too
636
- $this->installer_theme_reposities_that_has_themes( $installer_repositories, false, true );
637
- }
638
- }
639
-
640
- /** Returns product name by theme repo slug */
641
- private function installer_theme_get_repo_product_name( $theme_repo ) {
642
-
643
- $theme_repo_name = false;
644
-
645
- if ( isset(WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name']) ) {
646
- //Set
647
- $prod_name = WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name'];
648
- if ( !(empty($prod_name)) ) {
649
- $theme_repo_name = $prod_name;
650
- }
651
- } else {
652
- //Not yet
653
- if ( $theme_repo == $this->theme_repo ) {
654
- $result = $this->installer_theme_general_api_query();
655
- if ( isset($result['product-name']) ) {
656
- $product_name = $result['product-name'];
657
- if ( !(empty($product_name)) ) {
658
- $theme_repo_name = $product_name;
659
- }
660
- }
661
- }
662
- }
663
-
664
- return $theme_repo_name;
665
- }
666
-
667
- /** General query API method, returns $products */
668
- private function installer_theme_general_api_query() {
669
- $products = false;
670
- $response = wp_remote_get( $this->repository_theme_products );
671
- if ( !(is_wp_error( $response )) ) {
672
- //Not WP error
673
- //Evaluate response
674
- if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
675
- //In this case, response is set and defined, proceed...
676
- $body = wp_remote_retrieve_body( $response );
677
- if ( $body ) {
678
- $result = json_decode( $body, true );
679
- if ( (is_array( $result )) && (!(empty($result))) ) {
680
- $products = $result;
681
- }
682
- }
683
-
684
- }
685
- }
686
-
687
- return $products;
688
- }
689
-
690
- /** General method to check if themes are OTGS themes based on its slug*/
691
- private function installer_themes_belong_to_us( $theme_slug ) {
692
-
693
- $found = false;
694
- $theme_slug = trim( $theme_slug );
695
-
696
- foreach ( $this->installer_themes as $repo_with_theme => $themes ) {
697
- foreach ( $themes as $k => $otgs_theme_slug ) {
698
- if ( $theme_slug == $otgs_theme_slug ) {
699
- //match found! Theme belongs to otgs
700
- return true;
701
- }
702
- }
703
- }
704
- return $found;
705
-
706
- }
707
-
708
- /** Sets active tab on init */
709
- public function installer_theme_sets_active_tab_on_init() {
710
-
711
- if ( isset ($_SERVER ['REQUEST_URI']) ) {
712
- $request_uri = $_SERVER ['REQUEST_URI'];
713
- if ( isset ($_GET ['browse']) ) {
714
- $active_tab = trim( $_GET ['browse'] );
715
- $this->installer_theme_active_tab = $active_tab;
716
- } elseif ( isset ($_POST ['request'] ['browse']) ) {
717
- $active_tab = trim( $_POST ['request'] ['browse'] );
718
- $this->installer_theme_active_tab = $active_tab;
719
- } elseif ( (isset ($_GET ['theme_repo'])) && (isset ($_GET ['action'])) ) {
720
- $theme_repo = trim( $_GET ['theme_repo'] );
721
- $the_action = trim( $_GET ['action'] );
722
- if ( ('install-theme' == $the_action) && (!(empty($theme_repo))) ) {
723
- $this->installer_theme_active_tab = $theme_repo;
724
- }
725
- } elseif ( wp_get_referer() ) {
726
- $referer = wp_get_referer();
727
- $parts = parse_url( $referer );
728
- if ( isset($parts['query']) ) {
729
- parse_str( $parts['query'], $query );
730
- if ( isset($query['browse']) ) {
731
- $this->installer_theme_active_tab = $query['browse'];
732
- }
733
- }
734
- }
735
- }
736
- }
737
-
738
- /** WP Theme API compatibility- added num ratings */
739
- /** Installer 1.7.6+ Added updated 'rating' field */
740
- public function installer_theme_add_num_ratings( $themes ) {
741
-
742
- if ( (is_array( $themes )) && (!(empty($themes))) ) {
743
- foreach ( $themes as $k => $v ) {
744
- if ( !(isset($v->num_ratings)) ) {
745
- $themes[$k]->num_ratings = 100;
746
- }
747
- if ( !(isset($v->rating)) ) {
748
- $themes[$k]->rating = 100;
749
- }
750
- }
751
- }
752
-
753
- return $themes;
754
- }
755
-
756
- /** When WordPress.org makes a call to its repository, let's run our own upgrade checks too */
757
- public function installer_theme_sync_call_wp_theme_api( $locales ) {
758
-
759
- $this->installer_theme_upgrade_theme_check();
760
-
761
- return $locales;
762
- }
763
-
764
- /** Upgrade theme check */
765
- private function installer_theme_upgrade_theme_check() {
766
-
767
- // Step1-> we get all installed themes in clients local themes directory
768
- $installed_themes = wp_get_themes();
769
-
770
- // Step2: We need to loop through each repository with themes
771
- foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
772
-
773
- // We then need to retrieved the products URL for each of this repo
774
- $products_url = $this->repository_theme_products [$repo_slug];
775
-
776
- // Step3-> we get all available themes in our repository via API based on this URL
777
- $available_themes = $this->installer_theme_get_themes( $products_url, $repo_slug );
778
-
779
- if ( !($available_themes) ) {
780
-
781
- // API is not available as of the moment, return..
782
- return;
783
- } else {
784
-
785
- // We have available themes here...
786
- // Step4->let's simplify available themes data by slugs
787
- $simplified_available_themes = $this->installer_theme_savethemes_by_slug( $available_themes, true );
788
-
789
- // Step5->Let's loop through installed themes
790
- if ( (is_array( $installed_themes )) && (!(empty ($installed_themes))) ) {
791
- $otgs_theme_updates_available = array();
792
- foreach ( $installed_themes as $theme_slug => $theme_object ) {
793
- if ( array_key_exists( $theme_slug, $simplified_available_themes ) ) {
794
-
795
- // This is our theme
796
- // Step6->Let's get version of the local theme installed
797
- $local_version = $theme_object->get( 'Version' );
798
-
799
- // Step7->Let's get the latest version of this theme, page URL and download URL from our repository
800
- $repository_version = $simplified_available_themes [$theme_slug] ['version'];
801
- $theme_page_url = $simplified_available_themes [$theme_slug] ['theme_page_url'];
802
- $theme_download_url = $simplified_available_themes [$theme_slug] ['url'];
803
-
804
- // Step8->Let's compare the version
805
- if ( version_compare( $repository_version, $local_version, '>' ) ) {
806
-
807
- // Update available for this theme
808
- // Step9-> Define download URL with site key
809
- $package_url = WP_Installer()->append_site_key_to_download_url( $theme_download_url, $this->installer_site_key [$repo_slug], $repo_slug );
810
-
811
- //Step10-> Assign to updates array for later accessing.
812
- $otgs_theme_updates_available[$theme_slug] = array(
813
- 'theme' => $theme_slug,
814
- 'new_version' => $repository_version,
815
- 'url' => $theme_page_url,
816
- 'package' => $package_url
817
- );
818
- }
819
- }
820
- }
821
- //Exited the upgrade loop for this specific theme repository
822
- if ( !(empty($otgs_theme_updates_available)) ) {
823
- //Has updates
824
- update_option( $this->installer_themes_available_updates[$repo_slug], $otgs_theme_updates_available );
825
- } else {
826
- //No updates
827
- delete_option( $this->installer_themes_available_updates[$repo_slug] );
828
- }
829
-
830
- }
831
- }
832
- }
833
- }
834
-
835
- /** When the user is on Themes install page OTG themes repository, let's the currently selected tab */
836
- public function installer_theme_add_query_arg_tab( $url, $path, $blog_id = null ) {
837
-
838
- $wp_install_string = 'update.php?action=install-theme';
839
- if ( $path == $wp_install_string ) {
840
- if ( isset($this->installer_theme_active_tab) ) {
841
- if ( !(empty($this->installer_theme_active_tab)) ) {
842
- $url = add_query_arg( array(
843
- 'theme_repo' => $this->installer_theme_active_tab
844
- ), $url );
845
- }
846
- }
847
- }
848
- return $url;
849
- }
850
-
851
- /** Save frontend theme tab selected */
852
- public function installer_theme_frontend_selected_tab() {
853
- if ( isset($_POST["frontend_tab_selected"]) ) {
854
- check_ajax_referer( 'installer_theme_frontend_selected_tab', 'installer_theme_frontend_selected_tab_nonce' );
855
-
856
- //Client_side_active_tab
857
- $frontend_tab_selected = filter_input( INPUT_POST, 'frontend_tab_selected', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE );
858
- if ( !(empty($frontend_tab_selected)) ) {
859
- //Front end tab selected
860
- update_option( 'wp_installer_clientside_active_tab', $frontend_tab_selected, false );
861
-
862
- //Check for registration status
863
- if ( isset($this->theme_user_registration[$frontend_tab_selected]) ) {
864
- //Set
865
- if ( !($this->theme_user_registration[$frontend_tab_selected]) ) {
866
- //Not registered yet
867
-
868
- if ( is_multisite() ) {
869
- $admin_url_passed = network_admin_url();
870
- } else {
871
- $admin_url_passed = admin_url();
872
- }
873
-
874
- $registration_url = $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $frontend_tab_selected;
875
-
876
- //Message and link
877
- $theme_repo_name = $this->installer_theme_get_repo_product_name( $frontend_tab_selected );;
878
- $response['unregistered_messages'] = sprintf( __( 'To install and update %s, please %sregister%s %s for this site.', 'installer' ),
879
- $theme_repo_name, '<a href="' . $registration_url . '">', '</a>', $theme_repo_name );
880
-
881
- }
882
- }
883
-
884
- $response['output'] = $frontend_tab_selected;
885
- echo json_encode( $response );
886
- }
887
- die();
888
- }
889
- die();
890
- }
891
-
892
- /** Installer loaded aux hooks */
893
- public function installer_theme_loaded_hooks() {
894
-
895
- if ( isset($this->installer_theme_subscription_type) ) {
896
- $subscription_type = intval( $this->installer_theme_subscription_type );
897
- if ( $subscription_type > 0 ) {
898
- //Client is subscribed
899
- add_filter( 'installer_theme_get_themes', array($this, 'installer_theme_filter_themes_by_subscription'), 10, 2 );
900
- }
901
- }
902
-
903
- }
904
-
905
- /** Get themes by subscription type */
906
- protected function installer_theme_get_themes_by_subscription( $subscription_type, $repo ) {
907
-
908
- $themes_associated_with_subscription = array();
909
- if ( isset(WP_Installer()->settings['repositories'][$repo]['data']['packages']) ) {
910
- //Set
911
- $packages = WP_Installer()->settings['repositories'][$repo]['data']['packages'];
912
- $available_themes_subscription = array();
913
- foreach ( $packages as $package_id => $package_details ) {
914
- if ( isset($package_details['products']) ) {
915
- $the_products = $package_details['products'];
916
- foreach ( $the_products as $product_slug => $product_details ) {
917
- if ( isset($product_details['subscription_type']) ) {
918
- $subscription_type_from_settings = intval( $product_details['subscription_type'] );
919
- if ( $subscription_type_from_settings == $subscription_type ) {
920
- //We found the subscription
921
- if ( isset($product_details['themes']) ) {
922
- $themes_associated_with_subscription = $product_details['themes'];
923
- return $themes_associated_with_subscription;
924
- }
925
- }
926
- }
927
-
928
- }
929
- }
930
- }
931
- }
932
- return $themes_associated_with_subscription;
933
- }
934
-
935
- /** Filter API theme response according to user subscription */
936
- public function installer_theme_filter_themes_by_subscription( $themes, $active_tab ) {
937
-
938
- //Step1, we only filter OTGS themes
939
- $orig = count( $themes );
940
- if ( in_array( $active_tab, $this->theme_repo ) ) {
941
- //OTGS Theme
942
- //Step2, we retrieved the available themes based on client subscription
943
- if ( isset($this->installer_themes[$active_tab]) ) {
944
- $available_themes = $this->installer_themes[$active_tab];
945
- //Step3, we filter $themes based on this info
946
- if ( (is_array( $themes )) && (!(empty($themes))) ) {
947
- foreach ( $themes as $k => $theme ) {
948
- //Step4, get theme slug
949
- if ( isset($theme['slug']) ) {
950
- $theme_slug = $theme['slug'];
951
- if ( !(empty($theme_slug)) ) {
952
- if ( !(in_array( $theme_slug, $available_themes )) ) {
953
- //This theme is not in available themes
954
- unset($themes[$k]);
955
- }
956
- }
957
- }
958
- }
959
- }
960
- }
961
- }
962
- $new = count( $themes );
963
- if ( $orig != $new ) {
964
- //It is filtered
965
- $themes = array_values( $themes );
966
- }
967
-
968
- return $themes;
969
- }
970
-
971
- /** Hook to wp_loaded, fires when all Installer theme class is ready */
972
- public function installer_themes_support_set_up_func() {
973
- do_action( 'installer_themes_support_set_up' );
974
- }
975
-
976
- }
977
-
978
- /** Instantiate Installer Theme Class */
979
  new Installer_Theme_Class;
1
+ <?php
2
+ /**
3
+ * Installer Class for Theme Support
4
+ *
5
+ * Supports automatic updates and installation of Toolset/WPML Themes
6
+ *
7
+ * @class Installer_Theme_Class
8
+ * @version 1.6
9
+ * @category Class
10
+ * @author OnTheGoSystems
11
+ */
12
+
13
+ if ( !defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ /**
18
+ * Installer_Theme_Class
19
+ */
20
+ class Installer_Theme_Class {
21
+
22
+ /** Theme Repository */
23
+ private $theme_repo;
24
+
25
+ /** Repository API */
26
+ private $repository_api;
27
+
28
+ /** Repository Theme Products */
29
+ private $repository_theme_products;
30
+
31
+ /** Site URL */
32
+ private $installer_site_url;
33
+
34
+ /** Site Key */
35
+ private $installer_site_key;
36
+
37
+ /** The Themes Option */
38
+ protected $installer_themes_option;
39
+
40
+ /** Update settings */
41
+ protected $installer_themes_available_updates;
42
+
43
+ /** The Themes */
44
+ protected $installer_themes = array();
45
+
46
+ /** Repository with themes */
47
+ protected $installer_repo_with_themes;
48
+
49
+ /** Active tab */
50
+ protected $installer_theme_active_tab;
51
+
52
+ /** Theme user registration */
53
+ protected $theme_user_registration;
54
+
55
+ /** Client active subscription */
56
+ protected $installer_theme_subscription_type;
57
+
58
+ public function __construct() {
59
+
60
+ /** Properties */
61
+
62
+ //Get installer repositories
63
+ $installer_repositories = WP_Installer()->get_repositories();
64
+
65
+ //Get repos with themes
66
+ $repos_with_themes = $this->installer_theme_reposities_that_has_themes( $installer_repositories );
67
+
68
+ if ( is_array( $repos_with_themes ) ) {
69
+ //Assign to property
70
+ $this->installer_repo_with_themes = $repos_with_themes;
71
+
72
+ //Let's looped through repos with themes
73
+ foreach ( $repos_with_themes as $k => $repo ) {
74
+
75
+ //$repo could be 'toolset' or 'wpml'
76
+ //Assign each repo with theme to property
77
+ $this->theme_repo[] = $repo;
78
+
79
+ if ( (isset($installer_repositories[$repo]['api-url'])) && (isset($installer_repositories[$repo]['products'])) ) {
80
+
81
+ //Define the rest of the properties based on the given repo
82
+ $this->repository_api[$repo] = $installer_repositories[$repo]['api-url'];
83
+ $this->repository_theme_products[$repo] = $installer_repositories[$repo]['products'];
84
+ $this->installer_site_url[$repo] = WP_Installer()->get_installer_site_url( $repo );
85
+ $this->installer_site_key[$repo] = WP_Installer()->get_site_key( $repo );
86
+ $this->theme_user_registration[$repo] = false;
87
+
88
+ if ( WP_Installer()->repository_has_valid_subscription( $repo ) ) {
89
+
90
+ $this->installer_theme_subscription_type = WP_Installer()->get_subscription_type_for_repository( $repo );
91
+ $this->installer_themes_option[$repo] = 'wp_installer_' . $repo . '_themes';
92
+ $this->installer_themes_available_updates[$repo] = 'wp_installer_' . $repo . '_updated_themes';
93
+ $this->installer_theme_active_tab = '';
94
+
95
+ //We only set themes available to this validated subscription
96
+ $this->installer_theme_available( $repo, $this->installer_theme_subscription_type );
97
+
98
+ add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_sets_active_tab_on_init'), 10 );
99
+ $this->theme_user_registration[$repo] = true;
100
+ }
101
+
102
+ /** We are ready.. let's initialize .... */
103
+ $this->init();
104
+ }
105
+ }
106
+ add_action( 'installer_themes_support_set_up', array($this, 'installer_theme_loaded_hooks') );
107
+ }
108
+ }
109
+
110
+ /** Init */
111
+ public function init() {
112
+ add_action( 'admin_enqueue_scripts', array($this, 'installer_theme_enqueue_scripts') );
113
+ add_filter( 'themes_api', array($this, 'installer_theme_api_override'), 10, 3 );
114
+ add_filter( 'themes_api_result', array($this, 'installer_theme_api_override_response'), 10, 3 );
115
+ add_filter( 'site_transient_update_themes', array($this, 'installer_theme_upgrade_check'), 10, 1 );
116
+ add_action( 'http_api_debug', array($this, 'installer_theme_sync_native_wp_api'), 10, 5 );
117
+ add_filter( 'installer_theme_hook_response_theme', array($this, 'installer_theme_add_num_ratings'), 10, 1 );
118
+ add_filter( 'themes_update_check_locales', array($this, 'installer_theme_sync_call_wp_theme_api'), 10, 1 );
119
+ add_filter( 'admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 3 );
120
+ add_filter( 'network_admin_url', array($this, 'installer_theme_add_query_arg_tab'), 10, 2 );
121
+ add_action( 'wp_ajax_installer_theme_frontend_selected_tab', array($this, 'installer_theme_frontend_selected_tab'), 0 );
122
+ add_action( 'wp_loaded', array($this, 'installer_themes_support_set_up_func') );
123
+ }
124
+
125
+ /** Enqueue scripts */
126
+ public function installer_theme_enqueue_scripts() {
127
+ $current_screen = $this->installer_theme_current_screen();
128
+ $commercial_plugin_screen = $this->installer_theme_is_commercial_plugin_screen( $current_screen );
129
+ if ( ('theme-install' == $current_screen) || ($commercial_plugin_screen) || ('theme-install-network' == $current_screen) ) {
130
+ $repo_with_themes = $this->installer_repo_with_themes;
131
+ $js_array = array();
132
+ if ( is_array( $repo_with_themes ) ) {
133
+ foreach ( $repo_with_themes as $k => $v ) {
134
+
135
+ //Hyperlink text
136
+ $theme_repo_name = $this->installer_theme_get_repo_product_name( $v );
137
+ $the_hyperlink_text = esc_js( $theme_repo_name );
138
+
139
+ if ( is_multisite() ) {
140
+ $admin_url_passed = network_admin_url();
141
+ } else {
142
+ $admin_url_passed = admin_url();
143
+ }
144
+
145
+ //Define
146
+ $js_array[$v] = array(
147
+ 'the_hyperlink_text' => $the_hyperlink_text,
148
+ 'registration_status' => $this->theme_user_registration[$v],
149
+ 'is_commercial_plugin_tab' => $commercial_plugin_screen,
150
+ 'registration_url' => $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $v
151
+ );
152
+
153
+ }
154
+ }
155
+
156
+ if ( !(empty($js_array)) ) {
157
+ wp_enqueue_script( 'installer-theme-install', WP_Installer()->res_url() . '/res/js/installer_theme_install.js', array('jquery', 'installer-admin'), WP_Installer()->version() );
158
+ $installer_ajax_url = admin_url( 'admin-ajax.php' );
159
+
160
+ if ( is_ssl() ) {
161
+ $installer_ajax_url = str_replace( 'http://', 'https://', $installer_ajax_url );
162
+ } else {
163
+ $installer_ajax_url = str_replace( 'https://', 'http://', $installer_ajax_url );
164
+ }
165
+
166
+ //Case where user is subscribed to a subscription that does not have themes
167
+ $subscription_js_check = $this->installer_theme_subscription_does_not_have_theme( $js_array );
168
+
169
+ wp_localize_script( 'installer-theme-install', 'installer_theme_install_localize',
170
+ array(
171
+ 'js_array_installer' => $js_array,
172
+ 'ajaxurl' => $installer_ajax_url,
173
+ 'no_associated_themes' => $subscription_js_check,
174
+ 'installer_theme_frontend_selected_tab_nonce' => wp_create_nonce( 'installer_theme_frontend_selected_tab' )
175
+ )
176
+ );
177
+ }
178
+ }
179
+ }
180
+
181
+ /** Case where user is subscribed to a subscription that does not have themes */
182
+ protected function installer_theme_subscription_does_not_have_theme( $js_array ) {
183
+
184
+ $any_subscription_has_theme = array();
185
+ $number_of_registrations = array();
186
+
187
+ //Step1, we looped through JS array
188
+ foreach ( $js_array as $repo_slug => $js_details ) {
189
+
190
+ //Step2, checked if user is registered
191
+ if ( isset($this->theme_user_registration[$repo_slug]) ) {
192
+ $registration_status = $this->theme_user_registration[$repo_slug];
193
+ if ( $registration_status ) {
194
+
195
+ //Registered
196
+ $number_of_registrations[] = $repo_slug;
197
+
198
+ //Step3, we checked if the $repo_slug has available theme
199
+ $themes_available = false;
200
+ if ( isset($this->installer_themes[$repo_slug]) ) {
201
+ $themes_available = $this->installer_themes[$repo_slug];
202
+ if ( !(empty($themes_available)) ) {
203
+ //This subscription has theme
204
+ $themes_available = true;
205
+ }
206
+ }
207
+
208
+ if ( $themes_available ) {
209
+ $any_subscription_has_theme[] = $repo_slug;
210
+ }
211
+ }
212
+ }
213
+
214
+ }
215
+
216
+ //Step4, we are done looping, check if there are any repos that have themes
217
+ if ( empty($registration_status) ) {
218
+
219
+ //No registration on any repos
220
+ return FALSE;
221
+
222
+ } elseif ( !(empty($registration_status)) ) {
223
+
224
+ //Has some registration on some repos
225
+ //We then checked if this user has any active subscriptions
226
+ if ( empty($any_subscription_has_theme) ) {
227
+ //No subscription
228
+ return TRUE;
229
+ } else {
230
+ //Has subscription found
231
+ return FALSE;
232
+ }
233
+ }
234
+ }
235
+
236
+ /** Check if its the commercial plugin screen */
237
+ private function installer_theme_is_commercial_plugin_screen( $current_screen ) {
238
+ $commercial = false;
239
+ if ( ('plugin-install' == $current_screen) || ('plugin-install-network' == $current_screen) ) {
240
+ if ( isset($_GET['tab']) ) {
241
+ $tab = $_GET['tab'];
242
+ if ( 'commercial' == $tab ) {
243
+ $commercial = true;
244
+ }
245
+ }
246
+ }
247
+ return $commercial;
248
+ }
249
+
250
+ /** Current screen */
251
+ private function installer_theme_current_screen() {
252
+
253
+ $current_screen_loaded = false;
254
+
255
+ if ( function_exists( 'get_current_screen' ) ) {
256
+
257
+ $screen_output = get_current_screen();
258
+ $current_screen_loaded = $screen_output->id;
259
+
260
+ }
261
+
262
+ return $current_screen_loaded;
263
+
264
+ }
265
+
266
+ /** Override WordPress Themes API */
267
+ public function installer_theme_api_override( $api_boolean, $action, $args ) {
268
+
269
+ //Let's checked if user is browsing our themes
270
+ if ( isset($args->browse) ) {
271
+ $browse = $args->browse;
272
+ if ( in_array( $browse, $this->theme_repo ) ) {
273
+ //Uniquely validated for our Themes
274
+ if ( 'query_themes' == $action ) {
275
+ //User is querying or asking information about our themes, let's override
276
+ $api_boolean = true;
277
+ }
278
+ }
279
+ } elseif ( isset($args->slug) ) {
280
+ //We are installing our themes
281
+ $theme_to_install = $args->slug;
282
+
283
+ //Lets uniquely validate if this belongs to us
284
+ //Check if this is OTGS theme
285
+ $validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
286
+ if ( $validate_check ) {
287
+ //Belongs to us
288
+ if ( !(empty($theme_to_install)) ) {
289
+ $api_boolean = true;
290
+ }
291
+ }
292
+ }
293
+
294
+ return $api_boolean;
295
+ }
296
+
297
+ /** Override WordPress Themes API response with our own themes API*/
298
+ public function installer_theme_api_override_response( $res, $action, $args ) {
299
+
300
+ if ( true === $res ) {
301
+ if ( isset($args->browse) ) {
302
+ $browse = $args->browse;
303
+ if ( in_array( $browse, $this->theme_repo ) ) {
304
+ //Uniquely validated for our themes
305
+ if ( 'query_themes' == $action ) {
306
+ //Client querying OTGS themes
307
+ //Check for registration status
308
+ if ( isset($this->theme_user_registration[$browse]) ) {
309
+ //Set
310
+ if ( !($this->theme_user_registration[$browse]) ) {
311
+ //Not registered yet
312
+ $res = new stdClass();
313
+ $res->info = array();
314
+ $res->themes = array();
315
+ return $res;
316
+ } else {
317
+ //Registered
318
+ $themes = $this->installer_theme_get_themes( '', $browse );
319
+ $res = $this->installer_theme_format_response( $themes, $action );
320
+ }
321
+ }
322
+ }
323
+ }
324
+ } elseif ( isset($args->slug) ) {
325
+ //We are installing theme
326
+ //Lets uniquely validate if this belongs to our theme
327
+ $theme_to_install = $args->slug;
328
+
329
+ //Lets uniquely validate if this belongs to us
330
+ //Check if this is OTGS theme
331
+ $validate_check = $this->installer_themes_belong_to_us( $theme_to_install );
332
+ if ( $validate_check ) {
333
+ //Belongs to us
334
+ if ( ($res) && ('theme_information' == $action) ) {
335
+ $themes = $this->installer_theme_get_themes( '', $this->installer_theme_active_tab );
336
+ $res = $this->installer_theme_format_response( $themes, $action, $args->slug );
337
+ }
338
+ }
339
+ }
340
+ return $res;
341
+ } else {
342
+ //Default WP Themes here
343
+ $client_side_active_tab = get_option( 'wp_installer_clientside_active_tab' );
344
+ if ( $client_side_active_tab ) {
345
+ if ( !(in_array( $client_side_active_tab, $this->theme_repo )) ) {
346
+ //Not OTGS tab
347
+ return $res;
348
+ }
349
+ }
350
+
351
+ }
352
+ }
353
+
354
+ /** Get Themes */
355
+ private function installer_theme_get_themes( $product_url = '', $repo_source = '' ) {
356
+
357
+ //Query API
358
+ if ( empty($product_url) ) {
359
+ //Not set
360
+ if ( isset($this->repository_theme_products[$this->installer_theme_active_tab]) ) {
361
+ $query_remote_url = $this->repository_theme_products[$this->installer_theme_active_tab];
362
+ }
363
+
364
+ } else {
365
+ $query_remote_url = $product_url;
366
+ }
367
+
368
+ //Let's retrieved current installer settings so we won't be querying all the time
369
+ $current_installer_settings = WP_Installer()->get_settings();
370
+
371
+ //Set $themes to FALSE by default
372
+ $themes = false;
373
+
374
+ if ( (is_array( $current_installer_settings )) && (!(empty($current_installer_settings))) ) {
375
+
376
+ //Set and already defined, retrieved $products
377
+ if ( isset($current_installer_settings['repositories'][$repo_source]['data']) ) {
378
+ $products = $current_installer_settings['repositories'][$repo_source]['data'];
379
+ if ( isset($products['downloads']['themes']) ) {
380
+ $themes = $products['downloads']['themes'];
381
+ }
382
+ }
383
+
384
+ } else {
385
+
386
+ //Call API
387
+ $response = wp_remote_get( $query_remote_url );
388
+
389
+ if ( is_wp_error( $response ) ) {
390
+ //Error detected: http fallback
391
+ $query_remote_url = preg_replace( "@^https://@", 'http://', $query_remote_url );
392
+ $response = wp_remote_get( $query_remote_url );
393
+ }
394
+
395
+ if ( !(is_wp_error( $response )) ) {
396
+ //Not WP error
397
+ //Evaluate response
398
+ if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
399
+ //In this case, response is set and defined, proceed...
400
+ $body = wp_remote_retrieve_body( $response );
401
+ if ( $body ) {
402
+ $products = json_decode( $body, true );
403
+ if ( isset($products['downloads']['themes']) ) {
404
+ $themes = $products['downloads']['themes'];
405
+ }
406
+ }
407
+
408
+ }
409
+ }
410
+ }
411
+
412
+ //Return themes, can be filtered by user subscription type
413
+ return apply_filters( 'installer_theme_get_themes', $themes, $this->installer_theme_active_tab );
414
+ }
415
+
416
+ /** Format response in compatibility with WordPress Theme API response */
417
+ private function installer_theme_format_response( $themes, $action, $slug = '' ) {
418
+
419
+ //Let's append download link only when retrieving theme information for installation
420
+ if ( ('theme_information' == $action) && (!(empty($slug))) ) {
421
+
422
+ //Only return one result -> the theme to be installed
423
+ foreach ( $themes as $k => $theme ) {
424
+ if ( $slug == $theme['basename'] ) {
425
+ $theme['download_link'] = WP_Installer()->append_site_key_to_download_url( $theme['url'], $this->installer_site_key[$this->installer_theme_active_tab], $this->installer_theme_active_tab );
426
+ $theme = json_decode( json_encode( $theme ), FALSE );
427
+ return $theme;
428
+ }
429
+ }
430
+
431
+ } else {
432
+
433
+ $res = new stdClass();
434
+ $res->info = array();
435
+ $res->themes = array();
436
+
437
+ //Define info
438
+ $res->info['page'] = 1;
439
+ $res->info['pages'] = 10;
440
+
441
+ //Let's count available themes ;
442
+ $res->info['results'] = count( $themes );
443
+
444
+ //Let's saved themes for easy access later on
445
+ $this->installer_theme_savethemes_by_slug( $themes );
446
+
447
+ //Let's defined available themes
448
+ if ( isset($this->installer_theme_subscription_type) ) {
449
+ //Has subscription type defined, let's saved what is associated with this subscription
450
+ $this->installer_theme_available( $this->installer_theme_active_tab, $this->installer_theme_subscription_type );
451
+ } else {
452
+ $this->installer_theme_available( $this->installer_theme_active_tab );
453
+ }
454
+
455
+ //Let's add themes to the overriden WordPress API Theme response
456
+ /** Installer 1.7.6: Update to compatible data format response from WP Theme API */
457
+ $theme_compatible_array=array();
458
+ if ((is_array($themes))) {
459
+ foreach ($themes as $k=>$v) {
460
+ $theme_compatible_array[]=(object)($v);
461
+ }
462
+ }
463
+ $res->themes = $theme_compatible_array;
464
+ $res->themes = apply_filters( 'installer_theme_hook_response_theme', $res->themes );
465
+ return $res;
466
+ }
467
+ }
468
+
469
+ /** Let's save all available themes by its slug after any latest API query */
470
+ private function installer_theme_savethemes_by_slug( $themes, $doing_query = false ) {
471
+
472
+ if ( !($doing_query) ) {
473
+ $this->installer_themes[$this->installer_theme_active_tab] = array();
474
+ }
475
+
476
+ if ( !(empty($themes)) ) {
477
+ $themes_for_saving = array();
478
+ foreach ( $themes as $k => $theme ) {
479
+ if ( !($doing_query) ) {
480
+ if ( isset($theme['slug']) ) {
481
+ $theme_slug = $theme['slug'];
482
+ if ( !(empty($theme_slug)) ) {
483
+ $themes_for_saving[] = $theme_slug;
484
+ }
485
+ }
486
+ } else {
487
+
488
+ if ( ((isset($theme['slug'])) && (isset($theme['version'])) &&
489
+ (isset($theme['theme_page_url']))) && (isset($theme['url']))
490
+ ) {
491
+ $theme_slug = $theme['slug'];
492
+ $theme_version = $theme['version'];
493
+ $theme_page_url = $theme['theme_page_url'];
494
+ $theme_url = $theme['url'];
495
+ if ( (!(empty($theme_slug))) && (!(empty($theme_version))) &&
496
+ (!(empty($theme_page_url))) && (!(empty($theme_url)))
497
+ ) {
498
+ //$theme_slug is unique for every theme
499
+ $themes_for_saving[$theme_slug] = array(
500
+ 'version' => $theme_version,
501
+ 'theme_page_url' => $theme_page_url,
502
+ 'url' => $theme_url
503
+ );
504
+
505
+ }
506
+ }
507
+ }
508
+
509
+ }
510
+
511
+ if ( !(empty($themes_for_saving)) ) {
512
+ //Has themes for saving
513
+ if ( !($doing_query) ) {
514
+ //Not doing query
515
+ $existing_themes = get_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
516
+ if ( !($existing_themes) ) {
517
+ //Does not yet exists
518
+ delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
519
+ update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
520
+ } else {
521
+ //exists, check if we need to update
522
+ if ( $existing_themes == $themes_for_saving ) {
523
+ //Equal, no need to update here
524
+ } else {
525
+ //Update
526
+ delete_option( $this->installer_themes_option[$this->installer_theme_active_tab] );
527
+ update_option( $this->installer_themes_option[$this->installer_theme_active_tab], $themes_for_saving );
528
+ }
529
+ }
530
+ } else {
531
+ //Used for query purposes only, don't save anything
532
+ return $themes_for_saving;
533
+ }
534
+ }
535
+ }
536
+ }
537
+
538
+ /** Available themes */
539
+ private function installer_theme_available( $repo, $subscription_type = '' ) {
540
+
541
+ $subscription_type = intval( $subscription_type );
542
+ if ( $subscription_type > 0 ) {
543
+
544
+ //Here we have a case of validated subscription
545
+ //We need to set themes that is available to this subscription
546
+ $themes_associated_with_subscription = $this->installer_themes[$repo] = $this->installer_theme_get_themes_by_subscription( $subscription_type, $repo );
547
+ if ( !(empty($themes_associated_with_subscription)) ) {
548
+ //Has themes
549
+ $this->installer_themes[$repo] = $themes_associated_with_subscription;
550
+ }
551
+ } else {
552
+
553
+ //Get themes
554
+ $this->installer_themes[$repo] = get_option( $this->installer_themes_option[$repo] );
555
+ }
556
+ }
557
+
558
+ /** Theme upgrade check */
559
+ public function installer_theme_upgrade_check( $the_value ) {
560
+
561
+ //Step1: Let's looped through repos with themes and check if we have updates available for them.
562
+ if ( (is_array( $this->installer_repo_with_themes )) && (!(empty($this->installer_repo_with_themes))) ) {
563
+ foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
564
+ //Step2: Let's checked if we have update for this theme
565
+ $update_available = get_option( $this->installer_themes_available_updates[$repo_slug] );
566
+ if ( $update_available ) {
567
+ if ( (is_array( $update_available )) && (!(empty($update_available))) ) {
568
+ //Has updates available coming from this specific theme repo
569
+ //Let's loop through the themes that needs update
570
+ foreach ( $update_available as $theme_slug => $v ) {
571
+ //Add to response API
572
+ $the_value->response [$theme_slug] = array(
573
+ 'theme' => $theme_slug,
574
+ 'new_version' => $v['new_version'],
575
+ 'url' => $v['url'],
576
+ 'package' => $v['package']
577
+ );
578
+ }
579
+ }
580
+ }
581
+ }
582
+ }
583
+ //Return
584
+ return $the_value;
585
+ }
586
+
587
+ /** Return repositories that has themes */
588
+ private function installer_theme_reposities_that_has_themes( $repositories, $ret_value = true, $doing_api_query = false ) {
589
+
590
+ $repositories_with_themes = array();
591
+
592
+ if ( (is_array( $repositories )) && (!(empty($repositories))) ) {
593
+
594
+ //Let's checked if we have something before
595
+ $themes = get_option( 'installer_repositories_with_theme' );
596
+
597
+ if ( (!($themes)) || ($doing_api_query) ) {
598
+ //Not yet defined
599
+ //Loop through each repositories and check whether they have themes
600
+ foreach ( $repositories as $k => $v ) {
601
+ if ( isset($v['products']) ) {
602
+ $products_url = $v['products'];
603
+ $themes = $this->installer_theme_get_themes( $products_url, $k );
604
+ if ( (is_array( $themes )) && (!(empty($themes))) ) {
605
+ //Repo has themes
606
+ $repositories_with_themes[] = $k;
607
+ }
608
+ }
609
+ }
610
+ } else {
611
+ //Already set
612
+ $repositories_with_themes = $themes;
613
+ }
614
+
615
+ if ( (((is_array( $repositories_with_themes )) && (!(empty($repositories_with_themes)))) && (!($themes))) || ($doing_api_query) ) {
616
+ //Save to db
617
+ update_option( 'installer_repositories_with_theme', $repositories_with_themes );
618
+ }
619
+ }
620
+
621
+ if ( $ret_value ) {
622
+ return $repositories_with_themes;
623
+ }
624
+
625
+ }
626
+
627
+ /** When WordPress queries its own Themes API, we sync with our own */
628
+ public function installer_theme_sync_native_wp_api( $response, $responsetext, $class, $args, $url ) {
629
+
630
+ $api_native_string = 'api.wordpress.org/themes/';
631
+ if ( (strpos( $url, $api_native_string ) !== false) ) {
632
+ //WordPress is querying its own themes API
633
+ $installer_repositories = WP_Installer()->get_repositories();
634
+
635
+ //Query our own API and update repository values too
636
+ $this->installer_theme_reposities_that_has_themes( $installer_repositories, false, true );
637
+ }
638
+ }
639
+
640
+ /** Returns product name by theme repo slug */
641
+ private function installer_theme_get_repo_product_name( $theme_repo ) {
642
+
643
+ $theme_repo_name = false;
644
+
645
+ if ( isset(WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name']) ) {
646
+ //Set
647
+ $prod_name = WP_Installer()->settings['repositories'][$theme_repo]['data']['product-name'];
648
+ if ( !(empty($prod_name)) ) {
649
+ $theme_repo_name = $prod_name;
650
+ }
651
+ } else {
652
+ //Not yet
653
+ if ( $theme_repo == $this->theme_repo ) {
654
+ $result = $this->installer_theme_general_api_query();
655
+ if ( isset($result['product-name']) ) {
656
+ $product_name = $result['product-name'];
657
+ if ( !(empty($product_name)) ) {
658
+ $theme_repo_name = $product_name;
659
+ }
660
+ }
661
+ }
662
+ }
663
+
664
+ return $theme_repo_name;
665
+ }
666
+
667
+ /** General query API method, returns $products */
668
+ private function installer_theme_general_api_query() {
669
+ $products = false;
670
+ $response = wp_remote_get( $this->repository_theme_products );
671
+ if ( !(is_wp_error( $response )) ) {
672
+ //Not WP error
673
+ //Evaluate response
674
+ if ( $response && isset($response['response']['code']) && $response['response']['code'] == 200 ) {
675
+ //In this case, response is set and defined, proceed...
676
+ $body = wp_remote_retrieve_body( $response );
677
+ if ( $body ) {
678
+ $result = json_decode( $body, true );
679
+ if ( (is_array( $result )) && (!(empty($result))) ) {
680
+ $products = $result;
681
+ }
682
+ }
683
+
684
+ }
685
+ }
686
+
687
+ return $products;
688
+ }
689
+
690
+ /** General method to check if themes are OTGS themes based on its slug*/
691
+ private function installer_themes_belong_to_us( $theme_slug ) {
692
+
693
+ $found = false;
694
+ $theme_slug = trim( $theme_slug );
695
+
696
+ foreach ( $this->installer_themes as $repo_with_theme => $themes ) {
697
+ foreach ( $themes as $k => $otgs_theme_slug ) {
698
+ if ( $theme_slug == $otgs_theme_slug ) {
699
+ //match found! Theme belongs to otgs
700
+ return true;
701
+ }
702
+ }
703
+ }
704
+ return $found;
705
+
706
+ }
707
+
708
+ /** Sets active tab on init */
709
+ public function installer_theme_sets_active_tab_on_init() {
710
+
711
+ if ( isset ($_SERVER ['REQUEST_URI']) ) {
712
+ $request_uri = $_SERVER ['REQUEST_URI'];
713
+ if ( isset ($_GET ['browse']) ) {
714
+ $active_tab = trim( $_GET ['browse'] );
715
+ $this->installer_theme_active_tab = $active_tab;
716
+ } elseif ( isset ($_POST ['request'] ['browse']) ) {
717
+ $active_tab = trim( $_POST ['request'] ['browse'] );
718
+ $this->installer_theme_active_tab = $active_tab;
719
+ } elseif ( (isset ($_GET ['theme_repo'])) && (isset ($_GET ['action'])) ) {
720
+ $theme_repo = trim( $_GET ['theme_repo'] );
721
+ $the_action = trim( $_GET ['action'] );
722
+ if ( ('install-theme' == $the_action) && (!(empty($theme_repo))) ) {
723
+ $this->installer_theme_active_tab = $theme_repo;
724
+ }
725
+ } elseif ( wp_get_referer() ) {
726
+ $referer = wp_get_referer();
727
+ $parts = parse_url( $referer );
728
+ if ( isset($parts['query']) ) {
729
+ parse_str( $parts['query'], $query );
730
+ if ( isset($query['browse']) ) {
731
+ $this->installer_theme_active_tab = $query['browse'];
732
+ }
733
+ }
734
+ }
735
+ }
736
+ }
737
+
738
+ /** WP Theme API compatibility- added num ratings */
739
+ /** Installer 1.7.6+ Added updated 'rating' field */
740
+ public function installer_theme_add_num_ratings( $themes ) {
741
+
742
+ if ( (is_array( $themes )) && (!(empty($themes))) ) {
743
+ foreach ( $themes as $k => $v ) {
744
+ if ( !(isset($v->num_ratings)) ) {
745
+ $themes[$k]->num_ratings = 100;
746
+ }
747
+ if ( !(isset($v->rating)) ) {
748
+ $themes[$k]->rating = 100;
749
+ }
750
+ }
751
+ }
752
+
753
+ return $themes;
754
+ }
755
+
756
+ /** When WordPress.org makes a call to its repository, let's run our own upgrade checks too */
757
+ public function installer_theme_sync_call_wp_theme_api( $locales ) {
758
+
759
+ $this->installer_theme_upgrade_theme_check();
760
+
761
+ return $locales;
762
+ }
763
+
764
+ /** Upgrade theme check */
765
+ private function installer_theme_upgrade_theme_check() {
766
+
767
+ // Step1-> we get all installed themes in clients local themes directory
768
+ $installed_themes = wp_get_themes();
769
+
770
+ // Step2: We need to loop through each repository with themes
771
+ foreach ( $this->installer_repo_with_themes as $k => $repo_slug ) {
772
+
773
+ // We then need to retrieved the products URL for each of this repo
774
+ $products_url = $this->repository_theme_products [$repo_slug];
775
+
776
+ // Step3-> we get all available themes in our repository via API based on this URL
777
+ $available_themes = $this->installer_theme_get_themes( $products_url, $repo_slug );
778
+
779
+ if ( !($available_themes) ) {
780
+
781
+ // API is not available as of the moment, return..
782
+ return;
783
+ } else {
784
+
785
+ // We have available themes here...
786
+ // Step4->let's simplify available themes data by slugs
787
+ $simplified_available_themes = $this->installer_theme_savethemes_by_slug( $available_themes, true );
788
+
789
+ // Step5->Let's loop through installed themes
790
+ if ( (is_array( $installed_themes )) && (!(empty ($installed_themes))) ) {
791
+ $otgs_theme_updates_available = array();
792
+ foreach ( $installed_themes as $theme_slug => $theme_object ) {
793
+ if ( array_key_exists( $theme_slug, $simplified_available_themes ) ) {
794
+
795
+ // This is our theme
796
+ // Step6->Let's get version of the local theme installed
797
+ $local_version = $theme_object->get( 'Version' );
798
+
799
+ // Step7->Let's get the latest version of this theme, page URL and download URL from our repository
800
+ $repository_version = $simplified_available_themes [$theme_slug] ['version'];
801
+ $theme_page_url = $simplified_available_themes [$theme_slug] ['theme_page_url'];
802
+ $theme_download_url = $simplified_available_themes [$theme_slug] ['url'];
803
+
804
+ // Step8->Let's compare the version
805
+ if ( version_compare( $repository_version, $local_version, '>' ) ) {
806
+
807
+ // Update available for this theme
808
+ // Step9-> Define download URL with site key
809
+ $package_url = WP_Installer()->append_site_key_to_download_url( $theme_download_url, $this->installer_site_key [$repo_slug], $repo_slug );
810
+
811
+ //Step10-> Assign to updates array for later accessing.
812
+ $otgs_theme_updates_available[$theme_slug] = array(
813
+ 'theme' => $theme_slug,
814
+ 'new_version' => $repository_version,
815
+ 'url' => $theme_page_url,
816
+ 'package' => $package_url
817
+ );
818
+ }
819
+ }
820
+ }
821
+ //Exited the upgrade loop for this specific theme repository
822
+ if ( !(empty($otgs_theme_updates_available)) ) {
823
+ //Has updates
824
+ update_option( $this->installer_themes_available_updates[$repo_slug], $otgs_theme_updates_available );
825
+ } else {
826
+ //No updates
827
+ delete_option( $this->installer_themes_available_updates[$repo_slug] );
828
+ }
829
+
830
+ }
831
+ }
832
+ }
833
+ }
834
+
835
+ /** When the user is on Themes install page OTG themes repository, let's the currently selected tab */
836
+ public function installer_theme_add_query_arg_tab( $url, $path, $blog_id = null ) {
837
+
838
+ $wp_install_string = 'update.php?action=install-theme';
839
+ if ( $path == $wp_install_string ) {
840
+ if ( isset($this->installer_theme_active_tab) ) {
841
+ if ( !(empty($this->installer_theme_active_tab)) ) {
842
+ $url = add_query_arg( array(
843
+ 'theme_repo' => $this->installer_theme_active_tab
844
+ ), $url );
845
+ }
846
+ }
847
+ }
848
+ return $url;
849
+ }
850
+
851
+ /** Save frontend theme tab selected */
852
+ public function installer_theme_frontend_selected_tab() {
853
+ if ( isset($_POST["frontend_tab_selected"]) ) {
854
+ check_ajax_referer( 'installer_theme_frontend_selected_tab', 'installer_theme_frontend_selected_tab_nonce' );
855
+
856
+ //Client_side_active_tab
857
+ $frontend_tab_selected = filter_input( INPUT_POST, 'frontend_tab_selected', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE );
858
+ if ( !(empty($frontend_tab_selected)) ) {
859
+ //Front end tab selected
860
+ update_option( 'wp_installer_clientside_active_tab', $frontend_tab_selected, false );
861
+
862
+ //Check for registration status
863
+ if ( isset($this->theme_user_registration[$frontend_tab_selected]) ) {
864
+ //Set
865
+ if ( !($this->theme_user_registration[$frontend_tab_selected]) ) {
866
+ //Not registered yet
867
+
868
+ if ( is_multisite() ) {
869
+ $admin_url_passed = network_admin_url();
870
+ } else {
871
+ $admin_url_passed = admin_url();
872
+ }
873
+
874
+ $registration_url = $admin_url_passed . 'plugin-install.php?tab=commercial#installer_repo_' . $frontend_tab_selected;
875
+
876
+ //Message and link
877
+ $theme_repo_name = $this->installer_theme_get_repo_product_name( $frontend_tab_selected );;
878
+ $response['unregistered_messages'] = sprintf( __( 'To install and update %s, please %sregister%s %s for this site.', 'installer' ),
879
+ $theme_repo_name, '<a href="' . $registration_url . '">', '</a>', $theme_repo_name );
880
+
881
+ }
882
+ }
883
+
884
+ $response['output'] = $frontend_tab_selected;
885
+ echo json_encode( $response );
886
+ }
887
+ die();
888
+ }
889
+ die();
890
+ }
891
+
892
+ /** Installer loaded aux hooks */
893
+ public function installer_theme_loaded_hooks() {
894
+
895
+ if ( isset($this->installer_theme_subscription_type) ) {
896
+ $subscription_type = intval( $this->installer_theme_subscription_type );
897
+ if ( $subscription_type > 0 ) {
898
+ //Client is subscribed
899
+ add_filter( 'installer_theme_get_themes', array($this, 'installer_theme_filter_themes_by_subscription'), 10, 2 );
900
+ }
901
+ }
902
+
903
+ }
904
+
905
+ /** Get themes by subscription type */
906
+ protected function installer_theme_get_themes_by_subscription( $subscription_type, $repo ) {
907
+
908
+ $themes_associated_with_subscription = array();
909
+ if ( isset(WP_Installer()->settings['repositories'][$repo]['data']['packages']) ) {
910
+ //Set
911
+ $packages = WP_Installer()->settings['repositories'][$repo]['data']['packages'];
912
+ $available_themes_subscription = array();
913
+ foreach ( $packages as $package_id => $package_details ) {
914
+ if ( isset($package_details['products']) ) {
915
+ $the_products = $package_details['products'];
916
+ foreach ( $the_products as $product_slug => $product_details ) {
917
+ if ( isset($product_details['subscription_type']) ) {
918
+ $subscription_type_from_settings = intval( $product_details['subscription_type'] );
919
+ if ( $subscription_type_from_settings == $subscription_type ) {
920
+ //We found the subscription
921
+ if ( isset($product_details['themes']) ) {
922
+ $themes_associated_with_subscription = $product_details['themes'];
923
+ return $themes_associated_with_subscription;
924
+ }
925
+ }
926
+ }
927
+
928
+ }
929
+ }
930
+ }
931
+ }
932
+ return $themes_associated_with_subscription;
933
+ }
934
+
935
+ /** Filter API theme response according to user subscription */
936
+ public function installer_theme_filter_themes_by_subscription( $themes, $active_tab ) {
937
+
938
+ //Step1, we only filter OTGS themes
939
+ $orig = count( $themes );
940
+ if ( in_array( $active_tab, $this->theme_repo ) ) {
941
+ //OTGS Theme
942
+ //Step2, we retrieved the available themes based on client subscription
943
+ if ( isset($this->installer_themes[$active_tab]) ) {
944
+ $available_themes = $this->installer_themes[$active_tab];
945
+ //Step3, we filter $themes based on this info
946
+ if ( (is_array( $themes )) && (!(empty($themes))) ) {
947
+ foreach ( $themes as $k => $theme ) {
948
+ //Step4, get theme slug
949
+ if ( isset($theme['slug']) ) {
950
+ $theme_slug = $theme['slug'];
951
+ if ( !(empty($theme_slug)) ) {
952
+ if ( !(in_array( $theme_slug, $available_themes )) ) {
953
+ //This theme is not in available themes
954
+ unset($themes[$k]);
955
+ }
956
+ }
957
+ }
958
+ }
959
+ }
960
+ }
961
+ }
962
+ $new = count( $themes );
963
+ if ( $orig != $new ) {
964
+ //It is filtered
965
+ $themes = array_values( $themes );
966
+ }
967
+
968
+ return $themes;
969
+ }
970
+
971
+ /** Hook to wp_loaded, fires when all Installer theme class is ready */
972
+ public function installer_themes_support_set_up_func() {
973
+ do_action( 'installer_themes_support_set_up' );
974
+ }
975
+
976
+ }
977
+
978
+ /** Instantiate Installer Theme Class */
979
  new Installer_Theme_Class;
embedded/otgs/installer/includes/installer-api.php CHANGED
@@ -1,116 +1,116 @@
1
- <?php
2
-
3
- class WP_Installer_API{
4
-
5
- public static function get_product_installer_link($repository_id, $package_id = false){
6
-
7
- $menu_url = WP_Installer()->menu_url();
8
-
9
- $url = $menu_url . '#' . $repository_id;
10
- if($package_id){
11
- $url .= '/' . $package_id;
12
- }
13
-
14
- return $url;
15
-
16
- }
17
-
18
- public static function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
19
-
20
- $price = WP_Installer()->get_product_price($repository_id, $package_id, $product_id, $incl_discount);
21
-
22
- return $price;
23
- }
24
-
25
- /**
26
- * Retrieve the preferred translation service.
27
- *
28
- * @since 1.6.5
29
- *
30
- * @param string The repository id (e.g. wpml)
31
- * @return string The translation service id
32
- */
33
- public static function get_preferred_ts($repository_id = 'wpml'){
34
-
35
- if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'])){
36
- return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'];
37
- }
38
-
39
- return false;
40
-
41
- }
42
-
43
- /**
44
- * Set the preferred translation service.
45
- *
46
- * @since 1.6.5
47
- *
48
- * @param string The translation service id
49
- * @param string The repository id (e.g. wpml)
50
- */
51
- public static function set_preferred_ts( $value, $repository_id = 'wpml' ){
52
-
53
- if( isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] ) ){
54
-
55
- WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $value;
56
-
57
- WP_Installer()->save_settings();
58
-
59
- }
60
-
61
- }
62
-
63
- /**
64
- * Retrieve the referring translation service (if any)
65
- *
66
- * @since 1.6.5
67
- *
68
- * @param string The repository id (e.g. wpml)
69
- * @return string The translation service id or false
70
- */
71
- public static function get_ts_referal($repository_id = 'wpml'){
72
-
73
- if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'])){
74
- return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'];
75
- }
76
-
77
- return false;
78
-
79
- }
80
-
81
- /**
82
- * Retrieve the translation services client id for a specific repository (if any)
83
- *
84
- * @since 1.7.9
85
- *
86
- * @param string The repository id (e.g. wpml)
87
- * @return string The client id or false
88
- */
89
- public static function get_ts_client_id( $repository_id = 'wpml' ){
90
-
91
- if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'])){
92
- return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'];
93
- }
94
-
95
- return false;
96
-
97
- }
98
-
99
- /**
100
- * Retrieve the site key corresponding to a repository.
101
- * This is a wrapper of WP_Installer::get_site_key()
102
- * @see WP_Installer::get_site_key()
103
- *
104
- * @since 1.7.9
105
- *
106
- * @param string The repository id (e.g. wpml)
107
- * @return string The site key (or false)
108
- */
109
- public static function get_site_key( $repository_id = 'wpml' ){
110
-
111
- return WP_Installer()->get_site_key( $repository_id );
112
-
113
- }
114
-
115
-
116
  }
1
+ <?php
2
+
3
+ class WP_Installer_API{
4
+
5
+ public static function get_product_installer_link($repository_id, $package_id = false){
6
+
7
+ $menu_url = WP_Installer()->menu_url();
8
+
9
+ $url = $menu_url . '#' . $repository_id;
10
+ if($package_id){
11
+ $url .= '/' . $package_id;
12
+ }
13
+
14
+ return $url;
15
+
16
+ }
17
+
18
+ public static function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
19
+
20
+ $price = WP_Installer()->get_product_price($repository_id, $package_id, $product_id, $incl_discount);
21
+
22
+ return $price;
23
+ }
24
+
25
+ /**
26
+ * Retrieve the preferred translation service.
27
+ *
28
+ * @since 1.6.5
29
+ *
30
+ * @param string The repository id (e.g. wpml)
31
+ * @return string The translation service id
32
+ */
33
+ public static function get_preferred_ts($repository_id = 'wpml'){
34
+
35
+ if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'])){
36
+ return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'];
37
+ }
38
+
39
+ return false;
40
+
41
+ }
42
+
43
+ /**
44
+ * Set the preferred translation service.
45
+ *
46
+ * @since 1.6.5
47
+ *
48
+ * @param string The translation service id
49
+ * @param string The repository id (e.g. wpml)
50
+ */
51
+ public static function set_preferred_ts( $value, $repository_id = 'wpml' ){
52
+
53
+ if( isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] ) ){
54
+
55
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $value;
56
+
57
+ WP_Installer()->save_settings();
58
+
59
+ }
60
+
61
+ }
62
+
63
+ /**
64
+ * Retrieve the referring translation service (if any)
65
+ *
66
+ * @since 1.6.5
67
+ *
68
+ * @param string The repository id (e.g. wpml)
69
+ * @return string The translation service id or false
70
+ */
71
+ public static function get_ts_referal($repository_id = 'wpml'){
72
+
73
+ if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'])){
74
+ return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'];
75
+ }
76
+
77
+ return false;
78
+
79
+ }
80
+
81
+ /**
82
+ * Retrieve the translation services client id for a specific repository (if any)
83
+ *
84
+ * @since 1.7.9
85
+ *
86
+ * @param string The repository id (e.g. wpml)
87
+ * @return string The client id or false
88
+ */
89
+ public static function get_ts_client_id( $repository_id = 'wpml' ){
90
+
91
+ if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'])){
92
+ return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'];
93
+ }
94
+
95
+ return false;
96
+
97
+ }
98
+
99
+ /**
100
+ * Retrieve the site key corresponding to a repository.
101
+ * This is a wrapper of WP_Installer::get_site_key()
102
+ * @see WP_Installer::get_site_key()
103
+ *
104
+ * @since 1.7.9
105
+ *
106
+ * @param string The repository id (e.g. wpml)
107
+ * @return string The site key (or false)
108
+ */
109
+ public static function get_site_key( $repository_id = 'wpml' ){
110
+
111
+ return WP_Installer()->get_site_key( $repository_id );
112
+
113
+ }
114
+
115
+
116
  }
embedded/otgs/installer/includes/installer-upgrader-skins.php CHANGED
@@ -1,37 +1,37 @@
1
- <?php
2
- class Installer_Upgrader_Skins extends WP_Upgrader_Skin{
3
-
4
- function __construct($args = array()){
5
- $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
6
- $this->options = wp_parse_args($args, $defaults);
7
- }
8
-
9
- function header(){
10
-
11
- }
12
-
13
- function footer(){
14
-
15
- }
16
-
17
- function error($error){
18
- $this->installer_error = $error;
19
- }
20
-
21
- function add_strings(){
22
-
23
- }
24
-
25
- function feedback($string){
26
-
27
- }
28
-
29
- function before(){
30
-
31
- }
32
-
33
- function after(){
34
-
35
- }
36
-
37
  }
1
+ <?php
2
+ class Installer_Upgrader_Skins extends WP_Upgrader_Skin{
3
+
4
+ function __construct($args = array()){
5
+ $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
6
+ $this->options = wp_parse_args($args, $defaults);
7
+ }
8
+
9
+ function header(){
10
+
11
+ }
12
+
13
+ function footer(){
14
+
15
+ }
16
+
17
+ function error($error){
18
+ $this->installer_error = $error;
19
+ }
20
+
21
+ function add_strings(){
22
+
23
+ }
24
+
25
+ function feedback($string){
26
+
27
+ }
28
+
29
+ function before(){
30
+
31
+ }
32
+
33
+ function after(){
34
+
35
+ }
36
+
37
  }
embedded/otgs/installer/includes/installer.class.php CHANGED
@@ -1,2559 +1,2560 @@
1
- <?php
2
-
3
- final class WP_Installer{
4
- protected static $_instance = null;
5
-
6
- public $settings = array();
7
-
8
- private $repositories = array();
9
-
10
- protected $api_debug = '';
11
-
12
- private $config = array();
13
-
14
- protected $_plugins_renew_warnings = array();
15
-
16
- protected $_gz_on = false;
17
-
18
- private $admin_messages = array();
19
-
20
- private $_using_icl = false;
21
- private $_wpml_version = false;
22
-
23
- private $package_source = array();
24
-
25
- const SITE_KEY_VALIDATION_SOURCE_OTHER = 0;
26
- const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_SPECIFIC = 1;
27
- const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT = 2;
28
- const SITE_KEY_VALIDATION_SOURCE_REGISTRATION = 3;
29
- const SITE_KEY_VALIDATION_SOURCE_REVALIDATION = 4;
30
- const SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK = 5;
31
-
32
- public $dependencies;
33
-
34
- public static function instance() {
35
-
36
- if ( is_null( self::$_instance ) ) {
37
- self::$_instance = new self();
38
- }
39
-
40
- return self::$_instance;
41
- }
42
-
43
- public function __construct(){
44
-
45
- if(!is_admin() || !is_user_logged_in()) return; //Only for admin
46
-
47
- $this->_gz_on = function_exists('gzuncompress') && function_exists('gzcompress');
48
- $this->settings = $this->get_settings();
49
-
50
- add_action('admin_notices', array($this, 'show_site_key_nags'));
51
-
52
- add_action('admin_notices', array($this, 'show_admin_messages'));
53
-
54
- add_action('admin_init', array($this, 'load_embedded_plugins'), 0);
55
-
56
- add_action('admin_menu', array($this, 'menu_setup'));
57
- add_action('network_admin_menu', array($this, 'menu_setup'));
58
-
59
- if(defined('DOING_AJAX') && isset($_POST['action']) && $_POST['action'] == 'installer_download_plugin'){
60
- add_filter( 'site_transient_update_plugins', array( $this, 'plugins_upgrade_check') );
61
- }
62
- add_filter('plugins_api', array( $this, 'custom_plugins_api_call'), 10, 3);
63
- add_filter('pre_set_site_transient_update_plugins', array( $this, 'plugins_upgrade_check'));
64
-
65
- // register repositories
66
- $this->load_repositories_list();
67
-
68
- if( empty($this->settings['last_repositories_update']) || time() - $this->settings['last_repositories_update'] > 86400
69
- || ( isset($_GET['force-check']) && $_GET['force-check'] == 1 ) ){
70
- $this->refresh_repositories_data();
71
- }
72
-
73
- // default config
74
- $this->config['plugins_install_tab'] = false;
75
-
76
- add_action('init', array($this, 'init'));
77
-
78
- //add_filter('wp_installer_buy_url', array($this, 'append_parameters_to_buy_url'));
79
-
80
- add_action('init', array($this,'load_locale'));
81
-
82
- }
83
-
84
- public function get_repositories() {
85
-
86
- return $this->repositories;
87
-
88
- }
89
-
90
- public function set_config($key, $value){
91
-
92
- $this->config[$key] = $value;
93
-
94
- }
95
-
96
- public function init(){
97
- global $pagenow;
98
-
99
- $this->dependencies = new Installer_Dependencies;
100
-
101
- if(empty($this->settings['_pre_1_0_clean_up'])) {
102
- $this->_pre_1_0_clean_up();
103
- }
104
-
105
- $this->settings = $this->_old_products_format_backwards_compatibility($this->settings);
106
-
107
- if ( !function_exists( 'get_plugins' ) ) {
108
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
109
- }
110
-
111
- $this->_using_icl = function_exists('wpml_site_uses_icl') && wpml_site_uses_icl();
112
- $this->_wpml_version = defined('ICL_SITEPRESS_VERSION') ? ICL_SITEPRESS_VERSION : '';
113
-
114
- wp_enqueue_script('installer-admin', $this->res_url() . '/res/js/admin.js', array('jquery'), $this->version());
115
- wp_enqueue_style('installer-admin', $this->res_url() . '/res/css/admin.css', array(), $this->version());
116
-
117
- $translation_array = array(
118
- 'installing' => __( 'Installing %s', 'installer' ),
119
- 'updating' => __( 'Updating %s', 'installer' ),
120
- 'activating' => __( 'Activating %s', 'installer' )
121
- );
122
-
123
- wp_localize_script( 'installer-admin', 'installer_strings', $translation_array );
124
-
125
- if($pagenow == 'plugins.php'){
126
- add_action('admin_notices', array($this, 'setup_plugins_page_notices'));
127
- add_action('admin_notices', array($this, 'setup_plugins_renew_warnings'), 10);
128
- add_action('admin_notices', array($this, 'queue_plugins_renew_warnings'), 20);
129
-
130
- add_action('admin_init', array($this, 'setup_plugins_action_links'));
131
-
132
- }
133
-
134
- if($this->is_repositories_page()){
135
- add_action('admin_init', array($this, 'validate_repository_subscription'));
136
- }
137
-
138
- if(defined('DOING_AJAX')){
139
- add_action('wp_ajax_save_site_key', array($this, 'save_site_key'));
140
- add_action('wp_ajax_remove_site_key', array($this, 'remove_site_key'));
141
- add_action('wp_ajax_update_site_key', array($this, 'update_site_key'));
142
-
143
- add_action('wp_ajax_installer_download_plugin', array($this, 'download_plugin_ajax_handler'));
144
- add_action('wp_ajax_installer_activate_plugin', array($this, 'activate_plugin'));
145
-
146
- add_action('wp_ajax_installer_dismiss_nag', array($this, 'dismiss_nag'));
147
- }
148
-
149
- if($pagenow == 'update.php'){
150
- if(isset($_GET['action']) && $_GET['action'] == 'update-selected'){
151
- add_action('admin_head', array($this, 'plugin_upgrade_custom_errors')); //iframe/bulk
152
- }else{
153
- add_action('all_admin_notices', array($this, 'plugin_upgrade_custom_errors')); //regular/singular
154
- }
155
- }
156
-
157
- // WP 4.2
158
- if(defined('DOING_AJAX')){
159
- add_action('wp_ajax_update-plugin', array($this, 'plugin_upgrade_custom_errors'), 0); // high priority, before WP
160
- }
161
-
162
- //Include theme support
163
- include_once $this->plugin_path() . '/includes/class-installer-theme.php';
164
-
165
- // Extra information about the source of Installer
166
- $package_source_file = $this->plugin_path() . '/installer-source.json';
167
- if( file_exists( $package_source_file ) ){
168
- $this->package_source = json_decode( file_get_contents( $package_source_file ) );
169
- }
170
- }
171
-
172
- protected function log($message){
173
- if( defined('WPML_INSTALLER_LOGGING') && WPML_INSTALLER_LOGGING ){
174
- if($fh = @fopen( $this->plugin_path() . '/installer.log', 'a' )){
175
- fwrite($fh, current_time( 'mysql' ) . "\t" . $message . "\n");
176
- }
177
- }
178
- }
179
-
180
- public function register_admin_message($text, $type = 'updated'){
181
- $this->admin_messages[] = array('text' => $text, 'type' => $type);
182
- }
183
-
184
- public function show_admin_messages(){
185
- if(!empty($this->admin_messages)){
186
- $types = array( 'error', 'updated', 'notice' );
187
- foreach($this->admin_messages as $message){
188
- $class = in_array( $message['type'], $types ) ? $message['type'] : 'updated';
189
- ?>
190
- <div class="<?php echo $class ?>">
191
- <p>
192
- <?php echo $message['text'] ?>
193
- </p>
194
- </div>
195
- <?php
196
- }
197
- }
198
- }
199
-
200
- public function load_locale(){
201
- $locale = get_locale();
202
- $locale = apply_filters( 'plugin_locale', $locale, 'installer' );
203
- $mo_file = $this->plugin_path() . '/locale/installer-' . $locale . '.mo';
204
- if(file_exists($mo_file)){
205
- load_textdomain( 'installer', $mo_file );
206
- }
207
- }
208
-
209
- public function load_embedded_plugins(){
210
- if(file_exists($this->plugin_path() . '/embedded-plugins' )) {
211
- include_once $this->plugin_path() . '/embedded-plugins/embedded-plugins.class.php';
212
- $this->installer_embedded_plugins = new Installer_Embedded_Plugins();
213
- }
214
- }
215
-
216
- public function menu_setup(){
217
- global $pagenow;
218
-
219
- if(is_multisite() && !is_network_admin()){
220
- $this->menu_multisite_redirect();
221
- add_options_page(__('Installer', 'installer'), __('Installer', 'installer'), 'manage_options', 'installer', array($this, 'show_products')) ;
222
- }else{
223
- if($this->config['plugins_install_tab'] && is_admin() && $pagenow == 'plugin-install.php'){
224
- // Default GUI, under Plugins -> Install
225
- add_filter('install_plugins_tabs', array($this, 'add_install_plugins_tab'));
226
- add_action('install_plugins_commercial', array($this, 'show_products'));
227
- }
228
- }
229
-
230
- }
231
-
232
- public function menu_url(){
233
- if(is_multisite()){
234
- if(is_network_admin()){
235
- $url = network_admin_url('plugin-install.php?tab=commercial');
236
- }else{
237
- $url = admin_url('options-general.php?page=installer');
238
- }
239
- }else{
240
- $url = admin_url('plugin-install.php?tab=commercial');
241
- }
242
- return $url;
243
- }
244
-
245
- private function menu_multisite_redirect(){
246
- global $pagenow;
247
-
248
- if($pagenow == 'plugin-install.php' && isset($_GET['tab']) && $_GET['tab'] == 'commercial'){
249
- wp_redirect($this->menu_url());
250
- exit;
251
- }
252
-
253
- }
254
-
255
- private function _pre_1_0_clean_up(){
256
- global $wpdb;
257
-
258
- if(!defined('WPRC_VERSION')){
259
- $old_tables = array(
260
- $wpdb->prefix . 'wprc_cached_requests',
261
- $wpdb->prefix . 'wprc_extension_types',
262
- $wpdb->prefix . 'wprc_extensions',
263
- $wpdb->prefix . 'wprc_repositories',
264
- $wpdb->prefix . 'wprc_repositories_relationships',
265
- );
266
-
267
- foreach($old_tables as $table){
268
- $wpdb->query(sprintf("DROP TABLE IF EXISTS %s", $table));
269
- }
270
-
271
- }
272
-
273
- $this->settings['_pre_1_0_clean_up'] = true;
274
- $this->save_settings();
275
- }
276
-
277
- public function setup_plugins_action_links(){
278
-
279
- $plugins = get_plugins();
280
-
281
- $repositories_plugins = array();
282
-
283
- if( !empty($this->settings['repositories']) ) {
284
-
285
- foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
286
-
287
- foreach ( $repository['data']['packages'] as $package ) {
288
-
289
- foreach ( $package['products'] as $product ) {
290
-
291
- foreach ( $product['plugins'] as $plugin_slug ) {
292
-
293
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
294
-
295
- if ( !isset($repositories_plugins[$repository_id][$download['slug']]) ) {
296
- $repositories_plugins[$repository_id][$download['slug']] = array(
297
- 'name' => $download['name'],
298
- 'registered' => $this->plugin_is_registered( $repository_id, $download['slug'] ) ? 1 : 0
299
- );
300
- }
301
-
302
- }
303
-
304
- }
305
-
306
- }
307
-
308
- foreach ( $plugins as $plugin_id => $plugin ) {
309
-
310
- $wp_plugin_slug = dirname( $plugin_id );
311
- if ( empty($wp_plugin_slug) ) {
312
- $wp_plugin_slug = basename( $plugin_id, '.php' );
313
- }
314
-
315
- foreach ( $repositories_plugins as $repository_id => $r_plugins ) {
316
-
317
- foreach ( $r_plugins as $slug => $r_plugin ) {
318
-
319
- if ( $wp_plugin_slug == $slug || $r_plugin['name'] == $plugin['Name'] || $r_plugin['name'] == $plugin['Title'] ) { //match order: slug, name, title
320
-
321
- if ( $r_plugin['registered'] ) {
322
- add_filter( 'plugin_action_links_' . $plugin_id, array($this, 'plugins_action_links_registered') );
323
- } else {
324
- add_filter( 'plugin_action_links_' . $plugin_id, array($this, 'plugins_action_links_not_registered') );
325
- }
326
-
327
- }
328
-
329
- }
330
-
331
- }
332
-
333
-
334
- }
335
-
336
- }
337
- }
338
-
339
- }
340
-
341
- public function plugins_action_links_registered($links){
342
- $links[] = '<a href="' . $this->menu_url() . '">' . __('Registered', 'installer') . '</a>';
343
- return $links;
344
- }
345
-
346
- public function plugins_action_links_not_registered($links){
347
- $links[] = '<a href="' . $this->menu_url() . '">' . __('Register', 'installer') . '</a>';
348
- return $links;
349
- }
350
-
351
- public function plugin_is_registered($repository_id, $slug){
352
-
353
- $registered = false;
354
-
355
- if( $this->repository_has_valid_subscription($repository_id) ){
356
-
357
- $subscription_type = $this->get_subscription_type_for_repository($repository_id);
358
- $r_plugins = array();
359
-
360
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
361
-
362
- foreach($package['products'] as $product){
363
-
364
- if( $product['subscription_type'] == $subscription_type || $this->have_superior_subscription($subscription_type, $product) ) {
365
-
366
- foreach ($product['plugins'] as $plugin_slug) {
367
-
368
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
369
-
370
- if (!isset($rep_plugins[$download['slug']])) {
371
- $r_plugins[$download['slug']] = $download['slug'];
372
- }
373
-
374
- }
375
-
376
- }
377
-
378
- }
379
-
380
- }
381
-
382
- $registered = isset($r_plugins[$slug]);
383
-
384
- }
385
-
386
-
387
- return $registered;
388
-
389
- }
390
-
391
- public function version(){
392
- return WP_INSTALLER_VERSION;
393
- }
394
-
395
- public function plugin_path() {
396
- return untrailingslashit( plugin_dir_path( dirname(__FILE__) ) );
397
- }
398
-
399
- public function plugin_url() {
400
- if(isset($this->config['in_theme_folder']) && !empty($this->config['in_theme_folder'])){
401
- $url = untrailingslashit(get_template_directory_uri() . '/' . $this->config['in_theme_folder']);
402
- }else{
403
- $url = untrailingslashit( plugins_url( '/', dirname(__FILE__) ) );
404
- }
405
-
406
- return $url;
407
- }
408
-
409
- public function is_repositories_page(){
410
- global $pagenow;
411
-
412
- return $pagenow == 'plugin-install.php' && isset($_GET['tab']) && $_GET['tab'] == 'commercial';
413
- }
414
-
415
- public function res_url(){
416
- if(isset($this->config['in_theme_folder']) && !empty($this->config['in_theme_folder'])){
417
- $url = untrailingslashit(get_template_directory_uri() . '/' . $this->config['in_theme_folder']);
418
- }else{
419
- $url = $this->plugin_url();
420
- }
421
- return $url;
422
- }
423
-
424
- public function save_settings(){
425
-
426
- $_settings = serialize($this->settings);
427
- if($this->_gz_on){
428
- $_settings = gzcompress($_settings);
429
- }
430
- $_settings = base64_encode($_settings);
431
-
432
- update_option( 'wp_installer_settings', $_settings );
433
-
434
- if( is_multisite() && is_main_site() && isset($this->settings['repositories']) ){
435
- $network_settings = array();
436
-
437
- foreach( $this->settings['repositories'] as $rep_id => $repository ){
438
- if( isset($repository['subscription']) )
439
- $network_settings[$rep_id] = $repository['subscription'];
440
- }
441
-
442
- update_site_option( 'wp_installer_network', $network_settings );
443
-
444
-
445
- }
446
-
447
- }
448
-
449
- public function get_settings($refresh = false){
450
-
451
- if($refresh || empty($this->settings)){
452
-
453
- $_settings = get_option('wp_installer_settings');
454
-
455
-
456
- if (is_array($_settings) || empty($_settings)) { //backward compatibility 1.1
457
- $this->settings = $_settings;
458
-
459
- } else {
460
- $_settings = base64_decode($_settings);
461
- if ($this->_gz_on) {
462
- $_settings = gzuncompress($_settings);
463
- }
464
- $this->settings = unserialize($_settings);
465
- }
466
-
467
- if (is_multisite() && isset($this->settings['repositories'])) {
468
- $network_settings = maybe_unserialize(get_site_option('wp_installer_network'));
469
- if ($network_settings) {
470
- foreach ($this->settings['repositories'] as $rep_id => $repository) {
471
- if (isset($network_settings[$rep_id])) {
472
- $this->settings['repositories'][$rep_id]['subscription'] = $network_settings[$rep_id];
473
- }
474
- }
475
- }
476
- }
477
-
478
-
479
- $this->settings = $this->_pre_1_6_backwards_compatibility($this->settings);
480
-
481
- $this->settings = $this->_old_products_format_backwards_compatibility($this->settings);
482
-
483
- }
484
-
485
-
486
- return $this->settings;
487
- }
488
-
489
- //backward compatibility, will remove 'basename' in version 1.8
490
- private function _pre_1_6_backwards_compatibility($settings){
491
-
492
- if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) ){
493
-
494
- foreach ($settings['repositories'] as $repository_id => $repository) {
495
-
496
- foreach ($repository['data']['downloads']['plugins'] as $slug => $download) {
497
-
498
- $settings['repositories'][$repository_id]['data']['downloads']['plugins'][$slug]['slug'] = $download['basename'];
499
-
500
- }
501
- }
502
-
503
- }
504
-
505
- return $settings;
506
-
507
- }
508
-
509
- //backward compatibility - support old products list format (downloads under products instead of global downloads list)
510
- private function _old_products_format_backwards_compatibility($settings){
511
-
512
- if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) && empty($this->_old_products_format_backwards_compatibility) ) {
513
-
514
- foreach ($settings['repositories'] as $repository_id => $repository) {
515
-
516
- $populate_downloads = false;
517
-
518
- foreach ($repository['data']['packages'] as $package_id => $package) {
519
-
520
- foreach ($package['products'] as $product_id => $product) {
521
-
522
- if (!isset($product['plugins'])) {
523
-
524
- $populate_downloads = true;
525
-
526
- foreach ($product['downloads'] as $download_id => $download) {
527
-
528
- $settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['plugins'][] = $download['slug'];
529
-
530
- }
531
-
532
- }
533
-
534
- }
535
-
536
- }
537
-
538
- if ($populate_downloads) {
539
-
540
- // Add downloads branch
541
- foreach ($repository['data']['packages'] as $package_id => $package) {
542
-
543
- foreach ($package['products'] as $product_id => $product) {
544
-
545
- foreach ($product['downloads'] as $download_id => $download) {
546
-
547
- if (!isset($settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']])) {
548
- $settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']] = $download;
549
- }
550
-
551
- $settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['plugins'][] = $download['slug'];
552
- }
553
-
554
- unset($settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['downloads']);
555
-
556
- }
557
-
558
- }
559
-
560
- }
561
-
562
- }
563
-
564
- $this->_old_products_format_backwards_compatibility = true;
565
-
566
- }
567
-
568
- return $settings;
569
-
570
- }
571
-
572
- public function get_installer_site_url( $repository_id = false ){
573
- global $current_site;
574
-
575
- $site_url = get_site_url();
576
-
577
- if( $repository_id && is_multisite() && isset( $this->settings['repositories'] ) ){
578
- $network_settings = maybe_unserialize( get_site_option('wp_installer_network') );
579
-
580
- if ( isset( $network_settings[$repository_id] ) ) {
581
- $site_url = get_site_url( $current_site->blog_id );
582
- }
583
-
584
- }
585
-
586
- return $site_url;
587
- }
588
-
589
- public function show_site_key_nags(){
590
- $screen = get_current_screen();
591
-
592
- if($screen->base == 'settings_page_installer' || ($screen->base == 'plugin-install' && isset($_GET['tab']) && $_GET['tab'] == 'commercial')){
593
- return;
594
- }
595
-
596
- if(!empty($this->config['site_key_nags'])){
597
-
598
- foreach($this->config['site_key_nags'] as $nag){
599
-
600
- if(!$this->repository_has_subscription($nag['repository_id'] )){
601
- $show = true;
602
- if(!empty($nag['condition_cb'])){
603
- $show = call_user_func($nag['condition_cb']);
604
- }
605
-
606
- if(empty($this->settings['dismissed_nags'][$nag['repository_id']]) && $show){
607
- echo '<div class="updated error otgs-is-dismissible"><p>';
608
- printf(__("To get automatic updates, you need to register %s for this site. %sRegister %s%s", 'sitepress'),
609
- $nag['product_name'], '<a class="button-primary" href="' . $this->menu_url() . '">', $nag['product_name'], '</a>');
610
-
611
- echo '</p>';
612
- echo '<span class="installer-dismiss-nag notice-dismiss" data-repository="' . $nag['repository_id'] . '"><span class="screen-reader-text">' . __('Dismiss', 'sitepress') . '</span></span>';
613
- echo '</div>';
614
- }
615
- }
616
-
617
- }
618
-
619
- }
620
-
621
- }
622
-
623
- public function dismiss_nag(){
624
- $this->settings['dismissed_nags'][$_POST['repository']] = 1;
625
-
626
- $this->save_settings();
627
-
628
- echo json_encode(array());
629
- exit;
630
- }
631
-
632
- public function add_install_plugins_tab($tabs){
633
-
634
- $tabs['commercial'] = __('Commercial', 'installer');
635
-
636
- return $tabs;
637
- }
638
-
639
- public function load_repositories_list(){
640
- global $wp_installer_instances;
641
-
642
- foreach ($wp_installer_instances as $instance) {
643
-
644
- if (file_exists(dirname($instance['bootfile']) . '/repositories.xml')) {
645
- $config_file = dirname($instance['bootfile']) . '/repositories.xml';
646
-
647
- if (file_exists(dirname($instance['bootfile']) . '/repositories.sandbox.xml')) {
648
- $config_file = dirname($instance['bootfile']) . '/repositories.sandbox.xml';
649
- add_filter('https_ssl_verify', '__return_false');
650
- }
651
-
652
- $repos = simplexml_load_file($config_file);
653
-
654
- if($repos) {
655
- foreach ($repos as $repo) {
656
- $id = strval($repo->id);
657
-
658
- $data['api-url'] = strval($repo->apiurl);
659
- $data['products'] = strval($repo->products);
660
-
661
- // excludes rule;
662
- if (isset($this->config['repositories_exclude']) && in_array($id, $this->config['repositories_exclude'])) {
663
- continue;
664
- }
665
-
666
- // includes rule;
667
- if (isset($this->config['repositories_include']) && !in_array($id, $this->config['repositories_include'])) {
668
- continue;
669
- }
670
-
671
- $this->repositories[$id] = $data;
672
-
673
- }
674
- }
675
-
676
- }
677
- }
678
-
679
- }
680
-
681
- public function filter_repositories_list(){
682
-
683
- if(!empty($this->settings['repositories'])) {
684
- foreach ($this->settings['repositories'] as $id => $repo_data) {
685
-
686
- // excludes rule;
687
- if (isset($this->config['repositories_exclude']) && in_array($id, $this->config['repositories_exclude'])) {
688
- unset($this->settings['repositories'][$id]);
689
- }
690
-
691
- // includes rule;
692
- if (isset($this->config['repositories_include']) && !in_array($id, $this->config['repositories_include'])) {
693
- unset($this->settings['repositories'][$id]);
694
- }
695
-
696
-
697
- }
698
- }
699
-
700
-
701
- }
702
-
703
- public function refresh_repositories_data(){
704
- static $checked = false;
705
-
706
- if( defined('OTGS_DISABLE_AUTO_UPDATES') && OTGS_DISABLE_AUTO_UPDATES && empty($_GET['force-check']) || $checked ){
707
-
708
- if(empty($this->settings['repositories']) && $this->is_repositories_page()){
709
-
710
- foreach($this->repositories as $id => $data) {
711
- $repository_names[] = $id;
712
-
713
- }
714
-
715
- $error = sprintf(__("Installer cannot display the products information because the automatic updating for %s was explicitly disabled with the configuration below (usually in wp-config.php):", 'installer'), strtoupper( join(', ', $repository_names) ));
716
- $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code><br /><br />';
717
- $error .= sprintf(__("In order to see the products information, please run the %smanual updates check%s to initialize the products list or (temporarily) remove the above code.", 'installer'), '<a href="' . admin_url('update-core.php') . '">', '</a>');
718
-
719
- $this->register_admin_message($error, 'error');
720
-
721
-
722
- }
723
-
724
- return;
725
- }
726
-
727
- $checked = true;
728
-
729
- foreach($this->repositories as $id => $data){
730
-
731
- $response = wp_remote_get($data['products']);
732
-
733
- if(is_wp_error($response)){
734
- // http fallback
735
- $data['products'] = preg_replace("@^https://@", 'http://', $data['products']);
736
- $response = wp_remote_get($data['products']);
737
- }
738
-
739
- if(is_wp_error($response)){
740
-
741
- $error = sprintf(__("Installer cannot contact our updates server to get information about the available products and check for new versions. If you are seeing this message for the first time, you can ignore it, as it may be a temporary communication problem. If the problem persists and your WordPress admin is slowing down, you can disable automated version checks. Add the following line to your wp-config.php file:", 'installer'), strtoupper($id));
742
- $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code>';
743
-
744
- $this->register_admin_message($error, 'error');
745
-
746
- continue;
747
- }
748
-
749
- if($response && isset($response['response']['code']) && $response['response']['code'] == 200){
750
- $body = wp_remote_retrieve_body($response);
751
- if($body){
752
- $products = json_decode($body, true);
753
-
754
- if(is_array($products)){
755
- $this->settings['repositories'][$id]['data'] = $products;
756
- $this->settings = $this->_pre_1_6_backwards_compatibility($this->settings);
757
- }
758
- }
759
-
760
- }
761
-
762
- $this->log( sprintf("Checked for %s updates: %s", $id, $data['products']) );
763
-
764
-
765
- }
766
-
767
- // cleanup
768
- if(empty($this->settings['repositories'])){
769
- $this->settings['repositories'] = array();
770
- }
771
- foreach($this->settings['repositories'] as $id => $data){
772
- if(!in_array($id, array_keys($this->repositories))){
773
- unset($this->settings['repositories'][$id]);
774
- }
775
- }
776
-
777
- $this->settings['last_repositories_update']= time();
778
-
779
- $this->save_settings();
780
-
781
- }
782
-
783
- public function show_products($args = array()){
784
-
785
- $screen = get_current_screen();
786
-
787
- if($screen->base == 'settings_page_installer'){ // settings page
788
- echo '<div class="wrap">';
789
- echo '<h2>' . __('Installer', 'installer') . '</h2>';
790
- echo '<br />';
791
- }
792
-
793
- if(!is_array($args)) $args = array();
794
- if(empty($args['template'])) $args['template'] = 'default';
795
-
796
- $this->filter_repositories_list();
797
-
798
- if(!empty($this->settings['repositories'])){
799
-
800
- $this->localize_strings();
801
- $this->set_filtered_prices($args);
802
- $this->set_hierarchy_and_order();
803
-
804
- foreach($this->settings['repositories'] as $repository_id => $repository){
805
-
806
- if($args['template'] == 'compact'){
807
-
808
- if(isset($args['repository']) && $args['repository'] == $repository_id){
809
- include $this->plugin_path() . '/templates/products-compact.php';
810
- }
811
-
812
- }else{
813
-
814
- include $this->plugin_path() . '/templates/repository-listing.php';
815
-
816
- }
817
-
818
- unset($site_key, $subscription_type, $expired, $upgrade_options, $products_avaliable);
819
-
820
- }
821
-
822
- }else{
823
-
824
- echo '<center>' . __('No repositories defined.', 'installer') . '</center>';
825
-
826
- }
827
-
828
- if($screen->base == 'settings_page_installer'){ // settings page
829
- echo '</div>';
830
- }
831
-
832
-
833
- }
834
-
835
- public function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
836
-
837
- $price = false;
838
-
839
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package ){
840
-
841
- if($package['id'] == $package_id){
842
- if(isset($package['products'][$product_id])){
843
- if($incl_discount && isset($package['products'][$product_id]['price_disc'])){
844
- $price = $package['products'][$product_id]['price_disc'];
845
- }elseif(isset($package['products'][$product_id]['price'])){
846
- $price = $package['products'][$product_id]['price'];
847
- }
848
- }
849
- break;
850
- }
851
- }
852
-
853
- return $price;
854
- }
855
-
856
- private function _render_product_packages($packages, $subscription_type, $expired, $upgrade_options, $repository_id){
857
-
858
- $data = array();
859
-
860
- foreach($packages as $package_id => $package){
861
-
862
- $row = array('products' => array(), 'downloads' => array());
863
- foreach($package['products'] as $product){
864
-
865
- // filter out free subscriptions from being displayed as buying options
866
- if( empty($product['price']) && (empty($subscription_type) || $expired) ){
867
- continue;
868
- }
869
-
870
- // buy base
871
- if(empty($subscription_type) || $expired) {
872
-
873
- $p['url'] = $this->append_parameters_to_buy_url($product['url'], $repository_id);
874
- if (!empty($product['price_disc'])) {
875
- $p['label'] = $product['call2action'] . ' - ' . sprintf('$%s %s$%d%s (USD)', $product['price_disc'], '&nbsp;&nbsp;<del>', $product['price'], '</del>');
876
- } else {
877
- $p['label'] = $product['call2action'] . ' - ' . sprintf('$%d (USD)', $product['price']);
878
- }
879
- $row['products'][] = $p;
880
-
881
- // renew
882
- } elseif(isset($subscription_type) && $product['subscription_type'] == $subscription_type){
883
-
884
- if($product['renewals']) {
885
- foreach ($product['renewals'] as $renewal) {
886
- $p['url'] = $this->append_parameters_to_buy_url($renewal['url'], $repository_id);
887
- $p['label'] = $renewal['call2action'] . ' - ' . sprintf('$%d (USD)', $renewal['price']);
888
- }
889
-
890
- $row['products'][] = $p;
891
- }
892
-
893
- }
894
-
895
- // upgrades
896
- if(!empty($upgrade_options[$product['subscription_type']])){
897
-
898
- foreach($upgrade_options[$product['subscription_type']] as $stype => $upgrade){
899
- if($stype != $subscription_type) continue;
900
-
901
- $p['url'] = $this->append_parameters_to_buy_url($upgrade['url'], $repository_id);
902
- if (!empty($upgrade['price_disc'])) {
903
- $p['label'] = $upgrade['call2action'] . ' - ' . sprintf('$%s %s$%d%s (USD)', $upgrade['price_disc'], '&nbsp;&nbsp;<del>', $upgrade['price'], '</del>');
904
- } else {
905
- $p['label'] = $upgrade['call2action'] . ' - ' . sprintf('$%d (USD)', $upgrade['price']);
906
- }
907
- $row['products'][] = $p;
908
-
909
- }
910
-
911
- }
912
-
913
- // downloads
914
- if(isset($subscription_type) && !$expired && $product['subscription_type'] == $subscription_type){
915
- foreach($product['plugins'] as $plugin_slug){
916
-
917
- $row['downloads'][] = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
918
-
919
- }
920
-
921
- }
922
-
923
- //subpackages
924
- if(!empty($package['sub-packages'])){
925
- $row['sub-packages'] = $package['sub-packages'];
926
- }
927
-
928
- }
929
-
930
- $row['id'] = $package['id'];
931
- $row['image_url'] = $package['image_url'];
932
- $row['name'] = $package['name'];
933
- $row['description'] = $package['description'];
934
-
935
- if(!empty($row['products']) || !empty($row['downloads']) || !empty($row['sub-packages'])){
936
- $data[] = $row;
937
- }
938
-
939
-
940
- }
941
-
942
- return $data;
943
-
944
- }
945
-
946
- public function get_extra_url_parameters(){
947
-
948
- $parameters = array();
949
-
950
- if(!empty($this->package_source)){
951
- foreach($this->package_source as $key => $val){
952
- $parameters[$key] = $val;
953
- }
954
- }
955
-
956
- $parameters['installer_version'] = WP_INSTALLER_VERSION;
957
- $parameters['theme'] = wp_get_theme()->get( 'Name' );
958
- $parameters['site_name'] = get_bloginfo( 'name' );
959
-
960
- return $parameters;
961
- }
962
-
963
- public function append_parameters_to_buy_url($url, $repository_id, $args = array()){
964
-
965
- $url = add_query_arg( array('icl_site_url' => $this->get_installer_site_url( $repository_id ) ), $url );
966
-
967
- $affiliate_id = false;
968
- $affiliate_key = false;
969
-
970
- // Add extra parameters for custom Installer packages
971
- if( !empty($this->package_source) ){
972
- $extra = $this->get_extra_url_parameters();
973
-
974
- if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
975
-
976
- if( !empty($extra['affiliate_key']) && !empty($extra['user_id']) ){
977
- $this->config['affiliate_id:' . $repository_id] = $extra['user_id'];
978
- $this->config['affiliate_key:' . $repository_id] = $extra['affiliate_key'];
979
- unset($extra['affiliate_key'], $extra['user_id'], $extra['repository']); // no need to include these ones
980
- }
981
-
982
- $url = add_query_arg($extra, $url);
983
- }
984
-
985
- }
986
-
987
- if(isset($this->config['affiliate_id:' . $repository_id]) && isset($this->config['affiliate_key:' . $repository_id])){
988
-
989
- $affiliate_id = $this->config['affiliate_id:' . $repository_id];
990
- $affiliate_key = $this->config['affiliate_key:' . $repository_id];
991
-
992
- }elseif(isset($args['affiliate_id:' . $repository_id]) && isset($args['affiliate_key:' . $repository_id])){
993
-
994
- $affiliate_id = $args['affiliate_id:' . $repository_id];
995
- $affiliate_key = $args['affiliate_key:' . $repository_id];
996
-
997
- }elseif(defined('ICL_AFFILIATE_ID') && defined('ICL_AFFILIATE_KEY')){ //support for 1 repo
998
-
999
- $affiliate_id = ICL_AFFILIATE_ID;
1000
- $affiliate_key = ICL_AFFILIATE_KEY;
1001
-
1002
- }elseif(isset($this->config['affiliate_id']) && isset($this->config['affiliate_key'])) {
1003
- // BACKWARDS COMPATIBILITY
1004
- $affiliate_id = $this->config['affiliate_id'];
1005
- $affiliate_key = $this->config['affiliate_key'];
1006
- }
1007
-
1008
- if($affiliate_id && $affiliate_key){
1009
- $url = add_query_arg(array('aid' => $affiliate_id, 'affiliate_key' => $affiliate_key), $url);
1010
- }
1011
-
1012
- if($repository_id == 'wpml'){
1013
- $url = add_query_arg(array('using_icl' => $this->_using_icl, 'wpml_version' => $this->_wpml_version), $url);
1014
- }
1015
-
1016
- $url = apply_filters('wp_installer_buy_url', $url);
1017
-
1018
- $url = esc_url($url);
1019
-
1020
- return $url;
1021
-
1022
- }
1023
-
1024
- public function save_site_key($args = array()){
1025
-
1026
- $error = '';
1027
-
1028
- $repository_id = isset($args['repository_id']) ? $args['repository_id'] : (isset($_POST['repository_id']) ? $_POST['repository_id'] : false);
1029
- $nonce = isset($args['nonce']) ? $args['nonce'] : (isset($_POST['nonce']) ? $_POST['nonce'] : '');
1030
- $site_key = isset($args['site_key']) ? $args['site_key'] : $_POST['site_key_' . $repository_id];
1031
-
1032
- $site_key = preg_replace("/[^A-Za-z0-9]/", '', $site_key);
1033
-
1034
- if($repository_id && $nonce && wp_create_nonce('save_site_key_' . $repository_id) == $nonce){
1035
-
1036
- try {
1037
- $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REGISTRATION );
1038
-
1039
- if ( $subscription_data ) {
1040
- $this->settings['repositories'][$repository_id]['subscription'] = array('key' => $site_key, 'data' => $subscription_data);
1041
- $this->save_settings();
1042
- } else {
1043
- $error = __( 'Invalid site key for the current site.', 'installer' );
1044
- }
1045
-
1046
- } catch (Exception $e ){
1047
- $error = $e->getMessage();
1048
- if( preg_match('#Could not resolve host: (.*)#', $error, $matches) || preg_match('#Couldn\'t resolve host \'(.*)\'#', $error, $matches) ){
1049
- $error = sprintf(__("%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer'),
1050
- '<strong><i>' . $this->get_generic_product_name($repository_id) . '</i></strong>',
1051
- '<strong><i>' . $matches[1]. '</i></strong>'
1052
- ) ;
1053
- }
1054
- }
1055
-
1056
- }
1057
-
1058
- $return = array('error' => $error);
1059
-
1060
- if($this->api_debug){
1061
- $return['debug'] = $this->api_debug;
1062
- }
1063
-
1064
- if(!empty($args['return'])){
1065
- return $return;
1066
- }else{
1067
- echo json_encode($return);
1068
- exit;
1069
- }
1070
-
1071
- }
1072
-
1073
- /**
1074
- * Alias for WP_Installer::get_repository_site_key
1075
- * @see WP_Installer::get_repository_site_key()
1076
- *
1077
- * @param string $repository_id
1078
- * @return string (site key) or bool
1079
- */
1080
- public function get_site_key($repository_id){
1081
- return WP_Installer::get_repository_site_key( $repository_id );
1082
- }
1083
-
1084
- public function remove_site_key(){
1085
- if($_POST['nonce'] == wp_create_nonce('remove_site_key_' . $_POST['repository_id'])){
1086
- unset($this->settings['repositories'][$_POST['repository_id']]['subscription']);
1087
- $this->save_settings();
1088
-
1089
- $this->refresh_repositories_data();
1090
- }
1091
- exit;
1092
- }
1093
-
1094
- public function validate_repository_subscription(){
1095
- $repository_id = isset($_GET['validate_repository']) ? $_GET['validate_repository'] : false;
1096
- if($repository_id){
1097
-
1098
- $site_key = $this->get_site_key($repository_id);
1099
- if($site_key) {
1100
- $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION);
1101
- if(empty($subscription_data)){
1102
- unset($this->settings['repositories'][$repository_id]['subscription']);
1103
- delete_site_transient('update_plugins');
1104
- $this->save_settings();
1105
- }
1106
- }
1107
-
1108
- wp_redirect($this->menu_url() . '#repository-' . $repository_id);
1109
- exit;
1110
-
1111
- }
1112
-
1113
- }
1114
-
1115
- public function update_site_key(){
1116
-
1117
- $error = '';
1118
-
1119
- if($_POST['nonce'] == wp_create_nonce('update_site_key_' . $_POST['repository_id'])){
1120
-
1121
- $repository_id = $_POST['repository_id'];
1122
- $site_key = $this->get_site_key($_POST['repository_id']);
1123
-
1124
- if($site_key){
1125
- try {
1126
- $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK );
1127
-
1128
- if ( $subscription_data ) {
1129
- $this->settings['repositories'][$repository_id]['subscription'] = array('key' => $site_key, 'data' => $subscription_data);
1130
-
1131
- //also refresh products information
1132
- $this->refresh_repositories_data();
1133
-
1134
- $this->save_settings();
1135
-
1136
- } else {
1137
- unset($this->settings['repositories'][$repository_id]['subscription']);
1138
- $error = __( 'Invalid site key for the current site. If the error persists, try to unregister first and then register again with the same site key.', 'installer' );
1139
- }
1140
-
1141
-
1142
- } catch (Exception $e ){
1143
- $error = $e->getMessage();
1144
- if( preg_match('#Could not resolve host: (.*)#', $error, $matches) || preg_match('#Couldn\'t resolve host \'(.*)\'#', $error, $matches) ){
1145
- $error = sprintf(__("%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer'),
1146
- '<strong><i>' . $this->get_generic_product_name($repository_id) . '</i></strong>',
1147
- '<strong><i>' . $matches[1]. '</i></strong>'
1148
- ) ;
1149
- }
1150
- }
1151
-
1152
- }
1153
-
1154
- }
1155
-
1156
- echo json_encode(array('error' => $error));
1157
-
1158
- exit;
1159
- }
1160
-
1161
- public function api_debug_log($text){
1162
-
1163
- if(defined('WPML_DEBUG_INSTALLER') && WPML_DEBUG_INSTALLER){
1164
-
1165
- if(!is_scalar($text)){
1166
- $text = print_r($text, 1);
1167
- }
1168
-
1169
- $this->api_debug .= $text . "\n";
1170
-
1171
- }
1172
-
1173
- }
1174
-
1175
- public function fetch_subscription_data( $repository_id, $site_key, $source = self::SITE_KEY_VALIDATION_SOURCE_OTHER ){
1176
-
1177
- $subscription_data = false;
1178
-
1179
- $args['body'] = array(
1180
- 'action' => 'site_key_validation',
1181
- 'site_key' => $site_key,
1182
- 'site_url' => $this->get_installer_site_url( $repository_id ),
1183
- 'source' => $source
1184
- );
1185
-
1186
- if($repository_id == 'wpml'){
1187
- $args['body']['using_icl'] = $this->_using_icl;
1188
- $args['body']['wpml_version'] = $this->_wpml_version;
1189
- }
1190
-
1191
- $args['body']['installer_version'] = WP_INSTALLER_VERSION;
1192
- $args['body']['theme'] = wp_get_theme()->get( 'Name' );
1193
- $args['body']['site_name'] = get_bloginfo( 'name' );
1194
-
1195
- $args['body']['versions'] = $this->get_local_product_versions( $repository_id );
1196
-
1197
- $args['timeout'] = 45;
1198
-
1199
- // Add extra parameters for custom Installer packages
1200
- if( !empty($this->package_source) ){
1201
- $extra = $this->get_extra_url_parameters();
1202
- if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
1203
- unset($extra['repository']);
1204
- foreach($extra as $key => $val){
1205
- $args['body'][$key] = $val;
1206
- }
1207
- }
1208
- }
1209
-
1210
- $response = wp_remote_post($this->repositories[$repository_id]['api-url'], $args);
1211
-
1212
- $this->api_debug_log("POST {$this->repositories[$repository_id]['api-url']}");
1213
- $this->api_debug_log($args);
1214
-
1215
- $this->log("POST {$this->repositories[$repository_id]['api-url']} - fetch subscription data");
1216
-
1217
- if( !is_wp_error($response) ){
1218
- $datas = wp_remote_retrieve_body($response);
1219
-
1220
- if(is_serialized($datas)){
1221
- $data = unserialize($datas);
1222
- $this->api_debug_log($data);
1223
- }else{
1224
- $this->api_debug_log($datas);
1225
- }
1226
-
1227
- if(!empty($data->subscription_data)){
1228
- $subscription_data = $data->subscription_data;
1229
- }
1230
-
1231
- do_action( 'installer_fetched_subscription_data', $data, $repository_id);
1232
-
1233
- }else{
1234
-
1235
- $this->api_debug_log($response);
1236
- throw new Exception( $response->get_error_message() );
1237
- }
1238
-
1239
- return $subscription_data;
1240
-
1241
- }
1242
-
1243
- function get_local_product_versions( $repository_id ){
1244
-
1245
- $versions = array();
1246
-
1247
- foreach( $this->settings['repositories'][$repository_id]['data']['packages'] as $package_id => $package ){
1248
-
1249
- foreach( $package['products'] as $product_id => $product ){
1250
-
1251
- foreach( $product['plugins'] as $plugin_slug ){
1252
-
1253
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1254
-
1255
- if( empty( $versions[$download['slug']] ) ) {
1256
- $v = $this->get_plugin_installed_version($download['name'], $download['slug']);
1257
- if($v){
1258
- $versions[$download['slug']] = $v;
1259
- }
1260
- }
1261
-
1262
- }
1263
-
1264
- }
1265
-
1266
- }
1267
-
1268
- return $versions;
1269
- }
1270
-
1271
- public function get_repository_site_key($repository_id){
1272
- $site_key = false;
1273
-
1274
- if(!empty($this->settings['repositories'][$repository_id]['subscription']['key'])){
1275
- $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1276
- }
1277
-
1278
- return $site_key;
1279
- }
1280
-
1281
- public function repository_has_valid_subscription($repository_id){
1282
-
1283
- $valid = false;
1284
-
1285
- if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1286
-
1287
- $subscription = $this->settings['repositories'][$repository_id]['subscription']['data'];
1288
- $valid = ( $subscription->status == 1 && (strtotime($subscription->expires) > time() || empty($subscription->expires)) ) || $subscription->status == 4;
1289
-
1290
- }
1291
- return $valid;
1292
-
1293
- }
1294
-
1295
- public function repository_has_subscription($repository_id){
1296
- $key = false;
1297
- if(!empty($this->settings['repositories'][$repository_id]['subscription']['key'])){
1298
- $key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1299
- }
1300
-
1301
- return $key;
1302
-
1303
- }
1304
-
1305
- public function repository_has_expired_subscription($repository_id){
1306
-
1307
- return $this->repository_has_subscription($repository_id) && !$this->repository_has_valid_subscription($repository_id);
1308
-
1309
- }
1310
-
1311
- public function get_generic_product_name($repository_id){
1312
-
1313
- return $this->settings['repositories'][$repository_id]['data']['product-name'];
1314
-
1315
- }
1316
-
1317
- public function show_subscription_renew_warning($repository_id, $subscription_id){
1318
-
1319
- $show = false;
1320
-
1321
- $data = $this->settings['repositories'][$repository_id]['data'];
1322
- if(!empty($data['subscriptions_meta'])){
1323
- if(isset($data['subscriptions_meta']['expiration'])){
1324
-
1325
- if(!empty($data['subscriptions_meta']['expiration'][$subscription_id])){
1326
-
1327
- $days = $data['subscriptions_meta']['expiration'][$subscription_id]['days_warning'];
1328
- $message = $data['subscriptions_meta']['expiration'][$subscription_id]['warning_message'];
1329
-
1330
- }else{
1331
-
1332
- //defaults
1333
- $days = 30;
1334
- $message = __('You will have to renew your subscription in order to continue getting the updates and support.', 'installer');
1335
-
1336
- }
1337
-
1338
- if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1339
- $subscription = $this->settings['repositories'][$repository_id]['subscription'];
1340
-
1341
- if($subscription['data']->subscription_type == $subscription_id && !empty($subscription['data']->expires)){
1342
-
1343
- if(strtotime($subscription['data']->expires) < strtotime(sprintf("+%d day", $days))){
1344
-
1345
- $days_to_expiration = ceil((strtotime($subscription['data']->expires) - time()) / 86400);
1346
-
1347
- echo '<div><p class="installer-warn-box">' .
1348
- sprintf(_n('Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer'), $days_to_expiration) .
1349
- '<br />' . $message .
1350
- '</p></div>';
1351
-
1352
- $show = true;
1353
-
1354
- }
1355
-
1356
- }
1357
-
1358
- }
1359
-
1360
-
1361
- }
1362
- }
1363
-
1364
-
1365
- return $show;
1366
-
1367
- }
1368
-
1369
- public function setup_plugins_renew_warnings(){
1370
-
1371
- $plugins = get_plugins();
1372
-
1373
- $subscriptions_with_warnings = array();
1374
- foreach($this->settings['repositories'] as $repository_id => $repository){
1375
-
1376
- if($this->repository_has_valid_subscription($repository_id)){
1377
- $subscription_type = $this->settings['repositories'][$repository_id]['subscription']['data']->subscription_type;
1378
- $expires = $this->settings['repositories'][$repository_id]['subscription']['data']->expires;
1379
-
1380
- $never_expires = isset($this->settings['repositories'][$repository_id]['subscription'])
1381
- && empty($this->settings['repositories'][$repository_id]['subscription']['data']->expires)
1382
- && (
1383
- $this->settings['repositories'][$repository_id]['subscription']['data']->status == 4 ||
1384
- $this->settings['repositories'][$repository_id]['subscription']['data']->status == 1
1385
- );
1386
-
1387
- if(!$never_expires){
1388
- if(isset($this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type])){
1389
-
1390
- $days_warning = $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type]['days_warning'];
1391
- $custom_message = $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type]['warning_message'];
1392
-
1393
- }else{
1394
- //defaults
1395
- $days_warning = 30;
1396
- $custom_message = __('You will have to renew your subscription in order to continue getting the updates and support.', 'installer');
1397
- }
1398
-
1399
- if(strtotime($expires) < strtotime(sprintf('+%d day', $days_warning)) ){
1400
-
1401
- $days_to_expiration = ceil((strtotime($expires) - time()) / 86400);
1402
-
1403
- $message = sprintf(_n('Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer'), $days_to_expiration);
1404
- $subscriptions_with_warnings[$subscription_type] = $message . ' ' . $custom_message;
1405
-
1406
- }
1407
- }
1408
-
1409
- }
1410
-
1411
- }
1412
-
1413
-
1414
-
1415
- foreach($plugins as $plugin_id => $plugin){
1416
-
1417
- $slug = dirname($plugin_id);
1418
- if(empty($slug)) continue;
1419
-
1420
- foreach($this->settings['repositories'] as $repository_id => $repository){
1421
-
1422
- if($this->repository_has_valid_subscription($repository_id)){
1423
-
1424
- foreach($repository['data']['packages'] as $package){
1425
-
1426
- foreach($package['products'] as $product){
1427
-
1428
- foreach($product['plugins'] as $plugin_slug){
1429
-
1430
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1431
-
1432
- if($download['slug'] == $slug || $download['name'] == $plugin['Name'] || $download['name'] == $plugin['Title']){ //match order: slug, name, title
1433
-
1434
- if(isset($subscriptions_with_warnings[$product['subscription_type']])){
1435
-
1436
- $this->_plugins_renew_warnings[$plugin_id] = $subscriptions_with_warnings[$product['subscription_type']];
1437
-
1438
- }
1439
-
1440
- }
1441
-
1442
- }
1443
-
1444
- }
1445
-
1446
- }
1447
-
1448
- }
1449
-
1450
- }
1451
-
1452
- }
1453
-
1454
- }
1455
-
1456
- public function queue_plugins_renew_warnings() {
1457
-
1458
- if(!empty($this->_plugins_renew_warnings)){
1459
-
1460
- foreach($this->_plugins_renew_warnings as $plugin_id => $message){
1461
-
1462
- add_action( "after_plugin_row_" . $plugin_id, array($this, 'plugins_renew_warning'), 10, 3 );
1463
- }
1464
-
1465
- }
1466
-
1467
- }
1468
-
1469
- public function plugins_renew_warning($plugin_file, $plugin_data, $status){
1470
-
1471
- if(empty($this->_plugins_renew_warnings[$plugin_file])) return;
1472
-
1473
- $wp_list_table = _get_list_table('WP_Plugins_List_Table');
1474
- ?>
1475
-
1476
- <tr class="plugin-update-tr"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
1477
- <div class="update-message">
1478
- <?php
1479
- echo $this->_plugins_renew_warnings[$plugin_file]. ' ';
1480
- printf(__('%sRenew here%s.', 'installer'),
1481
- '<a href="' . $this->menu_url() . '">', '</a>');
1482
- ?>
1483
- </div>
1484
- </tr>
1485
-
1486
- <?php
1487
-
1488
- }
1489
-
1490
- public function get_subscription_type_for_repository($repository_id){
1491
-
1492
- $subscription_type = false;
1493
-
1494
- if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1495
- $subscription_type = $this->settings['repositories'][$repository_id]['subscription']['data']->subscription_type;
1496
- }
1497
-
1498
- return $subscription_type;
1499
-
1500
- }
1501
-
1502
- public function have_superior_subscription($subscription_type, $product){
1503
-
1504
- $have = false;
1505
-
1506
- if(is_array($product['upgrades'])){
1507
- foreach($product['upgrades'] as $u){
1508
- if($u['subscription_type'] == $subscription_type){
1509
- $have = true;
1510
- break;
1511
- }
1512
- }
1513
- }
1514
-
1515
- return $have;
1516
- }
1517
-
1518
- public function is_product_available_for_download($product_name, $repository_id){
1519
-
1520
- $available = false;
1521
-
1522
- $subscription_type = $this->get_subscription_type_for_repository($repository_id);
1523
- $expired = $this->repository_has_expired_subscription($repository_id);
1524
-
1525
- if($this->repository_has_subscription($repository_id) && !$expired){
1526
-
1527
- $this->set_hierarchy_and_order();
1528
-
1529
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package_id => $package){
1530
-
1531
- $has_top_package = false;
1532
-
1533
- foreach($package['products'] as $product){
1534
-
1535
- if($subscription_type == $product['subscription_type']){
1536
- $has_top_package = true;
1537
- if($product['name'] == $product_name){
1538
- return $available = true;
1539
- }
1540
- }
1541
-
1542
- }
1543
-
1544
- if(!empty($package['sub-packages'])){
1545
- foreach($package['sub-packages'] as $sub_package){
1546
- foreach($sub_package['products'] as $product){
1547
- if($product['name'] == $product_name && ($subscription_type == $product['subscription_type'] || $has_top_package)){
1548
- return $available = true;
1549
- }
1550
- }
1551
- }
1552
- }
1553
-
1554
- }
1555
- }
1556
-
1557
- return $available;
1558
-
1559
- }
1560
-
1561
- public function get_upgrade_options($repository_id){
1562
- $all_upgrades = array();
1563
-
1564
- //get all products: packages and subpackages
1565
- $all_products = array();
1566
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
1567
- foreach($package['products'] as $product) {
1568
- $all_products[] = $product;
1569
- }
1570
- if(!empty($package['sub-packages'])){
1571
- foreach($package['sub-packages'] as $subpackage){
1572
- foreach($subpackage['products'] as $product) {
1573
- $all_products[] = $product;
1574
- }
1575
-
1576
- }
1577
-
1578
- }
1579
-
1580
- }
1581
-
1582
- foreach($all_products as $product) {
1583
- if ($product['upgrades']) {
1584
- foreach ($product['upgrades'] as $upgrade) {
1585
- if ($this->repository_has_valid_subscription($repository_id) || ($this->repository_has_subscription($repository_id) && $upgrade['including_expired'])) {
1586
- $all_upgrades[$upgrade['subscription_type']][$product['subscription_type']] = $upgrade;
1587
- }
1588
- }
1589
- }
1590
- }
1591
-
1592
- return $all_upgrades;
1593
-
1594
- }
1595
-
1596
- public function append_site_key_to_download_url($url, $key, $repository_id){
1597
-
1598
- $url_params['site_key'] = $key;
1599
- $url_params['site_url'] = $this->get_installer_site_url( $repository_id );
1600
-
1601
-
1602
- // Add extra parameters for custom Installer packages
1603
- if( !empty($this->package_source) ){
1604
- $extra = $this->get_extra_url_parameters();
1605
- if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
1606
- unset($extra['repository']);
1607
- foreach($extra as $key => $val){
1608
- $url_params[$key] = $val;
1609
- }
1610
- }
1611
- }
1612
-
1613
- $url = add_query_arg($url_params, $url);
1614
-
1615
- if($repository_id == 'wpml'){
1616
- $url = add_query_arg(array('using_icl' => $this->_using_icl, 'wpml_version' => $this->_wpml_version), $url);
1617
- }
1618
-
1619
- return $url;
1620
-
1621
- }
1622
-
1623
- public function plugin_is_installed($name, $slug, $version = null){
1624
-
1625
- $is = false;
1626
-
1627
- $plugins = get_plugins();
1628
-
1629
- foreach($plugins as $plugin_id => $plugin){
1630
-
1631
- $wp_plugin_slug = dirname($plugin_id);
1632
-
1633
- // Exception: embedded plugins
1634
- if( $wp_plugin_slug == $slug || $plugin['Name'] == $name || $plugin['Title'] == $name || ( $wp_plugin_slug == $slug . '-embedded' || $plugin['Name'] == $name . ' Embedded' ) ){
1635
- if($version){
1636
- if(version_compare($plugin['Version'], $version, '>=')){
1637
- $is = $plugin['Version'];
1638
- }
1639
- }else{
1640
- $is = $plugin['Version'];
1641
- }
1642
-
1643
- break;
1644
- }
1645
-
1646
- }
1647
-
1648
- //exception: Types name difference
1649
- if(!$is && $name == 'Types'){
1650
- return $this->plugin_is_installed('Types - Complete Solution for Custom Fields and Types', $slug, $version);
1651
- }
1652
-
1653
- return $is;
1654
- }
1655
-
1656
- public function plugin_is_embedded_version($name, $slug){
1657
- $is = false;
1658
-
1659
- $plugins = get_plugins();
1660
-
1661
- //false if teh full version is also installed
1662
- $is_full_installed = false;
1663
- foreach($plugins as $plugin_id => $plugin){
1664
-
1665
- if(($plugin['Name'] == $name && !preg_match("#-embedded$#", $slug)) ){
1666
- $is_full_installed = true;
1667
- break;
1668
- }
1669
-
1670
- }
1671
-
1672
- if($is_full_installed){
1673
- return false;
1674
- }
1675
-
1676
- foreach($plugins as $plugin_id => $plugin){
1677
-
1678
- // TBD
1679
- $wp_plugin_slug = dirname($plugin_id);
1680
- if( $wp_plugin_slug == $slug . '-embedded' && $plugin['Name'] == $name . ' Embedded'){
1681
- $is = true;
1682
- break;
1683
- }
1684
-
1685
- }
1686
-
1687
- return $is;
1688
-
1689
- }
1690
-
1691
- //Alias for plugin_is_installed
1692
- public function get_plugin_installed_version($name, $slug){
1693
-
1694
- return $this->plugin_is_installed($name, $slug);
1695
-
1696
- }
1697
-
1698
- public function get_plugin_repository_version($repository_id, $slug){
1699
- $version = false;
1700
-
1701
- if(!empty($this->settings['repositories'][$repository_id]['data']['packages'])){
1702
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
1703
- foreach($package['products'] as $product) {
1704
-
1705
- foreach($product['plugins'] as $plugin_slug){
1706
-
1707
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1708
-
1709
- if($download['slug'] == $slug){
1710
- $version = $download['version'];
1711
- break (3);
1712
- }
1713
-
1714
- }
1715
-
1716
- }
1717
- }
1718
- }
1719
-
1720
- return $version;
1721
- }
1722
-
1723
- public function is_uploading_allowed(){
1724
-
1725
- //_deprecated_function ( __FUNCTION__, '1.7.3', 'Installer_Dependencies::' . __FUNCTION__ );
1726
- return $this->dependencies->is_uploading_allowed();
1727
-
1728
- }
1729
-
1730
- public function download_plugin_ajax_handler(){
1731
-
1732
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1733
- require_once $this->plugin_path() . '/includes/installer-upgrader-skins.php';
1734
-
1735
- if(isset($_POST['data'])){
1736
-
1737
- $data = json_decode( base64_decode( $_POST['data'] ), true );
1738
-
1739
- }
1740
-
1741
- $ret = false;
1742
- $plugin_id = false;
1743
- $message = '';
1744
-
1745
- //validate subscription
1746
- $site_key = $this->get_repository_site_key($data['repository_id']);
1747
- $subscription_data = $this->fetch_subscription_data( $data['repository_id'], $site_key , self::SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT);
1748
-
1749
- if($subscription_data && !is_wp_error($subscription_data) && $this->repository_has_valid_subscription($data['repository_id'])){
1750
-
1751
- if($data['nonce'] == wp_create_nonce('install_plugin_' . $data['url'])){
1752
-
1753
- $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1754
- $upgrader = new Plugin_Upgrader($upgrader_skins);
1755
-
1756
- remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
1757
-
1758
- $plugins = get_plugins();
1759
-
1760
- //upgrade or install?
1761
- foreach($plugins as $id => $plugin){
1762
- $wp_plugin_slug = dirname($id);
1763
- $is_embedded = $this->plugin_is_embedded_version(preg_replace('/ Embedded$/', '', $plugin['Name']), preg_replace('/-embedded$/', '', $wp_plugin_slug));
1764
-
1765
- if($wp_plugin_slug == $data['slug'] || $is_embedded && preg_replace('/-embedded$/', '', $wp_plugin_slug) == $data['slug']){
1766
- $plugin_id = $id;
1767
- break;
1768
- }
1769
- }
1770
-
1771
- if($plugin_id && empty($is_embedded)){ //upgrade
1772
- $response['upgrade'] = 1;
1773
-
1774
- $plugin_is_active = is_plugin_active($plugin_id);
1775
-
1776
- $ret = $upgrader->upgrade($plugin_id);
1777
-
1778
- if(!$ret && !empty($upgrader->skin->installer_error)){
1779
- if(is_wp_error($upgrader->skin->installer_error)){
1780
- $message = $upgrader->skin->installer_error->get_error_message() .
1781
- ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1782
- }
1783
- }
1784
-
1785
- if($plugin_is_active){
1786
- //prevent redirects
1787
- add_filter('wp_redirect', '__return_false');
1788
- activate_plugin($plugin_id);
1789
- }
1790
-
1791
- }else{ //install
1792
-
1793
- if($is_embedded){
1794
- delete_plugins(array($plugin_id));
1795
- }
1796
-
1797
- $response['install'] = 1;
1798
- $ret = $upgrader->install($data['url']);
1799
- if(!$ret && !empty($upgrader->skin->installer_error)){
1800
- if(is_wp_error($upgrader->skin->installer_error)){
1801
- $message = $upgrader->skin->installer_error->get_error_message() .
1802
- ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1803
- }
1804
- }
1805
- }
1806
-
1807
- $plugins = get_plugins(); //read again
1808
-
1809
- if($ret && !empty($_POST['activate'])){
1810
- foreach($plugins as $id => $plugin){
1811
- $wp_plugin_slug = dirname($id);
1812
- if($wp_plugin_slug == $data['slug']){
1813
- $plugin_version = $plugin['Version'];
1814
- $plugin_id = $id;
1815
- break;
1816
- }
1817
- }
1818
-
1819
- }
1820
-
1821
- }
1822
-
1823
- } else { //subscription not valid
1824
-
1825
- $ret = false;
1826
- $message = __('Your subscription appears to no longer be valid. Please try to register again using a valid site key.', 'installer');
1827
- }
1828
-
1829
- $response['version'] = isset($plugin_version) ? $plugin_version : 0;
1830
- $response['plugin_id'] = $plugin_id;
1831
- $response['nonce'] = wp_create_nonce('activate_' . $plugin_id);
1832
- $response['success'] = $ret;
1833
- $response['message'] = $message;
1834
-
1835
- echo json_encode( $response );
1836
- exit;
1837
-
1838
- }
1839
-
1840
- public function download_plugin($slug, $url){
1841
-
1842
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1843
- require_once $this->plugin_path() . '/includes/installer-upgrader-skins.php';
1844
-
1845
- $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1846
- $upgrader = new Plugin_Upgrader($upgrader_skins);
1847
-
1848
- remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
1849
-
1850
- $plugins = get_plugins();
1851
-
1852
- $plugin_id = false;
1853
-
1854
- //upgrade or install?
1855
- foreach($plugins as $id => $plugin){
1856
- $wp_plugin_slug = dirname($id);
1857
- if($wp_plugin_slug == $slug){
1858
- $plugin_id = $id;
1859
- break;
1860
- }
1861
- }
1862
-
1863
- if($plugin_id){ //upgrade
1864
-
1865
- $plugin_is_active = is_plugin_active($plugin_id);
1866
-
1867
- $ret = $upgrader->upgrade($plugin_id);
1868
-
1869
- if($plugin_is_active){
1870
- activate_plugin($plugin_id);
1871
- }
1872
-
1873
- }else{ //install
1874
- $ret = $upgrader->install($url);
1875
- }
1876
-
1877
- return $ret;
1878
-
1879
- }
1880
-
1881
- public function activate_plugin(){
1882
-
1883
- $error = '';
1884
-
1885
- if(isset($_POST['nonce']) && isset($_POST['plugin_id']) && $_POST['nonce'] == wp_create_nonce('activate_' . $_POST['plugin_id'])){
1886
-
1887
- $plugin_id = $_POST['plugin_id'];
1888
-
1889
- // Deactivate any embedded version
1890
- $plugin_slug = dirname($plugin_id);
1891
- $active_plugins = get_option('active_plugins');
1892
- foreach($active_plugins as $plugin){
1893
- $wp_plugin_slug = dirname($plugin);
1894
- if($wp_plugin_slug == $plugin_slug . '-embedded'){
1895
- deactivate_plugins(array($plugin));
1896
- break;
1897
- }
1898
- }
1899
-
1900
- //prevent redirects
1901
- add_filter('wp_redirect', '__return_false', 10000);
1902
-
1903
- $return = activate_plugin($plugin_id);
1904
-
1905
- if(is_wp_error($return)){
1906
- $error = $return->get_error_message();
1907
- }
1908
-
1909
- }else{
1910
- $error = 'error';
1911
- }
1912
-
1913
- $ret = array('error' => $error);
1914
-
1915
- echo json_encode($ret);
1916
- exit;
1917
-
1918
- }
1919
-
1920
- public function custom_plugins_api_call($false, $action, $args){
1921
-
1922
- if($action == 'plugin_information'){
1923
-
1924
- $slug = $args->slug;
1925
-
1926
- foreach($this->settings['repositories'] as $repository_id => $repository){
1927
-
1928
- if(!$this->repository_has_valid_subscription($repository_id)){
1929
- $site_key = false;
1930
- }else{
1931
- $site_key = $repository['subscription']['key'];
1932
- }
1933
-
1934
- foreach($repository['data']['packages'] as $package){
1935
-
1936
- foreach($package['products'] as $product){
1937
-
1938
- foreach($product['plugins'] as $plugin_slug){
1939
-
1940
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1941
-
1942
- if($download['slug'] == $slug){
1943
-
1944
- $res = new stdClass();
1945
- $res->external = true;
1946
-
1947
- $res->name = $download['name'];
1948
- $res->slug = $slug;
1949
- $res->version = $download['version'];
1950
- $res->author = '';
1951
- $res->author_profile = '';
1952
- $res->last_updated = $download['date'];
1953
- //$res->homepage = $download['url'];
1954
-
1955
- if($site_key){
1956
- $res->download_link = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
1957
- }else{
1958
- // if(!empty($download['free-on-wporg'])
1959
- return false; //try somewhere else. e.g. wordpress.org
1960
- }
1961
-
1962
- $res->homepage = $repository['data']['url'];
1963
- $res->sections = array('Description' => $download['description'], 'Changelog' => $download['changelog']);
1964
-
1965
- return $res;
1966
-
1967
- }
1968
-
1969
- }
1970
-
1971
- }
1972
-
1973
- }
1974
-
1975
- }
1976
-
1977
- }
1978
-
1979
- return $false;
1980
-
1981
- }
1982
-
1983
- public function plugins_upgrade_check($update_plugins){
1984
-
1985
- if(!empty($this->settings['repositories'])){
1986
-
1987
- $plugins = get_plugins();
1988
-
1989
- foreach($plugins as $plugin_id => $plugin){
1990
-
1991
- $slug = dirname($plugin_id);
1992
- if(empty($slug)) continue;
1993
-
1994
- $version = $plugin['Version'];
1995
- $name = $plugin['Name'];
1996
-
1997
- foreach($this->settings['repositories'] as $repository_id => $repository){
1998
-
1999
-
2000
- if(!$this->repository_has_valid_subscription($repository_id)){
2001
- $site_key = false;
2002
- }else{
2003
- $site_key = $repository['subscription']['key'];
2004
- //$subscription_type = $this->get_subscription_type_for_repository($repository_id);
2005
- }
2006
-
2007
- foreach($repository['data']['packages'] as $package){
2008
-
2009
- foreach($package['products'] as $product){
2010
-
2011
- foreach($product['plugins'] as $plugin_slug){
2012
-
2013
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2014
-
2015
- if(!empty($download['free-on-wporg'])) {
2016
- continue;
2017
- }
2018
-
2019
- if(empty($update_plugins->response[$plugin_id]) && ($download['slug'] == $slug || $download['name'] == $name ) && version_compare($download['version'], $version, '>')){
2020
-
2021
- $response = new stdClass();
2022
- $response->id = 0;
2023
- $response->slug = $slug;
2024
- $response->plugin = $plugin_id;
2025
- $response->new_version = $download['version'];
2026
- $response->upgrade_notice = '';
2027
- $response->url = $download['url'];
2028
- if($site_key){
2029
- $response->package = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
2030
- }
2031
- $update_plugins->checked[$plugin_id] = $version;
2032
- $update_plugins->response[$plugin_id] = $response;
2033
-
2034
- }
2035
-
2036
- }
2037
-
2038
- }
2039
-
2040
- }
2041
-
2042
- }
2043
-
2044
- }
2045
-
2046
- }
2047
-
2048
- return $update_plugins;
2049
-
2050
- }
2051
-
2052
- public function setup_plugins_page_notices(){
2053
-
2054
- $plugins = get_plugins();
2055
-
2056
- foreach($plugins as $plugin_id => $plugin){
2057
-
2058
- $slug = dirname($plugin_id);
2059
- if(empty($slug)) continue;
2060
-
2061
- $name = $plugin['Name'];
2062
-
2063
- foreach($this->settings['repositories'] as $repository_id => $repository){
2064
-
2065
- if(!$this->repository_has_valid_subscription($repository_id)){
2066
- $site_key = false;
2067
- }else{
2068
- $site_key = $repository['subscription']['key'];
2069
- }
2070
-
2071
- foreach($repository['data']['packages'] as $package){
2072
-
2073
- foreach($package['products'] as $product){
2074
-
2075
- foreach($product['plugins'] as $plugin_slug){
2076
-
2077
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2078
-
2079
- if(!empty($download['free-on-wporg'])) {
2080
- continue;
2081
- }
2082
-
2083
- if( $download['slug'] == $slug || $download['name'] == $name ){
2084
-
2085
- if( !$site_key || !$this->plugin_is_registered($repository_id, $download['slug']) ){
2086
- add_action( "after_plugin_row_" . $plugin_id, array($this, 'show_purchase_notice_under_plugin'), 10, 3 );
2087
- }
2088
-
2089
- }
2090
-
2091
- }
2092
-
2093
- }
2094
-
2095
- }
2096
-
2097
- }
2098
-
2099
- }
2100
-
2101
- }
2102
-
2103
- public function show_purchase_notice_under_plugin($plugin_file, $plugin_data, $status){
2104
-
2105
- $wp_list_table = _get_list_table('WP_Plugins_List_Table');
2106
- ?>
2107
-
2108
- <tr class="plugin-update-tr"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
2109
- <div class="update-message installer-q-icon">
2110
- <?php
2111
- printf(__('You need to have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s.', 'installer'),
2112
- '<a href="' . $this->menu_url() . '">', '</a>');
2113
- ?>
2114
- </div>
2115
- </tr>
2116
-
2117
- <?php
2118
-
2119
- }
2120
-
2121
- public function localize_strings(){
2122
-
2123
- if(!empty($this->settings['repositories'])){
2124
- foreach($this->settings['repositories'] as $repository_id => $repository){
2125
- //set name as call2action when don't have any
2126
- //products
2127
- foreach($repository['data']['packages'] as $package_id => $package){
2128
- foreach($package['products'] as $product_id => $product){
2129
- if(empty($product['call2action'])){
2130
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['call2action'] = $product['name'];
2131
- }
2132
-
2133
- foreach($product['upgrades'] as $idx => $upg){
2134
- if(empty($upg['call2action'])){
2135
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$idx]['call2action'] = $upg['name'];
2136
- }
2137
- }
2138
-
2139
- foreach($product['renewals'] as $idx => $rnw){
2140
- if(empty($rnw['call2action'])){
2141
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['renewals'][$idx]['call2action'] = $rnw['name'];
2142
- }
2143
-
2144
- }
2145
-
2146
- }
2147
- }
2148
- }
2149
- }
2150
-
2151
- global $sitepress;
2152
- if(is_null($sitepress)){
2153
- return;
2154
- }
2155
-
2156
- // default strings are always in English
2157
- $user_admin_language = $sitepress->get_admin_language();
2158
-
2159
- if($user_admin_language != 'en'){
2160
- foreach($this->settings['repositories'] as $repository_id => $repository){
2161
-
2162
- $localization = $repository['data']['localization'];
2163
-
2164
- //packages
2165
- foreach($repository['data']['packages'] as $package_id => $package){
2166
-
2167
- if( isset($localization['packages'][$package_id]['name'][$user_admin_language]) ){
2168
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['name'] = $localization['packages'][$package_id]['name'][$user_admin_language];
2169
- }
2170
- if( isset($localization['packages'][$package_id]['description'][$user_admin_language]) ){
2171
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['description'] = $localization['packages'][$package_id]['description'][$user_admin_language];
2172
- }
2173
-
2174
- }
2175
-
2176
- //products
2177
- foreach($repository['data']['packages'] as $package_id => $package){
2178
- foreach($package['products'] as $product_id => $product){
2179
-
2180
- if( isset($localization['products'][$product_id]['name'][$user_admin_language]) ){
2181
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['name']
2182
- = $localization['products'][$product_id]['name'][$user_admin_language];
2183
- }
2184
- if( isset($localization['products'][$product_id]['description'][$user_admin_language]) ){
2185
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['description']
2186
- = $localization['products'][$product_id]['description'][$user_admin_language];
2187
- }
2188
- if( isset($localization['products'][$product_id]['call2action'][$user_admin_language]) ){
2189
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['name']
2190
- = $localization['products'][$product_id]['call2action'][$user_admin_language];
2191
- }
2192
-
2193
-
2194
- }
2195
- }
2196
-
2197
- //subscription info
2198
- if(isset($repository['data']['subscriptions_meta']['expiration'])){
2199
- foreach($repository['data']['subscriptions_meta']['expiration'] as $subscription_id => $note){
2200
- if(isset($localization['subscriptions-notes'][$subscription_id]['expiration-warning'][$user_admin_language])){
2201
- $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_id]['warning_message']
2202
- = $localization['subscriptions-notes'][$subscription_id]['expiration-warning'][$user_admin_language];
2203
- }
2204
- }
2205
- }
2206
-
2207
- }
2208
- }
2209
-
2210
- }
2211
-
2212
- public function get_matching_cp($repository, $args = array()){
2213
- $match = false;
2214
-
2215
-
2216
- $cp_name = $cp_author = false;
2217
-
2218
- if(isset($this->config['src_name']) && isset($this->config['src_author'])){
2219
-
2220
- $cp_name = $this->config['src_name'];
2221
- $cp_author = $this->config['src_author'];
2222
-
2223
- }elseif(isset($args['src_name']) && isset($args['src_author'])){
2224
-
2225
- $cp_name = $args['src_name'];
2226
- $cp_author = $args['src_author'];
2227
-
2228
- }
2229
-
2230
- if(isset($repository['data']['marketing_cp'])){
2231
-
2232
- foreach($repository['data']['marketing_cp'] as $cp){
2233
-
2234
- if(!empty($cp['exp']) && time() > $cp['exp']){
2235
- continue;
2236
- }
2237
-
2238
- //Use theme_name for plugins too
2239
- if(!empty($cp['theme_name'])){
2240
- if($cp['author_name'] == $cp_author && $cp['theme_name'] == $cp_name){
2241
- $match = $cp;
2242
- continue;
2243
- }
2244
- }else{
2245
- if($cp['author_name'] == $cp_author){
2246
- $match = $cp;
2247
- continue;
2248
- }
2249
- }
2250
-
2251
- }
2252
-
2253
- }
2254
-
2255
- return $match;
2256
- }
2257
-
2258
- public function set_filtered_prices($args = array()){
2259
-
2260
- foreach($this->settings['repositories'] as $repository_id => $repository){
2261
-
2262
- $match = $this->get_matching_cp($repository, $args);
2263
-
2264
- if(empty($match)) continue;
2265
-
2266
- foreach($repository['data']['packages'] as $package_id => $package){
2267
-
2268
- foreach($package['products'] as $product_id => $product){
2269
-
2270
- if($match['dtp'] == '%'){
2271
- $fprice = round( $product['price'] * (1 - $match['amt']/100), 2 );
2272
- $fprice = $fprice != round($fprice) ? sprintf('%.2f', $fprice) : round($fprice, 0);
2273
- }elseif($match['dtp'] == '-'){
2274
- $fprice = $product['price'] - $match['amt'];
2275
- }else{
2276
- $fprice = $product['price'];
2277
- }
2278
-
2279
- if($fprice){
2280
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['price_disc'] = $fprice;
2281
-
2282
- $url_glue = false !== strpos($this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['url'], '?') ? '&' : '?';
2283
- $cpndata = base64_encode(json_encode(array('theme_author' => $match['author_name'], 'theme_name' => $match['theme_name'], 'vlc' => $match['vlc'])));
2284
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['url'] .= $url_glue . 'cpn=' . $cpndata;
2285
-
2286
- foreach($product['upgrades'] as $upgrade_id => $upgrade){
2287
-
2288
- $fprice = false;
2289
- if($match['dtp'] == '%'){
2290
- $fprice = round( $upgrade['price'] * (1 - $match['amt']/100), 2 );
2291
- $fprice = $fprice != round($fprice) ? sprintf('%.2f', $fprice) : round($fprice, 0);
2292
- }elseif($match['dtp'] == '-'){
2293
- $fprice = $upgrade['price'] - $match['amt'];
2294
- }
2295
- if($fprice){
2296
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$upgrade_id]['price_disc'] = $fprice;
2297
- $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$upgrade_id]['url'] .= $url_glue . 'cpn=' . $cpndata;
2298
- }
2299
-
2300
-
2301
- }
2302
-
2303
- }
2304
-
2305
- }
2306
-
2307
- }
2308
-
2309
- }
2310
-
2311
- }
2312
-
2313
- public function set_hierarchy_and_order(){
2314
-
2315
- //2 levels
2316
- if(!empty($this->settings['repositories'])) {
2317
- foreach ($this->settings['repositories'] as $repository_id => $repository) {
2318
-
2319
- if( empty( $repository['data']['packages'] ) ) continue;
2320
-
2321
- $all_packages = $repository['data']['packages'];
2322
- $ordered_packages = array();
2323
-
2324
- //backward compatibility - 'order'
2325
- foreach($all_packages as $k => $v){
2326
- if(!isset($v['order'])){
2327
- $all_packages[$k]['order'] = 0;
2328
- }
2329
- }
2330
-
2331
- //select parents
2332
- foreach ($all_packages as $package_id => $package) {
2333
- if(empty($package['parent'])){
2334
- $ordered_packages[$package_id] = $package;
2335
- }
2336
- }
2337
-
2338
- //add sub-packages
2339
- foreach($all_packages as $package_id => $package){
2340
- if(!empty($package['parent'])) {
2341
- if(isset($ordered_packages[$package['parent']])){
2342
- $ordered_packages[$package['parent']]['sub-packages'][$package_id] = $package;
2343
- }
2344
- }
2345
- }
2346
-
2347
- // order parents
2348
- usort($ordered_packages, array($this, '_order_packages_callback'));
2349
- //order sub-packages
2350
- foreach($ordered_packages as $package_id => $package){
2351
- if(!empty($package['sub-packages'])) {
2352
- usort($ordered_packages[$package_id]['sub-packages'], create_function('$a, $b', 'return $a[\'order\'] > $b[\'order\'];'));
2353
- }
2354
- }
2355
-
2356
- $this->settings['repositories'][$repository_id]['data']['packages'] = $ordered_packages;
2357
-
2358
-
2359
- }
2360
- }
2361
-
2362
-
2363
- }
2364
-
2365
- public function _order_packages_callback($a, $b){
2366
- return $a['order'] > $b['order'];
2367
- }
2368
-
2369
- public function get_support_tag_by_name( $name, $repository ){
2370
-
2371
- if( is_array($this->settings['repositories'][$repository]['data']['support_tags'] )){
2372
- foreach( $this->settings['repositories'][$repository]['data']['support_tags'] as $support_tag){
2373
- if( $support_tag['name'] == $name ){
2374
- return $support_tag['url'];
2375
- }
2376
- }
2377
- }
2378
-
2379
- return false;
2380
- }
2381
-
2382
- public function plugin_upgrade_custom_errors(){
2383
-
2384
- if ( isset($_REQUEST['action']) ) {
2385
-
2386
- $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
2387
-
2388
- //bulk mode
2389
- if('update-selected' == $action) {
2390
-
2391
- global $plugins;
2392
-
2393
- if(isset($plugins) && is_array($plugins)) {
2394
-
2395
- foreach ($plugins as $k => $plugin) {
2396
- $plugin_repository = false;
2397
-
2398
- $wp_plugin_slug = dirname($plugin);
2399
-
2400
- foreach ($this->settings['repositories'] as $repository_id => $repository) {
2401
-
2402
- foreach ($repository['data']['packages'] as $package) {
2403
-
2404
- foreach ($package['products'] as $product) {
2405
-
2406
- foreach ($product['plugins'] as $plugin_slug) {
2407
-
2408
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2409
-
2410
- if ($download['slug'] == $wp_plugin_slug) {
2411
- $plugin_repository = $repository_id;
2412
- $product_name = $repository['data']['product-name'];
2413
- $plugin_name = $download['name'];
2414
- $free_on_wporg = !empty($download['free-on-wporg']);
2415
- break;
2416
- }
2417
-
2418
- }
2419
-
2420
- }
2421
-
2422
- }
2423
-
2424
- }
2425
-
2426
- if ($plugin_repository) {
2427
-
2428
- //validate subscription
2429
- static $sub_cache = array();
2430
-
2431
- if(empty($sub_cache[$plugin_repository])){
2432
- $site_key = $this->get_repository_site_key($plugin_repository);
2433
- if ($site_key) {
2434
- $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2435
- }
2436
-
2437
- $sub_cache[$plugin_repository]['site_key'] = $site_key;
2438
- $sub_cache[$plugin_repository]['subscription_data'] = isset($subscription_data) ? $subscription_data : false;
2439
- }else{
2440
-
2441
- $site_key = $sub_cache[$plugin_repository]['site_key'];
2442
- $subscription_data = $sub_cache[$plugin_repository]['subscription_data'];
2443
-
2444
- }
2445
-
2446
- if(!$site_key && !empty($free_on_wporg)){ // allow the download from wp.org
2447
- continue;
2448
- }
2449
-
2450
- if (empty($site_key) || empty($subscription_data)) {
2451
-
2452
-
2453
- $error_message = sprintf(__("%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer'),
2454
- '<strong>' . $plugin_name . '</strong>', '<a target="_top" href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2455
- '#repository-' . $plugin_repository . '">', $product_name, '</a>');
2456
-
2457
- echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2458
-
2459
- unset($plugins[$k]);
2460
-
2461
-
2462
- }
2463
-
2464
- }
2465
-
2466
- }
2467
-
2468
- }
2469
-
2470
- }
2471
-
2472
-
2473
- if( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
2474
-
2475
- $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
2476
-
2477
- $wp_plugin_slug = dirname($plugin);
2478
-
2479
- $plugin_repository = false;
2480
-
2481
- foreach($this->settings['repositories'] as $repository_id => $repository){
2482
-
2483
- foreach($repository['data']['packages'] as $package){
2484
-
2485
- foreach($package['products'] as $product){
2486
-
2487
- foreach($product['plugins'] as $plugin_slug){
2488
- $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2489
-
2490
- //match by folder, will change to match by name and folder
2491
- if($download['slug'] == $wp_plugin_slug) {
2492
- $plugin_repository = $repository_id;
2493
- $product_name = $repository['data']['product-name'];
2494
- $plugin_name = $download['name'];
2495
- $free_on_wporg = !empty($download['free-on-wporg']);
2496
- break;
2497
- }
2498
-
2499
- }
2500
-
2501
- }
2502
-
2503
- }
2504
-
2505
- }
2506
-
2507
- if($plugin_repository) {
2508
-
2509
- //validate subscription
2510
- $site_key = $this->get_repository_site_key($plugin_repository);
2511
- if ($site_key) {
2512
- $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2513
- }
2514
-
2515
- if ( (empty($site_key) || empty($subscription_data)) && empty($free_on_wporg)) {
2516
-
2517
- $error_message = sprintf(__("%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer'),
2518
- '<strong>'.$plugin_name . '</strong>', '<a href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2519
- '#repository-' . $plugin_repository . '">', $product_name, '</a>');
2520
-
2521
- if(defined('DOING_AJAX')){ //WP 4.2
2522
-
2523
- $status = array(
2524
- 'update' => 'plugin',
2525
- 'plugin' => $plugin,
2526
- 'slug' => sanitize_key( $_POST['slug'] ),
2527
- 'oldVersion' => '',
2528
- 'newVersion' => '',
2529
- );
2530
-
2531
- $status['errorCode'] = 'wp_installer_invalid_subscription';
2532
- $status['error'] = $error_message;
2533
-
2534
- wp_send_json_error( $status );
2535
-
2536
- } else { // WP 4.1.1
2537
- echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2538
-
2539
-
2540
- echo '<div class="wrap">';
2541
- echo '<h2>' . __('Update Plugin') . '</h2>';
2542
- echo '<a href="' . admin_url('plugins.php') . '">' . __('Return to the plugins page') . '</a>';
2543
- echo '</div>';
2544
- require_once(ABSPATH . 'wp-admin/admin-footer.php');
2545
- exit;
2546
-
2547
- }
2548
-
2549
- }
2550
-
2551
-
2552
- }
2553
-
2554
- }
2555
- }
2556
-
2557
- }
2558
-
2559
- }
 
1
+ <?php
2
+
3
+ final class WP_Installer{
4
+ protected static $_instance = null;
5
+
6
+ public $settings = array();
7
+
8
+ private $repositories = array();
9
+
10
+ protected $api_debug = '';
11
+
12
+ private $config = array();
13
+
14
+ protected $_plugins_renew_warnings = array();
15
+
16
+ protected $_gz_on = false;
17
+
18
+ private $admin_messages = array();
19
+
20
+ private $_using_icl = false;
21
+ private $_wpml_version = false;
22
+
23
+ private $package_source = array();
24
+
25
+ const SITE_KEY_VALIDATION_SOURCE_OTHER = 0;
26
+ const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_SPECIFIC = 1;
27
+ const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT = 2;
28
+ const SITE_KEY_VALIDATION_SOURCE_REGISTRATION = 3;
29
+ const SITE_KEY_VALIDATION_SOURCE_REVALIDATION = 4;
30
+ const SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK = 5;
31
+
32
+ public $dependencies;
33
+
34
+ public static function instance() {
35
+
36
+ if ( is_null( self::$_instance ) ) {
37
+ self::$_instance = new self();
38
+ }
39
+
40
+ return self::$_instance;
41
+ }
42
+
43
+ public function __construct(){
44
+
45
+ if(!is_admin() || !is_user_logged_in()) return; //Only for admin
46
+
47
+ $this->_gz_on = function_exists('gzuncompress') && function_exists('gzcompress');
48
+ $this->settings = $this->get_settings();
49
+
50
+ add_action('admin_notices', array($this, 'show_site_key_nags'));
51
+
52
+ add_action('admin_notices', array($this, 'show_admin_messages'));
53
+
54
+ add_action('admin_init', array($this, 'load_embedded_plugins'), 0);
55
+
56
+ add_action('admin_menu', array($this, 'menu_setup'));
57
+ add_action('network_admin_menu', array($this, 'menu_setup'));
58
+
59
+ if(defined('DOING_AJAX') && isset($_POST['action']) && $_POST['action'] == 'installer_download_plugin'){
60
+ add_filter( 'site_transient_update_plugins', array( $this, 'plugins_upgrade_check') );
61
+ }
62
+ add_filter('plugins_api', array( $this, 'custom_plugins_api_call'), 10, 3);
63
+ add_filter('pre_set_site_transient_update_plugins', array( $this, 'plugins_upgrade_check'));
64
+
65
+ // register repositories
66
+ $this->load_repositories_list();
67
+
68
+ if( empty($this->settings['last_repositories_update']) || time() - $this->settings['last_repositories_update'] > 86400
69
+ || ( isset($_GET['force-check']) && $_GET['force-check'] == 1 ) ){
70
+ $this->refresh_repositories_data();
71
+ }
72
+
73
+ // default config
74
+ $this->config['plugins_install_tab'] = false;
75
+
76
+ add_action('init', array($this, 'init'));
77
+
78
+ //add_filter('wp_installer_buy_url', array($this, 'append_parameters_to_buy_url'));
79
+
80
+ add_action('init', array($this,'load_locale'));
81
+
82
+ }
83
+
84
+ public function get_repositories() {
85
+
86
+ return $this->repositories;
87
+
88
+ }
89
+
90
+ public function set_config($key, $value){
91
+
92
+ $this->config[$key] = $value;
93
+
94
+ }
95
+
96
+ public function init(){
97
+ global $pagenow;
98
+
99
+ $this->dependencies = new Installer_Dependencies;
100
+
101
+ if(empty($this->settings['_pre_1_0_clean_up'])) {
102
+ $this->_pre_1_0_clean_up();
103
+ }
104
+
105
+ $this->settings = $this->_old_products_format_backwards_compatibility($this->settings);
106
+
107
+ if ( !function_exists( 'get_plugins' ) ) {
108
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
109
+ }
110
+
111
+ $this->_using_icl = function_exists('wpml_site_uses_icl') && wpml_site_uses_icl();
112
+ $this->_wpml_version = defined('ICL_SITEPRESS_VERSION') ? ICL_SITEPRESS_VERSION : '';
113
+
114
+ wp_enqueue_script('installer-admin', $this->res_url() . '/res/js/admin.js', array('jquery'), $this->version());
115
+ wp_enqueue_style('installer-admin', $this->res_url() . '/res/css/admin.css', array(), $this->version());
116
+
117
+ $translation_array = array(
118
+ 'installing' => __( 'Installing %s', 'installer' ),
119
+ 'updating' => __( 'Updating %s', 'installer' ),
120
+ 'activating' => __( 'Activating %s', 'installer' )
121
+ );
122
+
123
+ wp_localize_script( 'installer-admin', 'installer_strings', $translation_array );
124
+
125
+ if($pagenow == 'plugins.php'){
126
+ add_action('admin_notices', array($this, 'setup_plugins_page_notices'));
127
+ add_action('admin_notices', array($this, 'setup_plugins_renew_warnings'), 10);
128
+ add_action('admin_notices', array($this, 'queue_plugins_renew_warnings'), 20);
129
+
130
+ add_action('admin_init', array($this, 'setup_plugins_action_links'));
131
+
132
+ }
133
+
134
+ if($this->is_repositories_page()){
135
+ add_action('admin_init', array($this, 'validate_repository_subscription'));
136
+ }
137
+
138
+ if(defined('DOING_AJAX')){
139
+ add_action('wp_ajax_save_site_key', array($this, 'save_site_key'));
140
+ add_action('wp_ajax_remove_site_key', array($this, 'remove_site_key'));
141
+ add_action('wp_ajax_update_site_key', array($this, 'update_site_key'));
142
+
143
+ add_action('wp_ajax_installer_download_plugin', array($this, 'download_plugin_ajax_handler'));
144
+ add_action('wp_ajax_installer_activate_plugin', array($this, 'activate_plugin'));
145
+
146
+ add_action('wp_ajax_installer_dismiss_nag', array($this, 'dismiss_nag'));
147
+ }
148
+
149
+ if($pagenow == 'update.php'){
150
+ if(isset($_GET['action']) && $_GET['action'] == 'update-selected'){
151
+ add_action('admin_head', array($this, 'plugin_upgrade_custom_errors')); //iframe/bulk
152
+ }else{
153
+ add_action('all_admin_notices', array($this, 'plugin_upgrade_custom_errors')); //regular/singular
154
+ }
155
+ }
156
+
157
+ // WP 4.2
158
+ if(defined('DOING_AJAX')){
159
+ add_action('wp_ajax_update-plugin', array($this, 'plugin_upgrade_custom_errors'), 0); // high priority, before WP
160
+ }
161
+
162
+ //Include theme support
163
+ include_once $this->plugin_path() . '/includes/class-installer-theme.php';
164
+
165
+ // Extra information about the source of Installer
166
+ $package_source_file = $this->plugin_path() . '/installer-source.json';
167
+ if( file_exists( $package_source_file ) ){
168
+ $this->package_source = json_decode( file_get_contents( $package_source_file ) );
169
+ }
170
+ }
171
+
172
+ protected function log($message){
173
+ if( defined('WPML_INSTALLER_LOGGING') && WPML_INSTALLER_LOGGING ){
174
+ if($fh = @fopen( $this->plugin_path() . '/installer.log', 'a' )){
175
+ fwrite($fh, current_time( 'mysql' ) . "\t" . $message . "\n");
176
+ }
177
+ }
178
+ }
179
+
180
+ public function register_admin_message($text, $type = 'updated'){
181
+ $this->admin_messages[] = array('text' => $text, 'type' => $type);
182
+ }
183
+
184
+ public function show_admin_messages(){
185
+ if(!empty($this->admin_messages)){
186
+ $types = array( 'error', 'updated', 'notice' );
187
+ foreach($this->admin_messages as $message){
188
+ $class = in_array( $message['type'], $types ) ? $message['type'] : 'updated';
189
+ ?>
190
+ <div class="<?php echo $class ?>">
191
+ <p>
192
+ <?php echo $message['text'] ?>
193
+ </p>
194
+ </div>
195
+ <?php
196
+ }
197
+ }
198
+ }
199
+
200
+ public function load_locale(){
201
+ $locale = get_locale();
202
+ $locale = apply_filters( 'plugin_locale', $locale, 'installer' );
203
+ $mo_file = $this->plugin_path() . '/locale/installer-' . $locale . '.mo';
204
+ if(file_exists($mo_file)){
205
+ load_textdomain( 'installer', $mo_file );
206
+ }
207
+ }
208
+
209
+ public function load_embedded_plugins(){
210
+ if(file_exists($this->plugin_path() . '/embedded-plugins' )) {
211
+ include_once $this->plugin_path() . '/embedded-plugins/embedded-plugins.class.php';
212
+ $this->installer_embedded_plugins = new Installer_Embedded_Plugins();
213
+ }
214
+ }
215
+
216
+ public function menu_setup(){
217
+ global $pagenow;
218
+
219
+ if(is_multisite() && !is_network_admin()){
220
+ $this->menu_multisite_redirect();
221
+ add_options_page(__('Installer', 'installer'), __('Installer', 'installer'), 'manage_options', 'installer', array($this, 'show_products')) ;
222
+ }else{
223
+ if($this->config['plugins_install_tab'] && is_admin() && $pagenow == 'plugin-install.php'){
224
+ // Default GUI, under Plugins -> Install
225
+ add_filter('install_plugins_tabs', array($this, 'add_install_plugins_tab'));
226
+ add_action('install_plugins_commercial', array($this, 'show_products'));
227
+ }
228
+ }
229
+
230
+ }
231
+
232
+ public function menu_url(){
233
+ if(is_multisite()){
234
+ if(is_network_admin()){
235
+ $url = network_admin_url('plugin-install.php?tab=commercial');
236
+ }else{
237
+ $url = admin_url('options-general.php?page=installer');
238
+ }
239
+ }else{
240
+ $url = admin_url('plugin-install.php?tab=commercial');
241
+ }
242
+ return $url;
243
+ }
244
+
245
+ private function menu_multisite_redirect(){
246
+ global $pagenow;
247
+
248
+ if($pagenow == 'plugin-install.php' && isset($_GET['tab']) && $_GET['tab'] == 'commercial'){
249
+ wp_redirect($this->menu_url());
250
+ exit;
251
+ }
252
+
253
+ }
254
+
255
+ private function _pre_1_0_clean_up(){
256
+ global $wpdb;
257
+
258
+ if(!defined('WPRC_VERSION')){
259
+ $old_tables = array(
260
+ $wpdb->prefix . 'wprc_cached_requests',
261
+ $wpdb->prefix . 'wprc_extension_types',
262
+ $wpdb->prefix . 'wprc_extensions',
263
+ $wpdb->prefix . 'wprc_repositories',
264
+ $wpdb->prefix . 'wprc_repositories_relationships',
265
+ );
266
+
267
+ foreach($old_tables as $table){
268
+ $wpdb->query(sprintf("DROP TABLE IF EXISTS %s", $table));
269
+ }
270
+
271
+ }
272
+
273
+ $this->settings['_pre_1_0_clean_up'] = true;
274
+ $this->save_settings();
275
+ }
276
+
277
+ public function setup_plugins_action_links(){
278
+
279
+ $plugins = get_plugins();
280
+
281
+ $repositories_plugins = array();
282
+
283
+ if( !empty($this->settings['repositories']) ) {
284
+
285
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
286
+
287
+ foreach ( $repository['data']['packages'] as $package ) {
288
+
289
+ foreach ( $package['products'] as $product ) {
290
+
291
+ foreach ( $product['plugins'] as $plugin_slug ) {
292
+
293
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
294
+
295
+ if ( !isset($repositories_plugins[$repository_id][$download['slug']]) ) {
296
+ $repositories_plugins[$repository_id][$download['slug']] = array(
297
+ 'name' => $download['name'],
298
+ 'registered' => $this->plugin_is_registered( $repository_id, $download['slug'] ) ? 1 : 0
299
+ );
300
+ }
301
+
302
+ }
303
+
304
+ }
305
+
306
+ }
307
+
308
+ foreach ( $plugins as $plugin_id => $plugin ) {
309
+
310
+ $wp_plugin_slug = dirname( $plugin_id );
311
+ if ( empty($wp_plugin_slug) ) {
312
+ $wp_plugin_slug = basename( $plugin_id, '.php' );
313
+ }
314
+
315
+ foreach ( $repositories_plugins as $repository_id => $r_plugins ) {
316
+
317
+ foreach ( $r_plugins as $slug => $r_plugin ) {
318
+
319
+ if ( $wp_plugin_slug == $slug || $r_plugin['name'] == $plugin['Name'] || $r_plugin['name'] == $plugin['Title'] ) { //match order: slug, name, title
320
+
321
+ if ( $r_plugin['registered'] ) {
322
+ add_filter( 'plugin_action_links_' . $plugin_id, array($this, 'plugins_action_links_registered') );
323
+ } else {
324
+ add_filter( 'plugin_action_links_' . $plugin_id, array($this, 'plugins_action_links_not_registered') );
325
+ }
326
+
327
+ }
328
+
329
+ }
330
+
331
+ }
332
+
333
+
334
+ }
335
+
336
+ }
337
+ }
338
+
339
+ }
340
+
341
+ public function plugins_action_links_registered($links){
342
+ $links[] = '<a href="' . $this->menu_url() . '">' . __('Registered', 'installer') . '</a>';
343
+ return $links;
344
+ }
345
+
346
+ public function plugins_action_links_not_registered($links){
347
+ $links[] = '<a href="' . $this->menu_url() . '">' . __('Register', 'installer') . '</a>';
348
+ return $links;
349
+ }
350
+
351
+ public function plugin_is_registered($repository_id, $slug){
352
+
353
+ $registered = false;
354
+
355
+ if( $this->repository_has_valid_subscription($repository_id) ){
356
+
357
+ $subscription_type = $this->get_subscription_type_for_repository($repository_id);
358
+ $r_plugins = array();
359
+
360
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
361
+
362
+ foreach($package['products'] as $product){
363
+
364
+ if( $product['subscription_type'] == $subscription_type || $this->have_superior_subscription($subscription_type, $product) ) {
365
+
366
+ foreach ($product['plugins'] as $plugin_slug) {
367
+
368
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
369
+
370
+ if (!isset($rep_plugins[$download['slug']])) {
371
+ $r_plugins[$download['slug']] = $download['slug'];
372
+ }
373
+
374
+ }
375
+
376
+ }
377
+
378
+ }
379
+
380
+ }
381
+
382
+ $registered = isset($r_plugins[$slug]);
383
+
384
+ }
385
+
386
+
387
+ return $registered;
388
+
389
+ }
390
+
391
+ public function version(){
392
+ return WP_INSTALLER_VERSION;
393
+ }
394
+
395
+ public function plugin_path() {
396
+ return untrailingslashit( plugin_dir_path( dirname(__FILE__) ) );
397
+ }
398
+
399
+ public function plugin_url() {
400
+ if(isset($this->config['in_theme_folder']) && !empty($this->config['in_theme_folder'])){
401
+ $url = untrailingslashit(get_template_directory_uri() . '/' . $this->config['in_theme_folder']);
402
+ }else{
403
+ $url = untrailingslashit( plugins_url( '/', dirname(__FILE__) ) );
404
+ }
405
+
406
+ return $url;
407
+ }
408
+
409
+ public function is_repositories_page(){
410
+ global $pagenow;
411
+
412
+ return $pagenow == 'plugin-install.php' && isset($_GET['tab']) && $_GET['tab'] == 'commercial';
413
+ }
414
+
415
+ public function res_url(){
416
+ if(isset($this->config['in_theme_folder']) && !empty($this->config['in_theme_folder'])){
417
+ $url = untrailingslashit(get_template_directory_uri() . '/' . $this->config['in_theme_folder']);
418
+ }else{
419
+ $url = $this->plugin_url();
420
+ }
421
+ return $url;
422
+ }
423
+
424
+ public function save_settings(){
425
+
426
+ $_settings = serialize($this->settings);
427
+ if($this->_gz_on){
428
+ $_settings = gzcompress($_settings);
429
+ }
430
+ $_settings = base64_encode($_settings);
431
+
432
+ update_option( 'wp_installer_settings', $_settings );
433
+
434
+ if( is_multisite() && is_main_site() && isset($this->settings['repositories']) ){
435
+ $network_settings = array();
436
+
437
+ foreach( $this->settings['repositories'] as $rep_id => $repository ){
438
+ if( isset($repository['subscription']) )
439
+ $network_settings[$rep_id] = $repository['subscription'];
440
+ }
441
+
442
+ update_site_option( 'wp_installer_network', $network_settings );
443
+
444
+
445
+ }
446
+
447
+ }
448
+
449
+ public function get_settings($refresh = false){
450
+
451
+ if($refresh || empty($this->settings)){
452
+
453
+ $_settings = get_option('wp_installer_settings');
454
+
455
+
456
+ if (is_array($_settings) || empty($_settings)) { //backward compatibility 1.1
457
+ $this->settings = $_settings;
458
+
459
+ } else {
460
+ $_settings = base64_decode($_settings);
461
+ if ($this->_gz_on) {
462
+ $_settings = gzuncompress($_settings);
463
+ }
464
+ $this->settings = unserialize($_settings);
465
+ }
466
+
467
+ if (is_multisite() && isset($this->settings['repositories'])) {
468
+ $network_settings = maybe_unserialize(get_site_option('wp_installer_network'));
469
+ if ($network_settings) {
470
+ foreach ($this->settings['repositories'] as $rep_id => $repository) {
471
+ if (isset($network_settings[$rep_id])) {
472
+ $this->settings['repositories'][$rep_id]['subscription'] = $network_settings[$rep_id];
473
+ }
474
+ }
475
+ }
476
+ }
477
+
478
+
479
+ $this->settings = $this->_pre_1_6_backwards_compatibility($this->settings);
480
+
481
+ $this->settings = $this->_old_products_format_backwards_compatibility($this->settings);
482
+
483
+ }
484
+
485
+
486
+ return $this->settings;
487
+ }
488
+
489
+ //backward compatibility, will remove 'basename' in version 1.8
490
+ private function _pre_1_6_backwards_compatibility($settings){
491
+
492
+ if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) ){
493
+
494
+ foreach ($settings['repositories'] as $repository_id => $repository) {
495
+
496
+ foreach ($repository['data']['downloads']['plugins'] as $slug => $download) {
497
+
498
+ $settings['repositories'][$repository_id]['data']['downloads']['plugins'][$slug]['slug'] = $download['basename'];
499
+
500
+ }
501
+ }
502
+
503
+ }
504
+
505
+ return $settings;
506
+
507
+ }
508
+
509
+ //backward compatibility - support old products list format (downloads under products instead of global downloads list)
510
+ private function _old_products_format_backwards_compatibility($settings){
511
+
512
+ if( version_compare($this->version(), '1.8', '<') && !empty($settings['repositories']) && empty($this->_old_products_format_backwards_compatibility) ) {
513
+
514
+ foreach ($settings['repositories'] as $repository_id => $repository) {
515
+
516
+ $populate_downloads = false;
517
+
518
+ foreach ($repository['data']['packages'] as $package_id => $package) {
519
+
520
+ foreach ($package['products'] as $product_id => $product) {
521
+
522
+ if (!isset($product['plugins'])) {
523
+
524
+ $populate_downloads = true;
525
+
526
+ foreach ($product['downloads'] as $download_id => $download) {
527
+
528
+ $settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['plugins'][] = $download['slug'];
529
+
530
+ }
531
+
532
+ }
533
+
534
+ }
535
+
536
+ }
537
+
538
+ if ($populate_downloads) {
539
+
540
+ // Add downloads branch
541
+ foreach ($repository['data']['packages'] as $package_id => $package) {
542
+
543
+ foreach ($package['products'] as $product_id => $product) {
544
+
545
+ foreach ($product['downloads'] as $download_id => $download) {
546
+
547
+ if (!isset($settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']])) {
548
+ $settings['repositories'][$repository_id]['data']['downloads']['plugins'][$download['slug']] = $download;
549
+ }
550
+
551
+ $settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['plugins'][] = $download['slug'];
552
+ }
553
+
554
+ unset($settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['downloads']);
555
+
556
+ }
557
+
558
+ }
559
+
560
+ }
561
+
562
+ }
563
+
564
+ $this->_old_products_format_backwards_compatibility = true;
565
+
566
+ }
567
+
568
+ return $settings;
569
+
570
+ }
571
+
572
+ public function get_installer_site_url( $repository_id = false ){
573
+ global $current_site;
574
+
575
+ $site_url = get_site_url();
576
+
577
+ if( $repository_id && is_multisite() && isset( $this->settings['repositories'] ) ){
578
+ $network_settings = maybe_unserialize( get_site_option('wp_installer_network') );
579
+
580
+ if ( isset( $network_settings[$repository_id] ) ) {
581
+ $site_url = get_site_url( $current_site->blog_id );
582
+ }
583
+
584
+ }
585
+
586
+ return $site_url;
587
+ }
588
+
589
+ public function show_site_key_nags(){
590
+ $screen = get_current_screen();
591
+
592
+ if($screen->base == 'settings_page_installer' || ($screen->base == 'plugin-install' && isset($_GET['tab']) && $_GET['tab'] == 'commercial')){
593
+ return;
594
+ }
595
+
596
+ if(!empty($this->config['site_key_nags'])){
597
+
598
+ foreach($this->config['site_key_nags'] as $nag){
599
+
600
+ if(!$this->repository_has_subscription($nag['repository_id'] )){
601
+ $show = true;
602
+ if(!empty($nag['condition_cb'])){
603
+ $show = call_user_func($nag['condition_cb']);
604
+ }
605
+
606
+ if(empty($this->settings['dismissed_nags'][$nag['repository_id']]) && $show){
607
+ echo '<div class="updated error otgs-is-dismissible"><p>';
608
+ printf(__("To get automatic updates, you need to register %s for this site. %sRegister %s%s", 'sitepress'),
609
+ $nag['product_name'], '<a class="button-primary" href="' . $this->menu_url() . '">', $nag['product_name'], '</a>');
610
+
611
+ echo '</p>';
612
+ echo '<span class="installer-dismiss-nag notice-dismiss" data-repository="' . $nag['repository_id'] . '"><span class="screen-reader-text">' . __('Dismiss', 'sitepress') . '</span></span>';
613
+ echo '</div>';
614
+ }
615
+ }
616
+
617
+ }
618
+
619
+ }
620
+
621
+ }
622
+
623
+ public function dismiss_nag(){
624
+ $this->settings['dismissed_nags'][$_POST['repository']] = 1;
625
+
626
+ $this->save_settings();
627
+
628
+ echo json_encode(array());
629
+ exit;
630
+ }
631
+
632
+ public function add_install_plugins_tab($tabs){
633
+
634
+ $tabs['commercial'] = __('Commercial', 'installer');
635
+
636
+ return $tabs;
637
+ }
638
+
639
+ public function load_repositories_list(){
640
+ global $wp_installer_instances;
641
+
642
+ foreach ($wp_installer_instances as $instance) {
643
+
644
+ if (file_exists(dirname($instance['bootfile']) . '/repositories.xml')) {
645
+ $config_file = dirname($instance['bootfile']) . '/repositories.xml';
646
+
647
+ if (file_exists(dirname($instance['bootfile']) . '/repositories.sandbox.xml')) {
648
+ $config_file = dirname($instance['bootfile']) . '/repositories.sandbox.xml';
649
+ add_filter('https_ssl_verify', '__return_false');
650
+ }
651
+
652
+ $repos = simplexml_load_file($config_file);
653
+
654
+ if($repos) {
655
+ foreach ($repos as $repo) {
656
+ $id = strval($repo->id);
657
+
658
+ $data['api-url'] = strval($repo->apiurl);
659
+ $data['products'] = strval($repo->products);
660
+
661
+ // excludes rule;
662
+ if (isset($this->config['repositories_exclude']) && in_array($id, $this->config['repositories_exclude'])) {
663
+ continue;
664
+ }
665
+
666
+ // includes rule;
667
+ if (isset($this->config['repositories_include']) && !in_array($id, $this->config['repositories_include'])) {
668
+ continue;
669
+ }
670
+
671
+ $this->repositories[$id] = $data;
672
+
673
+ }
674
+ }
675
+
676
+ }
677
+ }
678
+
679
+ }
680
+
681
+ public function filter_repositories_list(){
682
+
683
+ if(!empty($this->settings['repositories'])) {
684
+ foreach ($this->settings['repositories'] as $id => $repo_data) {
685
+
686
+ // excludes rule;
687
+ if (isset($this->config['repositories_exclude']) && in_array($id, $this->config['repositories_exclude'])) {
688
+ unset($this->settings['repositories'][$id]);
689
+ }
690
+
691
+ // includes rule;
692
+ if (isset($this->config['repositories_include']) && !in_array($id, $this->config['repositories_include'])) {
693
+ unset($this->settings['repositories'][$id]);
694
+ }
695
+
696
+
697
+ }
698
+ }
699
+
700
+
701
+ }
702
+
703
+ public function refresh_repositories_data(){
704
+ static $checked = false;
705
+
706
+ if( defined('OTGS_DISABLE_AUTO_UPDATES') && OTGS_DISABLE_AUTO_UPDATES && empty($_GET['force-check']) || $checked ){
707
+
708
+ if(empty($this->settings['repositories']) && $this->is_repositories_page()){
709
+
710
+ foreach($this->repositories as $id => $data) {
711
+ $repository_names[] = $id;
712
+
713
+ }
714
+
715
+ $error = sprintf(__("Installer cannot display the products information because the automatic updating for %s was explicitly disabled with the configuration below (usually in wp-config.php):", 'installer'), strtoupper( join(', ', $repository_names) ));
716
+ $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code><br /><br />';
717
+ $error .= sprintf(__("In order to see the products information, please run the %smanual updates check%s to initialize the products list or (temporarily) remove the above code.", 'installer'), '<a href="' . admin_url('update-core.php') . '">', '</a>');
718
+
719
+ $this->register_admin_message($error, 'error');
720
+
721
+
722
+ }
723
+
724
+ return;
725
+ }
726
+
727
+ $checked = true;
728
+
729
+ foreach($this->repositories as $id => $data){
730
+
731
+ $response = wp_remote_get($data['products']);
732
+
733
+ if(is_wp_error($response)){
734
+ // http fallback
735
+ $data['products'] = preg_replace("@^https://@", 'http://', $data['products']);
736
+ $response = wp_remote_get($data['products']);
737
+ }
738
+
739
+ if(is_wp_error($response)){
740
+
741
+ $error = sprintf(__("Installer cannot contact our updates server to get information about the available products and check for new versions. If you are seeing this message for the first time, you can ignore it, as it may be a temporary communication problem. If the problem persists and your WordPress admin is slowing down, you can disable automated version checks. Add the following line to your wp-config.php file:", 'installer'), strtoupper($id));
742
+ $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code>';
743
+
744
+ $this->register_admin_message($error, 'error');
745
+
746
+ continue;
747
+ }
748
+
749
+ if($response && isset($response['response']['code']) && $response['response']['code'] == 200){
750
+ $body = wp_remote_retrieve_body($response);
751
+ if($body){
752
+ $products = json_decode($body, true);
753
+
754
+ if(is_array($products)){
755
+ $this->settings['repositories'][$id]['data'] = $products;
756
+ $this->settings = $this->_pre_1_6_backwards_compatibility($this->settings);
757
+ }
758
+ }
759
+
760
+ }
761
+
762
+ $this->log( sprintf("Checked for %s updates: %s", $id, $data['products']) );
763
+
764
+
765
+ }
766
+
767
+ // cleanup
768
+ if(empty($this->settings['repositories'])){
769
+ $this->settings['repositories'] = array();
770
+ }
771
+ foreach($this->settings['repositories'] as $id => $data){
772
+ if(!in_array($id, array_keys($this->repositories))){
773
+ unset($this->settings['repositories'][$id]);
774
+ }
775
+ }
776
+
777
+ $this->settings['last_repositories_update']= time();
778
+
779
+ $this->save_settings();
780
+
781
+ }
782
+
783
+ public function show_products($args = array()){
784
+
785
+ $screen = get_current_screen();
786
+
787
+ if($screen->base == 'settings_page_installer'){ // settings page
788
+ echo '<div class="wrap">';
789
+ echo '<h2>' . __('Installer', 'installer') . '</h2>';
790
+ echo '<br />';
791
+ }
792
+
793
+ if(!is_array($args)) $args = array();
794
+ if(empty($args['template'])) $args['template'] = 'default';
795
+
796
+ $this->filter_repositories_list();
797
+
798
+ if(!empty($this->settings['repositories'])){
799
+
800
+ $this->localize_strings();
801
+ $this->set_filtered_prices($args);
802
+ $this->set_hierarchy_and_order();
803
+
804
+ foreach($this->settings['repositories'] as $repository_id => $repository){
805
+
806
+ if($args['template'] == 'compact'){
807
+
808
+ if(isset($args['repository']) && $args['repository'] == $repository_id){
809
+ include $this->plugin_path() . '/templates/products-compact.php';
810
+ }
811
+
812
+ }else{
813
+
814
+ include $this->plugin_path() . '/templates/repository-listing.php';
815
+
816
+ }
817
+
818
+ unset($site_key, $subscription_type, $expired, $upgrade_options, $products_avaliable);
819
+
820
+ }
821
+
822
+ }else{
823
+
824
+ echo '<center>' . __('No repositories defined.', 'installer') . '</center>';
825
+
826
+ }
827
+
828
+ if($screen->base == 'settings_page_installer'){ // settings page
829
+ echo '</div>';
830
+ }
831
+
832
+
833
+ }
834
+
835
+ public function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
836
+
837
+ $price = false;
838
+
839
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package ){
840
+
841
+ if($package['id'] == $package_id){
842
+ if(isset($package['products'][$product_id])){
843
+ if($incl_discount && isset($package['products'][$product_id]['price_disc'])){
844
+ $price = $package['products'][$product_id]['price_disc'];
845
+ }elseif(isset($package['products'][$product_id]['price'])){
846
+ $price = $package['products'][$product_id]['price'];
847
+ }
848
+ }
849
+ break;
850
+ }
851
+ }
852
+
853
+ return $price;
854
+ }
855
+
856
+ private function _render_product_packages($packages, $subscription_type, $expired, $upgrade_options, $repository_id){
857
+
858
+ $data = array();
859
+
860
+ foreach($packages as $package_id => $package){
861
+
862
+ $row = array('products' => array(), 'downloads' => array());
863
+ foreach($package['products'] as $product){
864
+
865
+ // filter out free subscriptions from being displayed as buying options
866
+ if( empty($product['price']) && (empty($subscription_type) || $expired) ){
867
+ continue;
868
+ }
869
+
870
+ // buy base
871
+ if(empty($subscription_type) || $expired) {
872
+
873
+ $p['url'] = $this->append_parameters_to_buy_url($product['url'], $repository_id);
874
+ if (!empty($product['price_disc'])) {
875
+ $p['label'] = $product['call2action'] . ' - ' . sprintf('$%s %s$%d%s (USD)', $product['price_disc'], '&nbsp;&nbsp;<del>', $product['price'], '</del>');
876
+ } else {
877
+ $p['label'] = $product['call2action'] . ' - ' . sprintf('$%d (USD)', $product['price']);
878
+ }
879
+ $row['products'][] = $p;
880
+
881
+ // renew
882
+ } elseif(isset($subscription_type) && $product['subscription_type'] == $subscription_type){
883
+
884
+ if($product['renewals']) {
885
+ foreach ($product['renewals'] as $renewal) {
886
+ $p['url'] = $this->append_parameters_to_buy_url($renewal['url'], $repository_id);
887
+ $p['label'] = $renewal['call2action'] . ' - ' . sprintf('$%d (USD)', $renewal['price']);
888
+ }
889
+
890
+ $row['products'][] = $p;
891
+ }
892
+
893
+ }
894
+
895
+ // upgrades
896
+ if(!empty($upgrade_options[$product['subscription_type']])){
897
+
898
+ foreach($upgrade_options[$product['subscription_type']] as $stype => $upgrade){
899
+ if($stype != $subscription_type) continue;
900
+
901
+ $p['url'] = $this->append_parameters_to_buy_url($upgrade['url'], $repository_id);
902
+ if (!empty($upgrade['price_disc'])) {
903
+ $p['label'] = $upgrade['call2action'] . ' - ' . sprintf('$%s %s$%d%s (USD)', $upgrade['price_disc'], '&nbsp;&nbsp;<del>', $upgrade['price'], '</del>');
904
+ } else {
905
+ $p['label'] = $upgrade['call2action'] . ' - ' . sprintf('$%d (USD)', $upgrade['price']);
906
+ }
907
+ $row['products'][] = $p;
908
+
909
+ }
910
+
911
+ }
912
+
913
+ // downloads
914
+ if(isset($subscription_type) && !$expired && $product['subscription_type'] == $subscription_type){
915
+ foreach($product['plugins'] as $plugin_slug){
916
+
917
+ $row['downloads'][] = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
918
+
919
+ }
920
+
921
+ }
922
+
923
+ //subpackages
924
+ if(!empty($package['sub-packages'])){
925
+ $row['sub-packages'] = $package['sub-packages'];
926
+ }
927
+
928
+ }
929
+
930
+ $row['id'] = $package['id'];
931
+ $row['image_url'] = $package['image_url'];
932
+ $row['name'] = $package['name'];
933
+ $row['description'] = $package['description'];
934
+
935
+ if(!empty($row['products']) || !empty($row['downloads']) || !empty($row['sub-packages'])){
936
+ $data[] = $row;
937
+ }
938
+
939
+
940
+ }
941
+
942
+ return $data;
943
+
944
+ }
945
+
946
+ public function get_extra_url_parameters(){
947
+
948
+ $parameters = array();
949
+
950
+ if(!empty($this->package_source)){
951
+ foreach($this->package_source as $key => $val){
952
+ $parameters[$key] = $val;
953
+ }
954
+ }
955
+
956
+ $parameters['installer_version'] = WP_INSTALLER_VERSION;
957
+ $parameters['theme'] = wp_get_theme()->get( 'Name' );
958
+ $parameters['site_name'] = get_bloginfo( 'name' );
959
+
960
+ return $parameters;
961
+ }
962
+
963
+ public function append_parameters_to_buy_url($url, $repository_id, $args = array()){
964
+
965
+ $url = add_query_arg( array('icl_site_url' => $this->get_installer_site_url( $repository_id ) ), $url );
966
+
967
+ $affiliate_id = false;
968
+ $affiliate_key = false;
969
+
970
+ // Add extra parameters for custom Installer packages
971
+ if( !empty($this->package_source) ){
972
+ $extra = $this->get_extra_url_parameters();
973
+
974
+ if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
975
+
976
+ if( !empty($extra['affiliate_key']) && !empty($extra['user_id']) ){
977
+ $this->config['affiliate_id:' . $repository_id] = $extra['user_id'];
978
+ $this->config['affiliate_key:' . $repository_id] = $extra['affiliate_key'];
979
+ unset($extra['affiliate_key'], $extra['user_id'], $extra['repository']); // no need to include these ones
980
+ }
981
+
982
+ $url = add_query_arg($extra, $url);
983
+ }
984
+
985
+ }
986
+
987
+ if(isset($this->config['affiliate_id:' . $repository_id]) && isset($this->config['affiliate_key:' . $repository_id])){
988
+
989
+ $affiliate_id = $this->config['affiliate_id:' . $repository_id];
990
+ $affiliate_key = $this->config['affiliate_key:' . $repository_id];
991
+
992
+ }elseif(isset($args['affiliate_id:' . $repository_id]) && isset($args['affiliate_key:' . $repository_id])){
993
+
994
+ $affiliate_id = $args['affiliate_id:' . $repository_id];
995
+ $affiliate_key = $args['affiliate_key:' . $repository_id];
996
+
997
+ }elseif(defined('ICL_AFFILIATE_ID') && defined('ICL_AFFILIATE_KEY')){ //support for 1 repo
998
+
999
+ $affiliate_id = ICL_AFFILIATE_ID;
1000
+ $affiliate_key = ICL_AFFILIATE_KEY;
1001
+
1002
+ }elseif(isset($this->config['affiliate_id']) && isset($this->config['affiliate_key'])) {
1003
+ // BACKWARDS COMPATIBILITY
1004
+ $affiliate_id = $this->config['affiliate_id'];
1005
+ $affiliate_key = $this->config['affiliate_key'];
1006
+ }
1007
+
1008
+ if($affiliate_id && $affiliate_key){
1009
+ $url = add_query_arg(array('aid' => $affiliate_id, 'affiliate_key' => $affiliate_key), $url);
1010
+ }
1011
+
1012
+ if($repository_id == 'wpml'){
1013
+ $url = add_query_arg(array('using_icl' => $this->_using_icl, 'wpml_version' => $this->_wpml_version), $url);
1014
+ }
1015
+
1016
+ $url = apply_filters('wp_installer_buy_url', $url);
1017
+
1018
+ $url = esc_url($url);
1019
+
1020
+ return $url;
1021
+
1022
+ }
1023
+
1024
+ public function save_site_key($args = array()){
1025
+
1026
+ $error = '';
1027
+
1028
+ $repository_id = isset($args['repository_id']) ? $args['repository_id'] : (isset($_POST['repository_id']) ? $_POST['repository_id'] : false);
1029
+ $nonce = isset($args['nonce']) ? $args['nonce'] : (isset($_POST['nonce']) ? $_POST['nonce'] : '');
1030
+ $site_key = isset($args['site_key']) ? $args['site_key'] : $_POST['site_key_' . $repository_id];
1031
+
1032
+ $site_key = preg_replace("/[^A-Za-z0-9]/", '', $site_key);
1033
+
1034
+ if($repository_id && $nonce && wp_create_nonce('save_site_key_' . $repository_id) == $nonce){
1035
+
1036
+ try {
1037
+ $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REGISTRATION );
1038
+
1039
+ if ( $subscription_data ) {
1040
+ $this->settings['repositories'][$repository_id]['subscription'] = array('key' => $site_key, 'data' => $subscription_data);
1041
+ $this->save_settings();
1042
+ } else {
1043
+ $error = __( 'Invalid site key for the current site.', 'installer' );
1044
+ }
1045
+
1046
+ } catch (Exception $e ){
1047
+ $error = $e->getMessage();
1048
+ if( preg_match('#Could not resolve host: (.*)#', $error, $matches) || preg_match('#Couldn\'t resolve host \'(.*)\'#', $error, $matches) ){
1049
+ $error = sprintf(__("%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer'),
1050
+ '<strong><i>' . $this->get_generic_product_name($repository_id) . '</i></strong>',
1051
+ '<strong><i>' . $matches[1]. '</i></strong>'
1052
+ ) ;
1053
+ }
1054
+ }
1055
+
1056
+ }
1057
+
1058
+ $return = array('error' => $error);
1059
+
1060
+ if($this->api_debug){
1061
+ $return['debug'] = $this->api_debug;
1062
+ }
1063
+
1064
+ if(!empty($args['return'])){
1065
+ return $return;
1066
+ }else{
1067
+ echo json_encode($return);
1068
+ exit;
1069
+ }
1070
+
1071
+ }
1072
+
1073
+ /**
1074
+ * Alias for WP_Installer::get_repository_site_key
1075
+ * @see WP_Installer::get_repository_site_key()
1076
+ *
1077
+ * @param string $repository_id
1078
+ * @return string (site key) or bool
1079
+ */
1080
+ public function get_site_key($repository_id){
1081
+ return WP_Installer::get_repository_site_key( $repository_id );
1082
+ }
1083
+
1084
+ public function remove_site_key(){
1085
+ if($_POST['nonce'] == wp_create_nonce('remove_site_key_' . $_POST['repository_id'])){
1086
+ unset($this->settings['repositories'][$_POST['repository_id']]['subscription']);
1087
+ $this->save_settings();
1088
+
1089
+ $this->refresh_repositories_data();
1090
+ }
1091
+ exit;
1092
+ }
1093
+
1094
+ public function validate_repository_subscription(){
1095
+ $repository_id = isset($_GET['validate_repository']) ? $_GET['validate_repository'] : false;
1096
+ if($repository_id){
1097
+
1098
+ $site_key = $this->get_site_key($repository_id);
1099
+ if($site_key) {
1100
+ $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION);
1101
+ if(empty($subscription_data)){
1102
+ unset($this->settings['repositories'][$repository_id]['subscription']);
1103
+ delete_site_transient('update_plugins');
1104
+ $this->save_settings();
1105
+ }
1106
+ }
1107
+
1108
+ wp_redirect($this->menu_url() . '#repository-' . $repository_id);
1109
+ exit;
1110
+
1111
+ }
1112
+
1113
+ }
1114
+
1115
+ public function update_site_key(){
1116
+
1117
+ $error = '';
1118
+
1119
+ if($_POST['nonce'] == wp_create_nonce('update_site_key_' . $_POST['repository_id'])){
1120
+
1121
+ $repository_id = $_POST['repository_id'];
1122
+ $site_key = $this->get_site_key($_POST['repository_id']);
1123
+
1124
+ if($site_key){
1125
+ try {
1126
+ $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK );
1127
+
1128
+ if ( $subscription_data ) {
1129
+ $this->settings['repositories'][$repository_id]['subscription'] = array('key' => $site_key, 'data' => $subscription_data);
1130
+
1131
+ //also refresh products information
1132
+ $this->refresh_repositories_data();
1133
+
1134
+ $this->save_settings();
1135
+
1136
+ } else {
1137
+ unset($this->settings['repositories'][$repository_id]['subscription']);
1138
+ $error = __( 'Invalid site key for the current site. If the error persists, try to unregister first and then register again with the same site key.', 'installer' );
1139
+ }
1140
+
1141
+
1142
+ } catch (Exception $e ){
1143
+ $error = $e->getMessage();
1144
+ if( preg_match('#Could not resolve host: (.*)#', $error, $matches) || preg_match('#Couldn\'t resolve host \'(.*)\'#', $error, $matches) ){
1145
+ $error = sprintf(__("%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer'),
1146
+ '<strong><i>' . $this->get_generic_product_name($repository_id) . '</i></strong>',
1147
+ '<strong><i>' . $matches[1]. '</i></strong>'
1148
+ ) ;
1149
+ }
1150
+ }
1151
+
1152
+ }
1153
+
1154
+ }
1155
+
1156
+ echo json_encode(array('error' => $error));
1157
+
1158
+ exit;
1159
+ }
1160
+
1161
+ public function api_debug_log($text){
1162
+
1163
+ if(defined('WPML_DEBUG_INSTALLER') && WPML_DEBUG_INSTALLER){
1164
+
1165
+ if(!is_scalar($text)){
1166
+ $text = print_r($text, 1);
1167
+ }
1168
+
1169
+ $this->api_debug .= $text . "\n";
1170
+
1171
+ }
1172
+
1173
+ }
1174
+
1175
+ public function fetch_subscription_data( $repository_id, $site_key, $source = self::SITE_KEY_VALIDATION_SOURCE_OTHER ){
1176
+
1177
+ $subscription_data = false;
1178
+
1179
+ $args['body'] = array(
1180
+ 'action' => 'site_key_validation',
1181
+ 'site_key' => $site_key,
1182
+ 'site_url' => $this->get_installer_site_url( $repository_id ),
1183
+ 'source' => $source
1184
+ );
1185
+
1186
+ if($repository_id == 'wpml'){
1187
+ $args['body']['using_icl'] = $this->_using_icl;
1188
+ $args['body']['wpml_version'] = $this->_wpml_version;
1189
+ }
1190
+
1191
+ $args['body']['installer_version'] = WP_INSTALLER_VERSION;
1192
+ $args['body']['theme'] = wp_get_theme()->get( 'Name' );
1193
+ $args['body']['site_name'] = get_bloginfo( 'name' );
1194
+
1195
+ $args['body']['versions'] = $this->get_local_product_versions( $repository_id );
1196
+
1197
+ $args['timeout'] = 45;
1198
+
1199
+ // Add extra parameters for custom Installer packages
1200
+ if( !empty($this->package_source) ){
1201
+ $extra = $this->get_extra_url_parameters();
1202
+ if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
1203
+ unset($extra['repository']);
1204
+ foreach($extra as $key => $val){
1205
+ $args['body'][$key] = $val;
1206
+ }
1207
+ }
1208
+ }
1209
+
1210
+ $response = wp_remote_post($this->repositories[$repository_id]['api-url'], $args);
1211
+
1212
+ $this->api_debug_log("POST {$this->repositories[$repository_id]['api-url']}");
1213
+ $this->api_debug_log($args);
1214
+
1215
+ $this->log("POST {$this->repositories[$repository_id]['api-url']} - fetch subscription data");
1216
+
1217
+ if( !is_wp_error($response) ){
1218
+ $datas = wp_remote_retrieve_body($response);
1219
+
1220
+ if(is_serialized($datas)){
1221
+ $data = unserialize($datas);
1222
+ $this->api_debug_log($data);
1223
+
1224
+ if( !empty( $data->subscription_data ) ){
1225
+ $subscription_data = $data->subscription_data;
1226
+ }
1227
+
1228
+ do_action( 'installer_fetched_subscription_data', $data, $repository_id);
1229
+
1230
+ }else{
1231
+ $this->api_debug_log($datas);
1232
+ }
1233
+
1234
+ }else{
1235
+
1236
+ $this->api_debug_log($response);
1237
+ throw new Exception( $response->get_error_message() );
1238
+ }
1239
+
1240
+ return $subscription_data;
1241
+
1242
+ }
1243
+
1244
+ function get_local_product_versions( $repository_id ){
1245
+
1246
+ $versions = array();
1247
+
1248
+ foreach( $this->settings['repositories'][$repository_id]['data']['packages'] as $package_id => $package ){
1249
+
1250
+ foreach( $package['products'] as $product_id => $product ){
1251
+
1252
+ foreach( $product['plugins'] as $plugin_slug ){
1253
+
1254
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1255
+
1256
+ if( empty( $versions[$download['slug']] ) ) {
1257
+ $v = $this->get_plugin_installed_version($download['name'], $download['slug']);
1258
+ if($v){
1259
+ $versions[$download['slug']] = $v;
1260
+ }
1261
+ }
1262
+
1263
+ }
1264
+
1265
+ }
1266
+
1267
+ }
1268
+
1269
+ return $versions;
1270
+ }
1271
+
1272
+ public function get_repository_site_key($repository_id){
1273
+ $site_key = false;
1274
+
1275
+ if(!empty($this->settings['repositories'][$repository_id]['subscription']['key'])){
1276
+ $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1277
+ }
1278
+
1279
+ return $site_key;
1280
+ }
1281
+
1282
+ public function repository_has_valid_subscription($repository_id){
1283
+
1284
+ $valid = false;
1285
+
1286
+ if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1287
+
1288
+ $subscription = $this->settings['repositories'][$repository_id]['subscription']['data'];
1289
+ $valid = ( $subscription->status == 1 && (strtotime($subscription->expires) > time() || empty($subscription->expires)) ) || $subscription->status == 4;
1290
+
1291
+ }
1292
+ return $valid;
1293
+
1294
+ }
1295
+
1296
+ public function repository_has_subscription($repository_id){
1297
+ $key = false;
1298
+ if(!empty($this->settings['repositories'][$repository_id]['subscription']['key'])){
1299
+ $key = $this->settings['repositories'][$repository_id]['subscription']['key'];
1300
+ }
1301
+
1302
+ return $key;
1303
+
1304
+ }
1305
+
1306
+ public function repository_has_expired_subscription($repository_id){
1307
+
1308
+ return $this->repository_has_subscription($repository_id) && !$this->repository_has_valid_subscription($repository_id);
1309
+
1310
+ }
1311
+
1312
+ public function get_generic_product_name($repository_id){
1313
+
1314
+ return $this->settings['repositories'][$repository_id]['data']['product-name'];
1315
+
1316
+ }
1317
+
1318
+ public function show_subscription_renew_warning($repository_id, $subscription_id){
1319
+
1320
+ $show = false;
1321
+
1322
+ $data = $this->settings['repositories'][$repository_id]['data'];
1323
+ if(!empty($data['subscriptions_meta'])){
1324
+ if(isset($data['subscriptions_meta']['expiration'])){
1325
+
1326
+ if(!empty($data['subscriptions_meta']['expiration'][$subscription_id])){
1327
+
1328
+ $days = $data['subscriptions_meta']['expiration'][$subscription_id]['days_warning'];
1329
+ $message = $data['subscriptions_meta']['expiration'][$subscription_id]['warning_message'];
1330
+
1331
+ }else{
1332
+
1333
+ //defaults
1334
+ $days = 30;
1335
+ $message = __('You will have to renew your subscription in order to continue getting the updates and support.', 'installer');
1336
+
1337
+ }
1338
+
1339
+ if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1340
+ $subscription = $this->settings['repositories'][$repository_id]['subscription'];
1341
+
1342
+ if($subscription['data']->subscription_type == $subscription_id && !empty($subscription['data']->expires)){
1343
+
1344
+ if(strtotime($subscription['data']->expires) < strtotime(sprintf("+%d day", $days))){
1345
+
1346
+ $days_to_expiration = ceil((strtotime($subscription['data']->expires) - time()) / 86400);
1347
+
1348
+ echo '<div><p class="installer-warn-box">' .
1349
+ sprintf(_n('Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer'), $days_to_expiration) .
1350
+ '<br />' . $message .
1351
+ '</p></div>';
1352
+
1353
+ $show = true;
1354
+
1355
+ }
1356
+
1357
+ }
1358
+
1359
+ }
1360
+
1361
+
1362
+ }
1363
+ }
1364
+
1365
+
1366
+ return $show;
1367
+
1368
+ }
1369
+
1370
+ public function setup_plugins_renew_warnings(){
1371
+
1372
+ $plugins = get_plugins();
1373
+
1374
+ $subscriptions_with_warnings = array();
1375
+ foreach($this->settings['repositories'] as $repository_id => $repository){
1376
+
1377
+ if($this->repository_has_valid_subscription($repository_id)){
1378
+ $subscription_type = $this->settings['repositories'][$repository_id]['subscription']['data']->subscription_type;
1379
+ $expires = $this->settings['repositories'][$repository_id]['subscription']['data']->expires;
1380
+
1381
+ $never_expires = isset($this->settings['repositories'][$repository_id]['subscription'])
1382
+ && empty($this->settings['repositories'][$repository_id]['subscription']['data']->expires)
1383
+ && (
1384
+ $this->settings['repositories'][$repository_id]['subscription']['data']->status == 4 ||
1385
+ $this->settings['repositories'][$repository_id]['subscription']['data']->status == 1
1386
+ );
1387
+
1388
+ if(!$never_expires){
1389
+ if(isset($this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type])){
1390
+
1391
+ $days_warning = $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type]['days_warning'];
1392
+ $custom_message = $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_type]['warning_message'];
1393
+
1394
+ }else{
1395
+ //defaults
1396
+ $days_warning = 30;
1397
+ $custom_message = __('You will have to renew your subscription in order to continue getting the updates and support.', 'installer');
1398
+ }
1399
+
1400
+ if(strtotime($expires) < strtotime(sprintf('+%d day', $days_warning)) ){
1401
+
1402
+ $days_to_expiration = ceil((strtotime($expires) - time()) / 86400);
1403
+
1404
+ $message = sprintf(_n('Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer'), $days_to_expiration);
1405
+ $subscriptions_with_warnings[$subscription_type] = $message . ' ' . $custom_message;
1406
+
1407
+ }
1408
+ }
1409
+
1410
+ }
1411
+
1412
+ }
1413
+
1414
+
1415
+
1416
+ foreach($plugins as $plugin_id => $plugin){
1417
+
1418
+ $slug = dirname($plugin_id);
1419
+ if(empty($slug)) continue;
1420
+
1421
+ foreach($this->settings['repositories'] as $repository_id => $repository){
1422
+
1423
+ if($this->repository_has_valid_subscription($repository_id)){
1424
+
1425
+ foreach($repository['data']['packages'] as $package){
1426
+
1427
+ foreach($package['products'] as $product){
1428
+
1429
+ foreach($product['plugins'] as $plugin_slug){
1430
+
1431
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1432
+
1433
+ if($download['slug'] == $slug || $download['name'] == $plugin['Name'] || $download['name'] == $plugin['Title']){ //match order: slug, name, title
1434
+
1435
+ if(isset($subscriptions_with_warnings[$product['subscription_type']])){
1436
+
1437
+ $this->_plugins_renew_warnings[$plugin_id] = $subscriptions_with_warnings[$product['subscription_type']];
1438
+
1439
+ }
1440
+
1441
+ }
1442
+
1443
+ }
1444
+
1445
+ }
1446
+
1447
+ }
1448
+
1449
+ }
1450
+
1451
+ }
1452
+
1453
+ }
1454
+
1455
+ }
1456
+
1457
+ public function queue_plugins_renew_warnings() {
1458
+
1459
+ if(!empty($this->_plugins_renew_warnings)){
1460
+
1461
+ foreach($this->_plugins_renew_warnings as $plugin_id => $message){
1462
+
1463
+ add_action( "after_plugin_row_" . $plugin_id, array($this, 'plugins_renew_warning'), 10, 3 );
1464
+ }
1465
+
1466
+ }
1467
+
1468
+ }
1469
+
1470
+ public function plugins_renew_warning($plugin_file, $plugin_data, $status){
1471
+
1472
+ if(empty($this->_plugins_renew_warnings[$plugin_file])) return;
1473
+
1474
+ $wp_list_table = _get_list_table('WP_Plugins_List_Table');
1475
+ ?>
1476
+
1477
+ <tr class="plugin-update-tr"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
1478
+ <div class="update-message">
1479
+ <?php
1480
+ echo $this->_plugins_renew_warnings[$plugin_file]. ' ';
1481
+ printf(__('%sRenew here%s.', 'installer'),
1482
+ '<a href="' . $this->menu_url() . '">', '</a>');
1483
+ ?>
1484
+ </div>
1485
+ </tr>
1486
+
1487
+ <?php
1488
+
1489
+ }
1490
+
1491
+ public function get_subscription_type_for_repository($repository_id){
1492
+
1493
+ $subscription_type = false;
1494
+
1495
+ if(!empty($this->settings['repositories'][$repository_id]['subscription'])){
1496
+ $subscription_type = $this->settings['repositories'][$repository_id]['subscription']['data']->subscription_type;
1497
+ }
1498
+
1499
+ return $subscription_type;
1500
+
1501
+ }
1502
+
1503
+ public function have_superior_subscription($subscription_type, $product){
1504
+
1505
+ $have = false;
1506
+
1507
+ if(is_array($product['upgrades'])){
1508
+ foreach($product['upgrades'] as $u){
1509
+ if($u['subscription_type'] == $subscription_type){
1510
+ $have = true;
1511
+ break;
1512
+ }
1513
+ }
1514
+ }
1515
+
1516
+ return $have;
1517
+ }
1518
+
1519
+ public function is_product_available_for_download($product_name, $repository_id){
1520
+
1521
+ $available = false;
1522
+
1523
+ $subscription_type = $this->get_subscription_type_for_repository($repository_id);
1524
+ $expired = $this->repository_has_expired_subscription($repository_id);
1525
+
1526
+ if($this->repository_has_subscription($repository_id) && !$expired){
1527
+
1528
+ $this->set_hierarchy_and_order();
1529
+
1530
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package_id => $package){
1531
+
1532
+ $has_top_package = false;
1533
+
1534
+ foreach($package['products'] as $product){
1535
+
1536
+ if($subscription_type == $product['subscription_type']){
1537
+ $has_top_package = true;
1538
+ if($product['name'] == $product_name){
1539
+ return $available = true;
1540
+ }
1541
+ }
1542
+
1543
+ }
1544
+
1545
+ if(!empty($package['sub-packages'])){
1546
+ foreach($package['sub-packages'] as $sub_package){
1547
+ foreach($sub_package['products'] as $product){
1548
+ if($product['name'] == $product_name && ($subscription_type == $product['subscription_type'] || $has_top_package)){
1549
+ return $available = true;
1550
+ }
1551
+ }
1552
+ }
1553
+ }
1554
+
1555
+ }
1556
+ }
1557
+
1558
+ return $available;
1559
+
1560
+ }
1561
+
1562
+ public function get_upgrade_options($repository_id){
1563
+ $all_upgrades = array();
1564
+
1565
+ //get all products: packages and subpackages
1566
+ $all_products = array();
1567
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
1568
+ foreach($package['products'] as $product) {
1569
+ $all_products[] = $product;
1570
+ }
1571
+ if(!empty($package['sub-packages'])){
1572
+ foreach($package['sub-packages'] as $subpackage){
1573
+ foreach($subpackage['products'] as $product) {
1574
+ $all_products[] = $product;
1575
+ }
1576
+
1577
+ }
1578
+
1579
+ }
1580
+
1581
+ }
1582
+
1583
+ foreach($all_products as $product) {
1584
+ if ($product['upgrades']) {
1585
+ foreach ($product['upgrades'] as $upgrade) {
1586
+ if ($this->repository_has_valid_subscription($repository_id) || ($this->repository_has_subscription($repository_id) && $upgrade['including_expired'])) {
1587
+ $all_upgrades[$upgrade['subscription_type']][$product['subscription_type']] = $upgrade;
1588
+ }
1589
+ }
1590
+ }
1591
+ }
1592
+
1593
+ return $all_upgrades;
1594
+
1595
+ }
1596
+
1597
+ public function append_site_key_to_download_url($url, $key, $repository_id){
1598
+
1599
+ $url_params['site_key'] = $key;
1600
+ $url_params['site_url'] = $this->get_installer_site_url( $repository_id );
1601
+
1602
+
1603
+ // Add extra parameters for custom Installer packages
1604
+ if( !empty($this->package_source) ){
1605
+ $extra = $this->get_extra_url_parameters();
1606
+ if( !empty($extra['repository']) && $extra['repository'] == $repository_id ) {
1607
+ unset($extra['repository']);
1608
+ foreach($extra as $key => $val){
1609
+ $url_params[$key] = $val;
1610
+ }
1611
+ }
1612
+ }
1613
+
1614
+ $url = add_query_arg($url_params, $url);
1615
+
1616
+ if($repository_id == 'wpml'){
1617
+ $url = add_query_arg(array('using_icl' => $this->_using_icl, 'wpml_version' => $this->_wpml_version), $url);
1618
+ }
1619
+
1620
+ return $url;
1621
+
1622
+ }
1623
+
1624
+ public function plugin_is_installed($name, $slug, $version = null){
1625
+
1626
+ $is = false;
1627
+
1628
+ $plugins = get_plugins();
1629
+
1630
+ foreach($plugins as $plugin_id => $plugin){
1631
+
1632
+ $wp_plugin_slug = dirname($plugin_id);
1633
+
1634
+ // Exception: embedded plugins
1635
+ if( $wp_plugin_slug == $slug || $plugin['Name'] == $name || $plugin['Title'] == $name || ( $wp_plugin_slug == $slug . '-embedded' || $plugin['Name'] == $name . ' Embedded' ) ){
1636
+ if($version){
1637
+ if(version_compare($plugin['Version'], $version, '>=')){
1638
+ $is = $plugin['Version'];
1639
+ }
1640
+ }else{
1641
+ $is = $plugin['Version'];
1642
+ }
1643
+
1644
+ break;
1645
+ }
1646
+
1647
+ }
1648
+
1649
+ //exception: Types name difference
1650
+ if(!$is && $name == 'Types'){
1651
+ return $this->plugin_is_installed('Types - Complete Solution for Custom Fields and Types', $slug, $version);
1652
+ }
1653
+
1654
+ return $is;
1655
+ }
1656
+
1657
+ public function plugin_is_embedded_version($name, $slug){
1658
+ $is = false;
1659
+
1660
+ $plugins = get_plugins();
1661
+
1662
+ //false if teh full version is also installed
1663
+ $is_full_installed = false;
1664
+ foreach($plugins as $plugin_id => $plugin){
1665
+
1666
+ if(($plugin['Name'] == $name && !preg_match("#-embedded$#", $slug)) ){
1667
+ $is_full_installed = true;
1668
+ break;
1669
+ }
1670
+
1671
+ }
1672
+
1673
+ if($is_full_installed){
1674
+ return false;
1675
+ }
1676
+
1677
+ foreach($plugins as $plugin_id => $plugin){
1678
+
1679
+ // TBD
1680
+ $wp_plugin_slug = dirname($plugin_id);
1681
+ if( $wp_plugin_slug == $slug . '-embedded' && $plugin['Name'] == $name . ' Embedded'){
1682
+ $is = true;
1683
+ break;
1684
+ }
1685
+
1686
+ }
1687
+
1688
+ return $is;
1689
+
1690
+ }
1691
+
1692
+ //Alias for plugin_is_installed
1693
+ public function get_plugin_installed_version($name, $slug){
1694
+
1695
+ return $this->plugin_is_installed($name, $slug);
1696
+
1697
+ }
1698
+
1699
+ public function get_plugin_repository_version($repository_id, $slug){
1700
+ $version = false;
1701
+
1702
+ if(!empty($this->settings['repositories'][$repository_id]['data']['packages'])){
1703
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package){
1704
+ foreach($package['products'] as $product) {
1705
+
1706
+ foreach($product['plugins'] as $plugin_slug){
1707
+
1708
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1709
+
1710
+ if($download['slug'] == $slug){
1711
+ $version = $download['version'];
1712
+ break (3);
1713
+ }
1714
+
1715
+ }
1716
+
1717
+ }
1718
+ }
1719
+ }
1720
+
1721
+ return $version;
1722
+ }
1723
+
1724
+ public function is_uploading_allowed(){
1725
+
1726
+ //_deprecated_function ( __FUNCTION__, '1.7.3', 'Installer_Dependencies::' . __FUNCTION__ );
1727
+ return $this->dependencies->is_uploading_allowed();
1728
+
1729
+ }
1730
+
1731
+ public function download_plugin_ajax_handler(){
1732
+
1733
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1734
+ require_once $this->plugin_path() . '/includes/installer-upgrader-skins.php';
1735
+
1736
+ if(isset($_POST['data'])){
1737
+
1738
+ $data = json_decode( base64_decode( $_POST['data'] ), true );
1739
+
1740
+ }
1741
+
1742
+ $ret = false;
1743
+ $plugin_id = false;
1744
+ $message = '';
1745
+
1746
+ //validate subscription
1747
+ $site_key = $this->get_repository_site_key($data['repository_id']);
1748
+ $subscription_data = $this->fetch_subscription_data( $data['repository_id'], $site_key , self::SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT);
1749
+
1750
+ if($subscription_data && !is_wp_error($subscription_data) && $this->repository_has_valid_subscription($data['repository_id'])){
1751
+
1752
+ if($data['nonce'] == wp_create_nonce('install_plugin_' . $data['url'])){
1753
+
1754
+ $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1755
+ $upgrader = new Plugin_Upgrader($upgrader_skins);
1756
+
1757
+ remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
1758
+
1759
+ $plugins = get_plugins();
1760
+
1761
+ //upgrade or install?
1762
+ foreach($plugins as $id => $plugin){
1763
+ $wp_plugin_slug = dirname($id);
1764
+ $is_embedded = $this->plugin_is_embedded_version(preg_replace('/ Embedded$/', '', $plugin['Name']), preg_replace('/-embedded$/', '', $wp_plugin_slug));
1765
+
1766
+ if($wp_plugin_slug == $data['slug'] || $is_embedded && preg_replace('/-embedded$/', '', $wp_plugin_slug) == $data['slug']){
1767
+ $plugin_id = $id;
1768
+ break;
1769
+ }
1770
+ }
1771
+
1772
+ if($plugin_id && empty($is_embedded)){ //upgrade
1773
+ $response['upgrade'] = 1;
1774
+
1775
+ $plugin_is_active = is_plugin_active($plugin_id);
1776
+
1777
+ $ret = $upgrader->upgrade($plugin_id);
1778
+
1779
+ if(!$ret && !empty($upgrader->skin->installer_error)){
1780
+ if(is_wp_error($upgrader->skin->installer_error)){
1781
+ $message = $upgrader->skin->installer_error->get_error_message() .
1782
+ ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1783
+ }
1784
+ }
1785
+
1786
+ if($plugin_is_active){
1787
+ //prevent redirects
1788
+ add_filter('wp_redirect', '__return_false');
1789
+ activate_plugin($plugin_id);
1790
+ }
1791
+
1792
+ }else{ //install
1793
+
1794
+ if($is_embedded){
1795
+ delete_plugins(array($plugin_id));
1796
+ }
1797
+
1798
+ $response['install'] = 1;
1799
+ $ret = $upgrader->install($data['url']);
1800
+ if(!$ret && !empty($upgrader->skin->installer_error)){
1801
+ if(is_wp_error($upgrader->skin->installer_error)){
1802
+ $message = $upgrader->skin->installer_error->get_error_message() .
1803
+ ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1804
+ }
1805
+ }
1806
+ }
1807
+
1808
+ $plugins = get_plugins(); //read again
1809
+
1810
+ if($ret && !empty($_POST['activate'])){
1811
+ foreach($plugins as $id => $plugin){
1812
+ $wp_plugin_slug = dirname($id);
1813
+ if($wp_plugin_slug == $data['slug']){
1814
+ $plugin_version = $plugin['Version'];
1815
+ $plugin_id = $id;
1816
+ break;
1817
+ }
1818
+ }
1819
+
1820
+ }
1821
+
1822
+ }
1823
+
1824
+ } else { //subscription not valid
1825
+
1826
+ $ret = false;
1827
+ $message = __('Your subscription appears to no longer be valid. Please try to register again using a valid site key.', 'installer');
1828
+ }
1829
+
1830
+ $response['version'] = isset($plugin_version) ? $plugin_version : 0;
1831
+ $response['plugin_id'] = $plugin_id;
1832
+ $response['nonce'] = wp_create_nonce('activate_' . $plugin_id);
1833
+ $response['success'] = $ret;
1834
+ $response['message'] = $message;
1835
+
1836
+ echo json_encode( $response );
1837
+ exit;
1838
+
1839
+ }
1840
+
1841
+ public function download_plugin($slug, $url){
1842
+
1843
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1844
+ require_once $this->plugin_path() . '/includes/installer-upgrader-skins.php';
1845
+
1846
+ $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1847
+ $upgrader = new Plugin_Upgrader($upgrader_skins);
1848
+
1849
+ remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
1850
+
1851
+ $plugins = get_plugins();
1852
+
1853
+ $plugin_id = false;
1854
+
1855
+ //upgrade or install?
1856
+ foreach($plugins as $id => $plugin){
1857
+ $wp_plugin_slug = dirname($id);
1858
+ if($wp_plugin_slug == $slug){
1859
+ $plugin_id = $id;
1860
+ break;
1861
+ }
1862
+ }
1863
+
1864
+ if($plugin_id){ //upgrade
1865
+
1866
+ $plugin_is_active = is_plugin_active($plugin_id);
1867
+
1868
+ $ret = $upgrader->upgrade($plugin_id);
1869
+
1870
+ if($plugin_is_active){
1871
+ activate_plugin($plugin_id);
1872
+ }
1873
+
1874
+ }else{ //install
1875
+ $ret = $upgrader->install($url);
1876
+ }
1877
+
1878
+ return $ret;
1879
+
1880
+ }
1881
+
1882
+ public function activate_plugin(){
1883
+
1884
+ $error = '';
1885
+
1886
+ if(isset($_POST['nonce']) && isset($_POST['plugin_id']) && $_POST['nonce'] == wp_create_nonce('activate_' . $_POST['plugin_id'])){
1887
+
1888
+ $plugin_id = $_POST['plugin_id'];
1889
+
1890
+ // Deactivate any embedded version
1891
+ $plugin_slug = dirname($plugin_id);
1892
+ $active_plugins = get_option('active_plugins');
1893
+ foreach($active_plugins as $plugin){
1894
+ $wp_plugin_slug = dirname($plugin);
1895
+ if($wp_plugin_slug == $plugin_slug . '-embedded'){
1896
+ deactivate_plugins(array($plugin));
1897
+ break;
1898
+ }
1899
+ }
1900
+
1901
+ //prevent redirects
1902
+ add_filter('wp_redirect', '__return_false', 10000);
1903
+
1904
+ $return = activate_plugin($plugin_id);
1905
+
1906
+ if(is_wp_error($return)){
1907
+ $error = $return->get_error_message();
1908
+ }
1909
+
1910
+ }else{
1911
+ $error = 'error';
1912
+ }
1913
+
1914
+ $ret = array('error' => $error);
1915
+
1916
+ echo json_encode($ret);
1917
+ exit;
1918
+
1919
+ }
1920
+
1921
+ public function custom_plugins_api_call($false, $action, $args){
1922
+
1923
+ if($action == 'plugin_information'){
1924
+
1925
+ $slug = $args->slug;
1926
+
1927
+ foreach($this->settings['repositories'] as $repository_id => $repository){
1928
+
1929
+ if(!$this->repository_has_valid_subscription($repository_id)){
1930
+ $site_key = false;
1931
+ }else{
1932
+ $site_key = $repository['subscription']['key'];
1933
+ }
1934
+
1935
+ foreach($repository['data']['packages'] as $package){
1936
+
1937
+ foreach($package['products'] as $product){
1938
+
1939
+ foreach($product['plugins'] as $plugin_slug){
1940
+
1941
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
1942
+
1943
+ if($download['slug'] == $slug){
1944
+
1945
+ $res = new stdClass();
1946
+ $res->external = true;
1947
+
1948
+ $res->name = $download['name'];
1949
+ $res->slug = $slug;
1950
+ $res->version = $download['version'];
1951
+ $res->author = '';
1952
+ $res->author_profile = '';
1953
+ $res->last_updated = $download['date'];
1954
+ //$res->homepage = $download['url'];
1955
+
1956
+ if($site_key){
1957
+ $res->download_link = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
1958
+ }else{
1959
+ // if(!empty($download['free-on-wporg'])
1960
+ return false; //try somewhere else. e.g. wordpress.org
1961
+ }
1962
+
1963
+ $res->homepage = $repository['data']['url'];
1964
+ $res->sections = array('Description' => $download['description'], 'Changelog' => $download['changelog']);
1965
+
1966
+ return $res;
1967
+
1968
+ }
1969
+
1970
+ }
1971
+
1972
+ }
1973
+
1974
+ }
1975
+
1976
+ }
1977
+
1978
+ }
1979
+
1980
+ return $false;
1981
+
1982
+ }
1983
+
1984
+ public function plugins_upgrade_check($update_plugins){
1985
+
1986
+ if(!empty($this->settings['repositories'])){
1987
+
1988
+ $plugins = get_plugins();
1989
+
1990
+ foreach($plugins as $plugin_id => $plugin){
1991
+
1992
+ $slug = dirname($plugin_id);
1993
+ if(empty($slug)) continue;
1994
+
1995
+ $version = $plugin['Version'];
1996
+ $name = $plugin['Name'];
1997
+
1998
+ foreach($this->settings['repositories'] as $repository_id => $repository){
1999
+
2000
+
2001
+ if(!$this->repository_has_valid_subscription($repository_id)){
2002
+ $site_key = false;
2003
+ }else{
2004
+ $site_key = $repository['subscription']['key'];
2005
+ //$subscription_type = $this->get_subscription_type_for_repository($repository_id);
2006
+ }
2007
+
2008
+ foreach($repository['data']['packages'] as $package){
2009
+
2010
+ foreach($package['products'] as $product){
2011
+
2012
+ foreach($product['plugins'] as $plugin_slug){
2013
+
2014
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2015
+
2016
+ if(!empty($download['free-on-wporg'])) {
2017
+ continue;
2018
+ }
2019
+
2020
+ if(empty($update_plugins->response[$plugin_id]) && ($download['slug'] == $slug || $download['name'] == $name ) && version_compare($download['version'], $version, '>')){
2021
+
2022
+ $response = new stdClass();
2023
+ $response->id = 0;
2024
+ $response->slug = $slug;
2025
+ $response->plugin = $plugin_id;
2026
+ $response->new_version = $download['version'];
2027
+ $response->upgrade_notice = '';
2028
+ $response->url = $download['url'];
2029
+ if($site_key){
2030
+ $response->package = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
2031
+ }
2032
+ $update_plugins->checked[$plugin_id] = $version;
2033
+ $update_plugins->response[$plugin_id] = $response;
2034
+
2035
+ }
2036
+
2037
+ }
2038
+
2039
+ }
2040
+
2041
+ }
2042
+
2043
+ }
2044
+
2045
+ }
2046
+
2047
+ }
2048
+
2049
+ return $update_plugins;
2050
+
2051
+ }
2052
+
2053
+ public function setup_plugins_page_notices(){
2054
+
2055
+ $plugins = get_plugins();
2056
+
2057
+ foreach($plugins as $plugin_id => $plugin){
2058
+
2059
+ $slug = dirname($plugin_id);
2060
+ if(empty($slug)) continue;
2061
+
2062
+ $name = $plugin['Name'];
2063
+
2064
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2065
+
2066
+ if(!$this->repository_has_valid_subscription($repository_id)){
2067
+ $site_key = false;
2068
+ }else{
2069
+ $site_key = $repository['subscription']['key'];
2070
+ }
2071
+
2072
+ foreach($repository['data']['packages'] as $package){
2073
+
2074
+ foreach($package['products'] as $product){
2075
+
2076
+ foreach($product['plugins'] as $plugin_slug){
2077
+
2078
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2079
+
2080
+ if(!empty($download['free-on-wporg'])) {
2081
+ continue;
2082
+ }
2083
+
2084
+ if( $download['slug'] == $slug || $download['name'] == $name ){
2085
+
2086
+ if( !$site_key || !$this->plugin_is_registered($repository_id, $download['slug']) ){
2087
+ add_action( "after_plugin_row_" . $plugin_id, array($this, 'show_purchase_notice_under_plugin'), 10, 3 );
2088
+ }
2089
+
2090
+ }
2091
+
2092
+ }
2093
+
2094
+ }
2095
+
2096
+ }
2097
+
2098
+ }
2099
+
2100
+ }
2101
+
2102
+ }
2103
+
2104
+ public function show_purchase_notice_under_plugin($plugin_file, $plugin_data, $status){
2105
+
2106
+ $wp_list_table = _get_list_table('WP_Plugins_List_Table');
2107
+ ?>
2108
+
2109
+ <tr class="plugin-update-tr"><td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
2110
+ <div class="update-message installer-q-icon">
2111
+ <?php
2112
+ printf(__('You need to have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s.', 'installer'),
2113
+ '<a href="' . $this->menu_url() . '">', '</a>');
2114
+ ?>
2115
+ </div>
2116
+ </tr>
2117
+
2118
+ <?php
2119
+
2120
+ }
2121
+
2122
+ public function localize_strings(){
2123
+
2124
+ if(!empty($this->settings['repositories'])){
2125
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2126
+ //set name as call2action when don't have any
2127
+ //products
2128
+ foreach($repository['data']['packages'] as $package_id => $package){
2129
+ foreach($package['products'] as $product_id => $product){
2130
+ if(empty($product['call2action'])){
2131
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['call2action'] = $product['name'];
2132
+ }
2133
+
2134
+ foreach($product['upgrades'] as $idx => $upg){
2135
+ if(empty($upg['call2action'])){
2136
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$idx]['call2action'] = $upg['name'];
2137
+ }
2138
+ }
2139
+
2140
+ foreach($product['renewals'] as $idx => $rnw){
2141
+ if(empty($rnw['call2action'])){
2142
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['renewals'][$idx]['call2action'] = $rnw['name'];
2143
+ }
2144
+
2145
+ }
2146
+
2147
+ }
2148
+ }
2149
+ }
2150
+ }
2151
+
2152
+ global $sitepress;
2153
+ if(is_null($sitepress)){
2154
+ return;
2155
+ }
2156
+
2157
+ // default strings are always in English
2158
+ $user_admin_language = $sitepress->get_admin_language();
2159
+
2160
+ if($user_admin_language != 'en'){
2161
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2162
+
2163
+ $localization = $repository['data']['localization'];
2164
+
2165
+ //packages
2166
+ foreach($repository['data']['packages'] as $package_id => $package){
2167
+
2168
+ if( isset($localization['packages'][$package_id]['name'][$user_admin_language]) ){
2169
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['name'] = $localization['packages'][$package_id]['name'][$user_admin_language];
2170
+ }
2171
+ if( isset($localization['packages'][$package_id]['description'][$user_admin_language]) ){
2172
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['description'] = $localization['packages'][$package_id]['description'][$user_admin_language];
2173
+ }
2174
+
2175
+ }
2176
+
2177
+ //products
2178
+ foreach($repository['data']['packages'] as $package_id => $package){
2179
+ foreach($package['products'] as $product_id => $product){
2180
+
2181
+ if( isset($localization['products'][$product_id]['name'][$user_admin_language]) ){
2182
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['name']
2183
+ = $localization['products'][$product_id]['name'][$user_admin_language];
2184
+ }
2185
+ if( isset($localization['products'][$product_id]['description'][$user_admin_language]) ){
2186
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['description']
2187
+ = $localization['products'][$product_id]['description'][$user_admin_language];
2188
+ }
2189
+ if( isset($localization['products'][$product_id]['call2action'][$user_admin_language]) ){
2190
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['name']
2191
+ = $localization['products'][$product_id]['call2action'][$user_admin_language];
2192
+ }
2193
+
2194
+
2195
+ }
2196
+ }
2197
+
2198
+ //subscription info
2199
+ if(isset($repository['data']['subscriptions_meta']['expiration'])){
2200
+ foreach($repository['data']['subscriptions_meta']['expiration'] as $subscription_id => $note){
2201
+ if(isset($localization['subscriptions-notes'][$subscription_id]['expiration-warning'][$user_admin_language])){
2202
+ $this->settings['repositories'][$repository_id]['data']['subscriptions_meta']['expiration'][$subscription_id]['warning_message']
2203
+ = $localization['subscriptions-notes'][$subscription_id]['expiration-warning'][$user_admin_language];
2204
+ }
2205
+ }
2206
+ }
2207
+
2208
+ }
2209
+ }
2210
+
2211
+ }
2212
+
2213
+ public function get_matching_cp($repository, $args = array()){
2214
+ $match = false;
2215
+
2216
+
2217
+ $cp_name = $cp_author = false;
2218
+
2219
+ if(isset($this->config['src_name']) && isset($this->config['src_author'])){
2220
+
2221
+ $cp_name = $this->config['src_name'];
2222
+ $cp_author = $this->config['src_author'];
2223
+
2224
+ }elseif(isset($args['src_name']) && isset($args['src_author'])){
2225
+
2226
+ $cp_name = $args['src_name'];
2227
+ $cp_author = $args['src_author'];
2228
+
2229
+ }
2230
+
2231
+ if(isset($repository['data']['marketing_cp'])){
2232
+
2233
+ foreach($repository['data']['marketing_cp'] as $cp){
2234
+
2235
+ if(!empty($cp['exp']) && time() > $cp['exp']){
2236
+ continue;
2237
+ }
2238
+
2239
+ //Use theme_name for plugins too
2240
+ if(!empty($cp['theme_name'])){
2241
+ if($cp['author_name'] == $cp_author && $cp['theme_name'] == $cp_name){
2242
+ $match = $cp;
2243
+ continue;
2244
+ }
2245
+ }else{
2246
+ if($cp['author_name'] == $cp_author){
2247
+ $match = $cp;
2248
+ continue;
2249
+ }
2250
+ }
2251
+
2252
+ }
2253
+
2254
+ }
2255
+
2256
+ return $match;
2257
+ }
2258
+
2259
+ public function set_filtered_prices($args = array()){
2260
+
2261
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2262
+
2263
+ $match = $this->get_matching_cp($repository, $args);
2264
+
2265
+ if(empty($match)) continue;
2266
+
2267
+ foreach($repository['data']['packages'] as $package_id => $package){
2268
+
2269
+ foreach($package['products'] as $product_id => $product){
2270
+
2271
+ if($match['dtp'] == '%'){
2272
+ $fprice = round( $product['price'] * (1 - $match['amt']/100), 2 );
2273
+ $fprice = $fprice != round($fprice) ? sprintf('%.2f', $fprice) : round($fprice, 0);
2274
+ }elseif($match['dtp'] == '-'){
2275
+ $fprice = $product['price'] - $match['amt'];
2276
+ }else{
2277
+ $fprice = $product['price'];
2278
+ }
2279
+
2280
+ if($fprice){
2281
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['price_disc'] = $fprice;
2282
+
2283
+ $url_glue = false !== strpos($this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['url'], '?') ? '&' : '?';
2284
+ $cpndata = base64_encode(json_encode(array('theme_author' => $match['author_name'], 'theme_name' => $match['theme_name'], 'vlc' => $match['vlc'])));
2285
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['url'] .= $url_glue . 'cpn=' . $cpndata;
2286
+
2287
+ foreach($product['upgrades'] as $upgrade_id => $upgrade){
2288
+
2289
+ $fprice = false;
2290
+ if($match['dtp'] == '%'){
2291
+ $fprice = round( $upgrade['price'] * (1 - $match['amt']/100), 2 );
2292
+ $fprice = $fprice != round($fprice) ? sprintf('%.2f', $fprice) : round($fprice, 0);
2293
+ }elseif($match['dtp'] == '-'){
2294
+ $fprice = $upgrade['price'] - $match['amt'];
2295
+ }
2296
+ if($fprice){
2297
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$upgrade_id]['price_disc'] = $fprice;
2298
+ $this->settings['repositories'][$repository_id]['data']['packages'][$package_id]['products'][$product_id]['upgrades'][$upgrade_id]['url'] .= $url_glue . 'cpn=' . $cpndata;
2299
+ }
2300
+
2301
+
2302
+ }
2303
+
2304
+ }
2305
+
2306
+ }
2307
+
2308
+ }
2309
+
2310
+ }
2311
+
2312
+ }
2313
+
2314
+ public function set_hierarchy_and_order(){
2315
+
2316
+ //2 levels
2317
+ if(!empty($this->settings['repositories'])) {
2318
+ foreach ($this->settings['repositories'] as $repository_id => $repository) {
2319
+
2320
+ if( empty( $repository['data']['packages'] ) ) continue;
2321
+
2322
+ $all_packages = $repository['data']['packages'];
2323
+ $ordered_packages = array();
2324
+
2325
+ //backward compatibility - 'order'
2326
+ foreach($all_packages as $k => $v){
2327
+ if(!isset($v['order'])){
2328
+ $all_packages[$k]['order'] = 0;
2329
+ }
2330
+ }
2331
+
2332
+ //select parents
2333
+ foreach ($all_packages as $package_id => $package) {
2334
+ if(empty($package['parent'])){
2335
+ $ordered_packages[$package_id] = $package;
2336
+ }
2337
+ }
2338
+
2339
+ //add sub-packages
2340
+ foreach($all_packages as $package_id => $package){
2341
+ if(!empty($package['parent'])) {
2342
+ if(isset($ordered_packages[$package['parent']])){
2343
+ $ordered_packages[$package['parent']]['sub-packages'][$package_id] = $package;
2344
+ }
2345
+ }
2346
+ }
2347
+
2348
+ // order parents
2349
+ usort($ordered_packages, array($this, '_order_packages_callback'));
2350
+ //order sub-packages
2351
+ foreach($ordered_packages as $package_id => $package){
2352
+ if(!empty($package['sub-packages'])) {
2353
+ usort($ordered_packages[$package_id]['sub-packages'], create_function('$a, $b', 'return $a[\'order\'] > $b[\'order\'];'));
2354
+ }
2355
+ }
2356
+
2357
+ $this->settings['repositories'][$repository_id]['data']['packages'] = $ordered_packages;
2358
+
2359
+
2360
+ }
2361
+ }
2362
+
2363
+
2364
+ }
2365
+
2366
+ public function _order_packages_callback($a, $b){
2367
+ return $a['order'] > $b['order'];
2368
+ }
2369
+
2370
+ public function get_support_tag_by_name( $name, $repository ){
2371
+
2372
+ if( is_array($this->settings['repositories'][$repository]['data']['support_tags'] )){
2373
+ foreach( $this->settings['repositories'][$repository]['data']['support_tags'] as $support_tag){
2374
+ if( $support_tag['name'] == $name ){
2375
+ return $support_tag['url'];
2376
+ }
2377
+ }
2378
+ }
2379
+
2380
+ return false;
2381
+ }
2382
+
2383
+ public function plugin_upgrade_custom_errors(){
2384
+
2385
+ if ( isset($_REQUEST['action']) ) {
2386
+
2387
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
2388
+
2389
+ //bulk mode
2390
+ if('update-selected' == $action) {
2391
+
2392
+ global $plugins;
2393
+
2394
+ if(isset($plugins) && is_array($plugins)) {
2395
+
2396
+ foreach ($plugins as $k => $plugin) {
2397
+ $plugin_repository = false;
2398
+
2399
+ $wp_plugin_slug = dirname($plugin);
2400
+
2401
+ foreach ($this->settings['repositories'] as $repository_id => $repository) {
2402
+
2403
+ foreach ($repository['data']['packages'] as $package) {
2404
+
2405
+ foreach ($package['products'] as $product) {
2406
+
2407
+ foreach ($product['plugins'] as $plugin_slug) {
2408
+
2409
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2410
+
2411
+ if ($download['slug'] == $wp_plugin_slug) {
2412
+ $plugin_repository = $repository_id;
2413
+ $product_name = $repository['data']['product-name'];
2414
+ $plugin_name = $download['name'];
2415
+ $free_on_wporg = !empty($download['free-on-wporg']);
2416
+ break;
2417
+ }
2418
+
2419
+ }
2420
+
2421
+ }
2422
+
2423
+ }
2424
+
2425
+ }
2426
+
2427
+ if ($plugin_repository) {
2428
+
2429
+ //validate subscription
2430
+ static $sub_cache = array();
2431
+
2432
+ if(empty($sub_cache[$plugin_repository])){
2433
+ $site_key = $this->get_repository_site_key($plugin_repository);
2434
+ if ($site_key) {
2435
+ $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2436
+ }
2437
+
2438
+ $sub_cache[$plugin_repository]['site_key'] = $site_key;
2439
+ $sub_cache[$plugin_repository]['subscription_data'] = isset($subscription_data) ? $subscription_data : false;
2440
+ }else{
2441
+
2442
+ $site_key = $sub_cache[$plugin_repository]['site_key'];
2443
+ $subscription_data = $sub_cache[$plugin_repository]['subscription_data'];
2444
+
2445
+ }
2446
+
2447
+ if(!$site_key && !empty($free_on_wporg)){ // allow the download from wp.org
2448
+ continue;
2449
+ }
2450
+
2451
+ if (empty($site_key) || empty($subscription_data)) {
2452
+
2453
+
2454
+ $error_message = sprintf(__("%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer'),
2455
+ '<strong>' . $plugin_name . '</strong>', '<a target="_top" href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2456
+ '#repository-' . $plugin_repository . '">', $product_name, '</a>');
2457
+
2458
+ echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2459
+
2460
+ unset($plugins[$k]);
2461
+
2462
+
2463
+ }
2464
+
2465
+ }
2466
+
2467
+ }
2468
+
2469
+ }
2470
+
2471
+ }
2472
+
2473
+
2474
+ if( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
2475
+
2476
+ $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
2477
+
2478
+ $wp_plugin_slug = dirname($plugin);
2479
+
2480
+ $plugin_repository = false;
2481
+
2482
+ foreach($this->settings['repositories'] as $repository_id => $repository){
2483
+
2484
+ foreach($repository['data']['packages'] as $package){
2485
+
2486
+ foreach($package['products'] as $product){
2487
+
2488
+ foreach($product['plugins'] as $plugin_slug){
2489
+ $download = $this->settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
2490
+
2491
+ //match by folder, will change to match by name and folder
2492
+ if($download['slug'] == $wp_plugin_slug) {
2493
+ $plugin_repository = $repository_id;
2494
+ $product_name = $repository['data']['product-name'];
2495
+ $plugin_name = $download['name'];
2496
+ $free_on_wporg = !empty($download['free-on-wporg']);
2497
+ break;
2498
+ }
2499
+
2500
+ }
2501
+
2502
+ }
2503
+
2504
+ }
2505
+
2506
+ }
2507
+
2508
+ if($plugin_repository) {
2509
+
2510
+ //validate subscription
2511
+ $site_key = $this->get_repository_site_key($plugin_repository);
2512
+ if ($site_key) {
2513
+ $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2514
+ }
2515
+
2516
+ if ( (empty($site_key) || empty($subscription_data)) && empty($free_on_wporg)) {
2517
+
2518
+ $error_message = sprintf(__("%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer'),
2519
+ '<strong>'.$plugin_name . '</strong>', '<a href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2520
+ '#repository-' . $plugin_repository . '">', $product_name, '</a>');
2521
+
2522
+ if(defined('DOING_AJAX')){ //WP 4.2
2523
+
2524
+ $status = array(
2525
+ 'update' => 'plugin',
2526
+ 'plugin' => $plugin,
2527
+ 'slug' => sanitize_key( $_POST['slug'] ),
2528
+ 'oldVersion' => '',
2529
+ 'newVersion' => '',
2530
+ );
2531
+
2532
+ $status['errorCode'] = 'wp_installer_invalid_subscription';
2533
+ $status['error'] = $error_message;
2534
+
2535
+ wp_send_json_error( $status );
2536
+
2537
+ } else { // WP 4.1.1
2538
+ echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2539
+
2540
+
2541
+ echo '<div class="wrap">';
2542
+ echo '<h2>' . __('Update Plugin') . '</h2>';
2543
+ echo '<a href="' . admin_url('plugins.php') . '">' . __('Return to the plugins page') . '</a>';
2544
+ echo '</div>';
2545
+ require_once(ABSPATH . 'wp-admin/admin-footer.php');
2546
+ exit;
2547
+
2548
+ }
2549
+
2550
+ }
2551
+
2552
+
2553
+ }
2554
+
2555
+ }
2556
+ }
2557
+
2558
+ }
2559
+
2560
+ }
embedded/otgs/installer/includes/translation-service-info.class.php CHANGED
@@ -1,40 +1,40 @@
1
- <?php
2
-
3
- class TranslationServiceInfo{
4
-
5
- function __construct(){
6
-
7
- add_action('installer_fetched_subscription_data',array($this, 'save_info'), 10, 2);
8
-
9
- }
10
-
11
- function save_info($data, $repository_id) {
12
-
13
- $ts_info = isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info'] ) ?
14
- WP_Installer()->settings['repositories'][$repository_id]['ts_info'] : false;
15
-
16
- $save_settings = false;
17
- if(isset($data->ts_info['preferred']) && empty($ts_info['preferred'])){
18
- WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $data->ts_info['preferred'];
19
- $save_settings = true;
20
- }
21
-
22
- if(isset($data->ts_info['referal']) && empty($ts_info['referal'])){
23
- WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'] = $data->ts_info['referal'];
24
- $save_settings = true;
25
- }
26
-
27
- if ( !empty( $data->ts_info['client_id'] ) ) { // can be updated
28
- WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'] = $data->ts_info['client_id'];
29
- $save_settings = true;
30
- }
31
-
32
- if($save_settings){
33
- WP_Installer()->save_settings();
34
- }
35
-
36
- }
37
-
38
- }
39
-
40
  new TranslationServiceInfo();
1
+ <?php
2
+
3
+ class TranslationServiceInfo{
4
+
5
+ function __construct(){
6
+
7
+ add_action('installer_fetched_subscription_data',array($this, 'save_info'), 10, 2);
8
+
9
+ }
10
+
11
+ function save_info($data, $repository_id) {
12
+
13
+ $ts_info = isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info'] ) ?
14
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info'] : false;
15
+
16
+ $save_settings = false;
17
+ if(isset($data->ts_info['preferred']) && empty($ts_info['preferred'])){
18
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $data->ts_info['preferred'];
19
+ $save_settings = true;
20
+ }
21
+
22
+ if(isset($data->ts_info['referal']) && empty($ts_info['referal'])){
23
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'] = $data->ts_info['referal'];
24
+ $save_settings = true;
25
+ }
26
+
27
+ if ( !empty( $data->ts_info['client_id'] ) ) { // can be updated
28
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'] = $data->ts_info['client_id'];
29
+ $save_settings = true;
30
+ }
31
+
32
+ if($save_settings){
33
+ WP_Installer()->save_settings();
34
+ }
35
+
36
+ }
37
+
38
+ }
39
+
40
  new TranslationServiceInfo();
embedded/otgs/installer/installer.php CHANGED
@@ -1,22 +1,22 @@
1
- <?php
2
- define('WP_INSTALLER_VERSION', '1.7.9');
3
-
4
- include_once dirname(__FILE__) . '/includes/installer.class.php';
5
-
6
- function WP_Installer() {
7
- return WP_Installer::instance();
8
- }
9
-
10
-
11
- WP_Installer();
12
-
13
- include_once WP_Installer()->plugin_path() . '/includes/installer-api.php';
14
- include_once WP_Installer()->plugin_path() . '/includes/translation-service-info.class.php';
15
- include_once WP_Installer()->plugin_path() . '/includes/class-installer-dependencies.php';
16
-
17
- // Ext function
18
- function WP_Installer_Show_Products($args = array()){
19
-
20
- WP_Installer()->show_products($args);
21
-
22
  }
1
+ <?php
2
+ define('WP_INSTALLER_VERSION', '1.7.10');
3
+
4
+ include_once dirname(__FILE__) . '/includes/installer.class.php';
5
+
6
+ function WP_Installer() {
7
+ return WP_Installer::instance();
8
+ }
9
+
10
+
11
+ WP_Installer();
12
+
13
+ include_once WP_Installer()->plugin_path() . '/includes/installer-api.php';
14
+ include_once WP_Installer()->plugin_path() . '/includes/translation-service-info.class.php';
15
+ include_once WP_Installer()->plugin_path() . '/includes/class-installer-dependencies.php';
16
+
17
+ // Ext function
18
+ function WP_Installer_Show_Products($args = array()){
19
+
20
+ WP_Installer()->show_products($args);
21
+
22
  }
embedded/otgs/installer/loader.php CHANGED
@@ -1,151 +1,151 @@
1
- <?php
2
-
3
- if ( ! defined( 'ABSPATH' ) ) {
4
- exit; // Exit if accessed directly
5
- }
6
-
7
- //It should only be loaded on the admin side
8
- if( !is_admin() ){
9
- if(!function_exists('WP_Installer_Setup')){ function WP_Installer_Setup(){} }
10
- $wp_installer_instance = null;
11
- return;
12
- }
13
-
14
-
15
- $wp_installer_instance = dirname(__FILE__) . '/installer.php';
16
-
17
-
18
- // Global stack of instances
19
- global $wp_installer_instances;
20
- $wp_installer_instances[$wp_installer_instance] = array(
21
- 'bootfile' => $wp_installer_instance,
22
- 'version' => '1.7.9'
23
- );
24
-
25
-
26
- /* EXCEPTIONS ********************************************************************************************/
27
- // Exception: When WPML prior 3.2 is used, that instance must be used regardless of another newer instance
28
- // Case 1: WPML loaded before Types - eliminate other instances
29
- if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.2', '<') ) {
30
- foreach($wp_installer_instances as $key => $instance) {
31
- if(isset($instance['args']['site_key_nags'])){
32
- $wp_installer_instances[$key]['version'] = '9.9';
33
- }else{
34
- $wp_installer_instances[$key]['version'] = '0';
35
- }
36
- }
37
- }
38
-
39
- // Exception: Types 1.8.9 (Installer 1.7.0) with WPML before 3.3 (Installer before 1.7.0)
40
- // New products file http://d2salfytceyqoe.cloudfront.net/wpml-products33.json overrides the old one
41
- // while the WPML's instance is being used
42
- // => Force using the new Installer Instance
43
- if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.3.1', '<') ) {
44
-
45
- // if Installer 1.7.0+ is present, unregister Installer from old WPML
46
- // Force Installer 1.7.0+ being used over older Installer versions
47
- $installer_171_plus_on = false;
48
- foreach($wp_installer_instances as $key => $instance) {
49
- if( version_compare( $instance['version'], '1.7.1', '>=' ) ){
50
- $installer_171_plus_on = true;
51
- break;
52
- }
53
- }
54
-
55
- if( $installer_171_plus_on ){
56
- foreach($wp_installer_instances as $key => $instance) {
57
-
58
- if( version_compare( $instance['version'], '1.7.0', '<' ) ){
59
- unset( $wp_installer_instances[$key] );
60
- }
61
-
62
- }
63
- }
64
-
65
- }
66
-
67
- // Exception: When using the embedded plugins module allow the set up to run completely with the
68
- // Installer instance that triggers it
69
- if( isset( $_POST['installer_instance'] ) && isset( $wp_installer_instances[$_POST['installer_instance']] ) ){
70
- $wp_installer_instances[$_POST['installer_instance']]['version'] = '999';
71
- }
72
- /* EXCEPTIONS ********************************************************************************************/
73
-
74
-
75
- // Only one of these in the end
76
- remove_action('after_setup_theme', 'wpml_installer_instance_delegator', 1);
77
- add_action('after_setup_theme', 'wpml_installer_instance_delegator', 1);
78
-
79
- // When all plugins load pick the newest version
80
- if(!function_exists('wpml_installer_instance_delegator')){
81
- function wpml_installer_instance_delegator(){
82
- global $wp_installer_instances;
83
-
84
- // version based election
85
- foreach($wp_installer_instances as $instance){
86
-
87
- if(!isset($delegate)){
88
- $delegate = $instance;
89
- continue;
90
- }
91
-
92
- if(version_compare($instance['version'], $delegate['version'], '>')){
93
- $delegate = $instance;
94
- }
95
- }
96
-
97
- // priority based election
98
- $highest_priority = null;
99
- foreach($wp_installer_instances as $instance) {
100
- if(isset($instance['args']['high_priority'])){
101
- if(is_null($highest_priority) || $instance['args']['high_priority'] <= $highest_priority){
102
- $highest_priority = $instance['args']['high_priority'];
103
- $delegate = $instance;
104
- }
105
- }
106
- }
107
-
108
- // Exception: When WPML prior 3.2 is used, that instance must be used regardless of another newer instance
109
- // Case 2: WPML loaded after Types
110
- if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.2', '<') ) {
111
- foreach($wp_installer_instances as $key => $instance) {
112
- if(isset($instance['args']['site_key_nags'])){
113
- $delegate = $instance;
114
- $wp_installer_instances = array($key => $delegate); //Eliminate other instances
115
- break;
116
- }
117
- }
118
- }
119
-
120
- include_once $delegate['bootfile'];
121
-
122
- // set configuration
123
- if(strpos(realpath($delegate['bootfile']), realpath(TEMPLATEPATH)) === 0){
124
- $delegate['args']['in_theme_folder'] = dirname(ltrim(str_replace(realpath(TEMPLATEPATH), '', realpath($delegate['bootfile'])), '\\/'));
125
- }
126
- if(isset($delegate['args']) && is_array($delegate['args'])){
127
- foreach($delegate['args'] as $key => $value){
128
- WP_Installer()->set_config($key, $value);
129
- }
130
- }
131
-
132
- }
133
- }
134
-
135
- if(!function_exists('WP_Installer_Setup')){
136
-
137
- // $args:
138
- // plugins_install_tab = true|false (default: true)
139
- // repositories_include = array() (default: all)
140
- // repositories_exclude = array() (default: none)
141
- // template = name (default: default)
142
- //
143
- // Ext function
144
- function WP_Installer_Setup($wp_installer_instance, $args = array()){
145
- global $wp_installer_instances;
146
-
147
- $wp_installer_instances[$wp_installer_instance]['args'] = $args;
148
-
149
- }
150
-
151
  }
1
+ <?php
2
+
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit; // Exit if accessed directly
5
+ }
6
+
7
+ //It should only be loaded on the admin side
8
+ if( !is_admin() ){
9
+ if(!function_exists('WP_Installer_Setup')){ function WP_Installer_Setup(){} }
10
+ $wp_installer_instance = null;
11
+ return;
12
+ }
13
+
14
+
15
+ $wp_installer_instance = dirname(__FILE__) . '/installer.php';
16
+
17
+
18
+ // Global stack of instances
19
+ global $wp_installer_instances;
20
+ $wp_installer_instances[$wp_installer_instance] = array(
21
+ 'bootfile' => $wp_installer_instance,
22
+ 'version' => '1.7.10'
23
+ );
24
+
25
+
26
+ /* EXCEPTIONS ********************************************************************************************/
27
+ // Exception: When WPML prior 3.2 is used, that instance must be used regardless of another newer instance
28
+ // Case 1: WPML loaded before Types - eliminate other instances
29
+ if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.2', '<') ) {
30
+ foreach($wp_installer_instances as $key => $instance) {
31
+ if(isset($instance['args']['site_key_nags'])){
32
+ $wp_installer_instances[$key]['version'] = '9.9';
33
+ }else{
34
+ $wp_installer_instances[$key]['version'] = '0';
35
+ }
36
+ }
37
+ }
38
+
39
+ // Exception: Types 1.8.9 (Installer 1.7.0) with WPML before 3.3 (Installer before 1.7.0)
40
+ // New products file http://d2salfytceyqoe.cloudfront.net/wpml-products33.json overrides the old one
41
+ // while the WPML's instance is being used
42
+ // => Force using the new Installer Instance
43
+ if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.3.1', '<') ) {
44
+
45
+ // if Installer 1.7.0+ is present, unregister Installer from old WPML
46
+ // Force Installer 1.7.0+ being used over older Installer versions
47
+ $installer_171_plus_on = false;
48
+ foreach($wp_installer_instances as $key => $instance) {
49
+ if( version_compare( $instance['version'], '1.7.1', '>=' ) ){
50
+ $installer_171_plus_on = true;
51
+ break;
52
+ }
53
+ }
54
+
55
+ if( $installer_171_plus_on ){
56
+ foreach($wp_installer_instances as $key => $instance) {
57
+
58
+ if( version_compare( $instance['version'], '1.7.0', '<' ) ){
59
+ unset( $wp_installer_instances[$key] );
60
+ }
61
+
62
+ }
63
+ }
64
+
65
+ }
66
+
67
+ // Exception: When using the embedded plugins module allow the set up to run completely with the
68
+ // Installer instance that triggers it
69
+ if( isset( $_POST['installer_instance'] ) && isset( $wp_installer_instances[$_POST['installer_instance']] ) ){
70
+ $wp_installer_instances[$_POST['installer_instance']]['version'] = '999';
71
+ }
72
+ /* EXCEPTIONS ********************************************************************************************/
73
+
74
+
75
+ // Only one of these in the end
76
+ remove_action('after_setup_theme', 'wpml_installer_instance_delegator', 1);
77
+ add_action('after_setup_theme', 'wpml_installer_instance_delegator', 1);
78
+
79
+ // When all plugins load pick the newest version
80
+ if(!function_exists('wpml_installer_instance_delegator')){
81
+ function wpml_installer_instance_delegator(){
82
+ global $wp_installer_instances;
83
+
84
+ // version based election
85
+ foreach($wp_installer_instances as $instance){
86
+
87
+ if(!isset($delegate)){
88
+ $delegate = $instance;
89
+ continue;
90
+ }
91
+
92
+ if(version_compare($instance['version'], $delegate['version'], '>')){
93
+ $delegate = $instance;
94
+ }
95
+ }
96
+
97
+ // priority based election
98
+ $highest_priority = null;
99
+ foreach($wp_installer_instances as $instance) {
100
+ if(isset($instance['args']['high_priority'])){
101
+ if(is_null($highest_priority) || $instance['args']['high_priority'] <= $highest_priority){
102
+ $highest_priority = $instance['args']['high_priority'];
103
+ $delegate = $instance;
104
+ }
105
+ }
106
+ }
107
+
108
+ // Exception: When WPML prior 3.2 is used, that instance must be used regardless of another newer instance
109
+ // Case 2: WPML loaded after Types
110
+ if( defined('ICL_SITEPRESS_VERSION') && version_compare(ICL_SITEPRESS_VERSION, '3.2', '<') ) {
111
+ foreach($wp_installer_instances as $key => $instance) {
112
+ if(isset($instance['args']['site_key_nags'])){
113
+ $delegate = $instance;
114
+ $wp_installer_instances = array($key => $delegate); //Eliminate other instances
115
+ break;
116
+ }
117
+ }
118
+ }
119
+
120
+ include_once $delegate['bootfile'];
121
+
122
+ // set configuration
123
+ if(strpos(realpath($delegate['bootfile']), realpath(TEMPLATEPATH)) === 0){
124
+ $delegate['args']['in_theme_folder'] = dirname(ltrim(str_replace(realpath(TEMPLATEPATH), '', realpath($delegate['bootfile'])), '\\/'));
125
+ }
126
+ if(isset($delegate['args']) && is_array($delegate['args'])){
127
+ foreach($delegate['args'] as $key => $value){
128
+ WP_Installer()->set_config($key, $value);
129
+ }
130
+ }
131
+
132
+ }
133
+ }
134
+
135
+ if(!function_exists('WP_Installer_Setup')){
136
+
137
+ // $args:
138
+ // plugins_install_tab = true|false (default: true)
139
+ // repositories_include = array() (default: all)
140
+ // repositories_exclude = array() (default: none)
141
+ // template = name (default: default)
142
+ //
143
+ // Ext function
144
+ function WP_Installer_Setup($wp_installer_instance, $args = array()){
145
+ global $wp_installer_instances;
146
+
147
+ $wp_installer_instances[$wp_installer_instance]['args'] = $args;
148
+
149
+ }
150
+
151
  }
embedded/otgs/installer/locale/orig/installer.po CHANGED
@@ -1,230 +1,230 @@
1
- # This file was generated by WPML
2
- # WPML is a WordPress plugin that can turn any WordPress site into a full featured multilingual content management system.
3
- # https://wpml.org
4
- msgid ""
5
- msgstr ""
6
- "Content-Type: text/plain; charset=utf-8\n"
7
- "Content-Transfer-Encoding: 8bit\n"
8
- "Project-Id-Version:WPML_EXPORT\n"
9
- "POT-Creation-Date: \n"
10
- "PO-Revision-Date: \n"
11
- "Last-Translator: \n"
12
- "Language-Team: \n"
13
- "Language:en\n"
14
- "MIME-Version: 1.0\n"
15
-
16
- msgid "Installer"
17
- msgstr ""
18
-
19
- msgid "Registered"
20
- msgstr ""
21
-
22
- msgid "Register"
23
- msgstr ""
24
-
25
- msgid "To get automatic updates, you need to register %s for this site. %sRegister %s%s"
26
- msgstr ""
27
-
28
- msgid "Dismiss"
29
- msgstr ""
30
-
31
- msgid "Commercial"
32
- msgstr ""
33
-
34
- msgid "Installer cannot contact our updates server to get information about the available products and check for new versions. If you are seeing this message for the first time, you can ignore it, as it may be a temporary communication problem. If the problem persists and your WordPress admin is slowing down, you can disable automated version checks. Add the following line to your wp-config.php file:"
35
- msgstr ""
36
-
37
- msgid "No repositories defined."
38
- msgstr ""
39
-
40
- msgid "%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates."
41
- msgstr ""
42
-
43
- msgid "Invalid site key for the current site."
44
- msgstr ""
45
-
46
- msgid "You will have to renew your subscription in order to continue getting the updates and support."
47
- msgstr ""
48
-
49
- msgid "%sRenew here%s."
50
- msgstr ""
51
-
52
- msgid "Your subscription appears to no longer be valid. Please try to register again using a valid site key."
53
- msgstr ""
54
-
55
- msgid "You need to have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s."
56
- msgstr ""
57
-
58
- msgid "%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first."
59
- msgstr ""
60
-
61
- msgid "Update Plugin"
62
- msgstr ""
63
-
64
- msgid "Return to the plugins page"
65
- msgstr ""
66
-
67
- msgid "Your subscription expires in %d day."
68
- msgstr ""
69
-
70
- msgid "Your subscription expires in %d days."
71
- msgstr ""
72
-
73
- msgid "Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s."
74
- msgstr ""
75
-
76
- msgid "Plugin"
77
- msgstr ""
78
-
79
- msgid "downloading..."
80
- msgstr ""
81
-
82
- msgid "failed!"
83
- msgstr ""
84
-
85
- msgid "downloaded"
86
- msgstr ""
87
-
88
- msgid "activating"
89
- msgstr ""
90
-
91
- msgid "activated"
92
- msgstr ""
93
-
94
- msgid "Activate after download"
95
- msgstr ""
96
-
97
- msgid "Operation complete!"
98
- msgstr ""
99
-
100
- msgid "Download failed!\n\nClick OK to revalidate your subscription or CANCEL to try again."
101
- msgstr ""
102
-
103
- msgid "Available"
104
- msgstr ""
105
-
106
- msgid "Installed"
107
- msgstr ""
108
-
109
- msgid "Downloading"
110
- msgstr ""
111
-
112
- msgid "Activate"
113
- msgstr ""
114
-
115
- msgid "Download"
116
- msgstr ""
117
-
118
- msgid "Downloads:"
119
- msgstr ""
120
-
121
- msgid "Current version"
122
- msgstr ""
123
-
124
- msgid "Released"
125
- msgstr ""
126
-
127
- msgid "Installed version"
128
- msgstr ""
129
-
130
- msgid "(embedded)"
131
- msgstr ""
132
-
133
- msgid "installing..."
134
- msgstr ""
135
-
136
- msgid "updating..."
137
- msgstr ""
138
-
139
- msgid "installed"
140
- msgstr ""
141
-
142
- msgid "updated"
143
- msgstr ""
144
-
145
- msgid "Download failed!\n\nPlease refresh the page and try again."
146
- msgstr ""
147
-
148
- msgid "Incorrect setup"
149
- msgstr ""
150
-
151
- msgid "Invalid product"
152
- msgstr ""
153
-
154
- msgid "Unknown repository"
155
- msgstr ""
156
-
157
- msgid " Your current site key (%s) does not match the selected product (%s)."
158
- msgstr ""
159
-
160
- msgid "Buy %s"
161
- msgstr ""
162
-
163
- msgid "Already bought %s?"
164
- msgstr ""
165
-
166
- msgid "Renew %s"
167
- msgstr ""
168
-
169
- msgid "Remove current site key (%s)"
170
- msgstr ""
171
-
172
- msgid "%s support on wpml.org"
173
- msgstr ""
174
-
175
- msgid "Enter site key"
176
- msgstr ""
177
-
178
- msgid "Subscription is expired."
179
- msgstr ""
180
-
181
- msgid "Add"
182
- msgstr ""
183
-
184
- msgid "Are you sure you want to remove this site key?"
185
- msgstr ""
186
-
187
- msgid "Register %s"
188
- msgstr ""
189
-
190
- msgid "1. Go to your %s%s account%s and add this site URL: %s"
191
- msgstr ""
192
-
193
- msgid "Unregister %s from this site"
194
- msgstr ""
195
-
196
- msgid "%s is registered on this site. You will receive automatic updates until %s"
197
- msgstr ""
198
-
199
- msgid "%s is registered on this site. Your Lifetime account gives you updates for life."
200
- msgstr ""
201
-
202
- msgid "This page lets you install plugins and update existing plugins. To remove any of these plugins, go to the %splugins%s page and if you have the permission to remove plugins you should be able to do this."
203
- msgstr ""
204
-
205
- msgid "Already bought?"
206
- msgstr ""
207
-
208
- msgid "2. Enter your site key"
209
- msgstr ""
210
-
211
- msgid "Subscription is expired. You need to either purchase a new subscription or upgrade if available."
212
- msgstr ""
213
-
214
- msgid "Check for updates"
215
- msgstr ""
216
-
217
- msgid "Individual components"
218
- msgstr ""
219
-
220
- msgid "OK"
221
- msgstr ""
222
-
223
- msgid "Cancel"
224
- msgstr ""
225
-
226
- msgid "Are you sure you want to unregister?"
227
- msgstr ""
228
-
229
- msgid "Click to see individual components options."
230
- msgstr ""
1
+ # This file was generated by WPML
2
+ # WPML is a WordPress plugin that can turn any WordPress site into a full featured multilingual content management system.
3
+ # https://wpml.org
4
+ msgid ""
5
+ msgstr ""
6
+ "Content-Type: text/plain; charset=utf-8\n"
7
+ "Content-Transfer-Encoding: 8bit\n"
8
+ "Project-Id-Version:WPML_EXPORT\n"
9
+ "POT-Creation-Date: \n"
10
+ "PO-Revision-Date: \n"
11
+ "Last-Translator: \n"
12
+ "Language-Team: \n"
13
+ "Language:en\n"
14
+ "MIME-Version: 1.0\n"
15
+
16
+ msgid "Installer"
17
+ msgstr ""
18
+
19
+ msgid "Registered"
20
+ msgstr ""
21
+
22
+ msgid "Register"
23
+ msgstr ""
24
+
25
+ msgid "To get automatic updates, you need to register %s for this site. %sRegister %s%s"
26
+ msgstr ""
27
+
28
+ msgid "Dismiss"
29
+ msgstr ""
30
+
31
+ msgid "Commercial"
32
+ msgstr ""
33
+
34
+ msgid "Installer cannot contact our updates server to get information about the available products and check for new versions. If you are seeing this message for the first time, you can ignore it, as it may be a temporary communication problem. If the problem persists and your WordPress admin is slowing down, you can disable automated version checks. Add the following line to your wp-config.php file:"
35
+ msgstr ""
36
+
37
+ msgid "No repositories defined."
38
+ msgstr ""
39
+
40
+ msgid "%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates."
41
+ msgstr ""
42
+
43
+ msgid "Invalid site key for the current site."
44
+ msgstr ""
45
+
46
+ msgid "You will have to renew your subscription in order to continue getting the updates and support."
47
+ msgstr ""
48
+
49
+ msgid "%sRenew here%s."
50
+ msgstr ""
51
+
52
+ msgid "Your subscription appears to no longer be valid. Please try to register again using a valid site key."
53
+ msgstr ""
54
+
55
+ msgid "You need to have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s."
56
+ msgstr ""
57
+
58
+ msgid "%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first."
59
+ msgstr ""
60
+
61
+ msgid "Update Plugin"
62
+ msgstr ""
63
+
64
+ msgid "Return to the plugins page"
65
+ msgstr ""
66
+
67
+ msgid "Your subscription expires in %d day."
68
+ msgstr ""
69
+
70
+ msgid "Your subscription expires in %d days."
71
+ msgstr ""
72
+
73
+ msgid "Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s."
74
+ msgstr ""
75
+
76
+ msgid "Plugin"
77
+ msgstr ""
78
+
79
+ msgid "downloading..."
80
+ msgstr ""
81
+
82
+ msgid "failed!"
83
+ msgstr ""
84
+
85
+ msgid "downloaded"
86
+ msgstr ""
87
+
88
+ msgid "activating"
89
+ msgstr ""
90
+
91
+ msgid "activated"
92
+ msgstr ""
93
+
94
+ msgid "Activate after download"
95
+ msgstr ""
96
+
97
+ msgid "Operation complete!"
98
+ msgstr ""
99
+
100
+ msgid "Download failed!\n\nClick OK to revalidate your subscription or CANCEL to try again."
101
+ msgstr ""
102
+
103
+ msgid "Available"
104
+ msgstr ""
105
+
106
+ msgid "Installed"
107
+ msgstr ""
108
+
109
+ msgid "Downloading"
110
+ msgstr ""
111
+
112
+ msgid "Activate"
113
+ msgstr ""
114
+
115
+ msgid "Download"
116
+ msgstr ""
117
+
118
+ msgid "Downloads:"
119
+ msgstr ""
120
+
121
+ msgid "Current version"
122
+ msgstr ""
123
+
124
+ msgid "Released"
125
+ msgstr ""
126
+
127
+ msgid "Installed version"
128
+ msgstr ""
129
+
130
+ msgid "(embedded)"
131
+ msgstr ""
132
+
133
+ msgid "installing..."
134
+ msgstr ""
135
+
136
+ msgid "updating..."
137
+ msgstr ""
138
+
139
+ msgid "installed"
140
+ msgstr ""
141
+
142
+ msgid "updated"
143
+ msgstr ""
144
+
145
+ msgid "Download failed!\n\nPlease refresh the page and try again."
146
+ msgstr ""
147
+
148
+ msgid "Incorrect setup"
149
+ msgstr ""
150
+
151
+ msgid "Invalid product"
152
+ msgstr ""
153
+
154
+ msgid "Unknown repository"
155
+ msgstr ""
156
+
157
+ msgid " Your current site key (%s) does not match the selected product (%s)."
158
+ msgstr ""
159
+
160
+ msgid "Buy %s"
161
+ msgstr ""
162
+
163
+ msgid "Already bought %s?"
164
+ msgstr ""
165
+
166
+ msgid "Renew %s"
167
+ msgstr ""
168
+
169
+ msgid "Remove current site key (%s)"
170
+ msgstr ""
171
+
172
+ msgid "%s support on wpml.org"
173
+ msgstr ""
174
+
175
+ msgid "Enter site key"
176
+ msgstr ""
177
+
178
+ msgid "Subscription is expired."
179
+ msgstr ""
180
+
181
+ msgid "Add"
182
+ msgstr ""
183
+
184
+ msgid "Are you sure you want to remove this site key?"
185
+ msgstr ""
186
+
187
+ msgid "Register %s"
188
+ msgstr ""
189
+
190
+ msgid "1. Go to your %s%s account%s and add this site URL: %s"
191
+ msgstr ""
192
+
193
+ msgid "Unregister %s from this site"
194
+ msgstr ""
195
+
196
+ msgid "%s is registered on this site. You will receive automatic updates until %s"
197
+ msgstr ""
198
+
199
+ msgid "%s is registered on this site. Your Lifetime account gives you updates for life."
200
+ msgstr ""
201
+
202
+ msgid "This page lets you install plugins and update existing plugins. To remove any of these plugins, go to the %splugins%s page and if you have the permission to remove plugins you should be able to do this."
203
+ msgstr ""
204
+
205
+ msgid "Already bought?"
206
+ msgstr ""
207
+
208
+ msgid "2. Enter your site key"
209
+ msgstr ""
210
+
211
+ msgid "Subscription is expired. You need to either purchase a new subscription or upgrade if available."
212
+ msgstr ""
213
+
214
+ msgid "Check for updates"
215
+ msgstr ""
216
+
217
+ msgid "Individual components"
218
+ msgstr ""
219
+
220
+ msgid "OK"
221
+ msgstr ""
222
+
223
+ msgid "Cancel"
224
+ msgstr ""
225
+
226
+ msgid "Are you sure you want to unregister?"
227
+ msgstr ""
228
+
229
+ msgid "Click to see individual components options."
230
+ msgstr ""
embedded/otgs/installer/repositories.xml CHANGED
@@ -1,13 +1,13 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <repositories>
3
- <repository>
4
- <id>wpml</id>
5
- <apiurl>https://api.wpml.org/</apiurl>
6
- <products>http://d2salfytceyqoe.cloudfront.net/wpml33-products.json</products>
7
- </repository>
8
- <repository>
9
- <id>toolset</id>
10
- <apiurl>https://api.wp-types.com/</apiurl>
11
- <products>http://d7j863fr5jhrr.cloudfront.net/toolset33-products.json</products>
12
- </repository>
13
- </repositories>
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <repositories>
3
+ <repository>
4
+ <id>wpml</id>
5
+ <apiurl>https://api.wpml.org/</apiurl>
6
+ <products>http://d2salfytceyqoe.cloudfront.net/wpml33-products.json</products>
7
+ </repository>
8
+ <repository>
9
+ <id>toolset</id>
10
+ <apiurl>https://api.wp-types.com/</apiurl>
11
+ <products>http://d7j863fr5jhrr.cloudfront.net/toolset33-products.json</products>
12
+ </repository>
13
+ </repositories>
embedded/otgs/installer/res/css/admin.css CHANGED
@@ -1,186 +1,186 @@
1
- .otgsi_site_key_form{
2
- display:none;
3
- /*display:inline;*/
4
- }
5
-
6
- .installer-status-installing, .installer-status-installed, .installer-status-updating, .installer-status-updated, .installer-status-activating, .installer-status-activated, .installer-status-success{
7
- display: none;
8
- }
9
- .installer-status-installing{color: #FF9900; }
10
- .installer-status-installed{color: #003300; font-weight: bold; }
11
- .installer-status-updating{color: #FF9900; }
12
- .installer-status-updated{color: #003300; font-weight: bold; }
13
-
14
- .installer-status-activating{color: #996666 }
15
- .installer-status-activated{color: #333366; font-weight: bold; }
16
-
17
- .js-status-success p{
18
- color: #FF9900;
19
- padding: 4px;
20
- }
21
-
22
- .installer-green-text{
23
- color:#006600;
24
- font-weight:bold;
25
- }
26
-
27
- .installer-red-text{
28
- color:#b22121;
29
- font-weight:bold;
30
- }
31
-
32
- .installer-products-list li{
33
- display: inline;
34
- margin-right: 20px;
35
- }
36
-
37
- .otgs_wp_installer_table a.disabled{
38
- color:#888;
39
- }
40
-
41
- .otgs_wp_installer_subtable{
42
- clear: both;
43
- margin-left:-20px;
44
- }
45
- .otgs_wp_installer_subtable td p{
46
- font-size: 92%;
47
- }
48
-
49
- .installer-status-error{
50
- color: #f00;
51
- }
52
-
53
- .installer-status-note{
54
- color: #6F6E6D;
55
- font-style: italic;
56
- }
57
-
58
- .installer-warn-box{
59
- -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #962722;background-color:#F5C8C6;
60
- color: #333;
61
- padding: 5px;
62
- }
63
- .installer-warn-box span.details{
64
- font-style: italic;
65
- color:#777;
66
- }
67
-
68
- .installer-error-box{
69
- color:#962722;
70
- margin-top: 10px;
71
- }
72
- .installer-error-box p{
73
- margin: 10px 0 10px 0;
74
- -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #962722;background-color:#F5C8C6;
75
- color: #333;
76
- padding: 5px;
77
- text-align: center;
78
- }
79
-
80
- .spinner-inline{
81
- float: none;
82
- display: inline-block;
83
- visibility: visible;
84
- }
85
-
86
- .installer-q-icon:before{
87
- content: '\f223' !important;
88
- }
89
-
90
- .otgsi_yellow_bg{
91
- background-color: #f2f46b;
92
- }
93
-
94
- .otgs_wp_installer_table_compact{
95
- width:480px;
96
- border: solid 1px #999;
97
- padding:10px;
98
- border-radius: 5px;
99
- }
100
-
101
- .installer-plugins-list-compact{
102
- background-color: #fff;
103
- border-collapse: collapse;
104
- border:solid 1px #C1DAD7;
105
- width:100%;
106
- }
107
-
108
- .installer-plugins-list-compact tr th{
109
- padding-top:3px;
110
- background-color: #ccc;
111
- }
112
-
113
- .installer-plugins-list-compact tr{
114
- background-color: #ddd;
115
- }
116
-
117
- .installer-plugins-list-compact tr.even{
118
- background-color: #eee;
119
- }
120
-
121
- .installer-plugins-list-compact td{
122
- padding:2px 5px 2px 5px;
123
- border-right: 1px solid #C1DAD7;
124
- border-bottom: 1px solid #C1DAD7;
125
- }
126
-
127
- .installer-plugins-list-compact td.twelve{
128
- width:16px;
129
- }
130
-
131
- .otgs_wp_installer_table_compact .installer-status-downloading,
132
- .otgs_wp_installer_table_compact .installer-status-downloaded,
133
- .otgs_wp_installer_table_compact .installer-status-activating,
134
- .otgs_wp_installer_table_compact .installer-status-activated{
135
- display: none;
136
- color:transparent; width: 12px; padding:2px;
137
- }
138
-
139
- .otgs_wp_installer_table_compact .installer-status-success,
140
- .otgs_wp_installer_table_compact .installer-status-fail{
141
- display: none;
142
- }
143
-
144
- .installer-status-success{
145
- float: right;
146
- color: #006600;
147
- }
148
-
149
- .otgs_wp_installer_table_compact .installer-status-downloading{background: url(../img/dn.gif) no-repeat center; }
150
- .otgs_wp_installer_table_compact .installer-status-downloaded{background: url(../img/complete.png) no-repeat center;}
151
- .otgs_wp_installer_table_compact .installer-status-activating{background: url(../img/dn.gif) no-repeat center; }
152
- .otgs_wp_installer_table_compact .installer-status-activated{background: url(../img/complete.png) no-repeat center; }
153
- .otgs_wp_installer_table_compact .installer-status-error{background: url(../img/icon_error.gif) no-repeat center; }
154
-
155
- .installer_highlight{
156
- color:#c5510b;
157
- }
158
-
159
- .installer_highlight_package{
160
- background-color: #fff9c0;
161
- }
162
-
163
- .plugin_progress{
164
- font-style: italic;
165
- color: #777
166
- }
167
-
168
- .installer-download-progress-status{
169
- display: none;
170
- float:right;
171
- color: #006600;
172
- font-style: italic;
173
- background: url('../img/spinner.gif') no-repeat;
174
- padding-left:24px;
175
- }
176
-
177
- .otgs-is-dismissible {
178
- position: relative;
179
- padding-right: 38px;
180
- }
181
- .otgs-is-dismissible .notice-dismiss {
182
- text-decoration: none;
183
- }
184
- .otgs-is-dismissible p [class*="button-"] {
185
- margin: -5px 5px;
186
  }
1
+ .otgsi_site_key_form{
2
+ display:none;
3
+ /*display:inline;*/
4
+ }
5
+
6
+ .installer-status-installing, .installer-status-installed, .installer-status-updating, .installer-status-updated, .installer-status-activating, .installer-status-activated, .installer-status-success{
7
+ display: none;
8
+ }
9
+ .installer-status-installing{color: #FF9900; }
10
+ .installer-status-installed{color: #003300; font-weight: bold; }
11
+ .installer-status-updating{color: #FF9900; }
12
+ .installer-status-updated{color: #003300; font-weight: bold; }
13
+
14
+ .installer-status-activating{color: #996666 }
15
+ .installer-status-activated{color: #333366; font-weight: bold; }
16
+
17
+ .js-status-success p{
18
+ color: #FF9900;
19
+ padding: 4px;
20
+ }
21
+
22
+ .installer-green-text{
23
+ color:#006600;
24
+ font-weight:bold;
25
+ }
26
+
27
+ .installer-red-text{
28
+ color:#b22121;
29
+ font-weight:bold;
30
+ }
31
+
32
+ .installer-products-list li{
33
+ display: inline;
34
+ margin-right: 20px;
35
+ }
36
+
37
+ .otgs_wp_installer_table a.disabled{
38
+ color:#888;
39
+ }
40
+
41
+ .otgs_wp_installer_subtable{
42
+ clear: both;
43
+ margin-left:-20px;
44
+ }
45
+ .otgs_wp_installer_subtable td p{
46
+ font-size: 92%;
47
+ }
48
+
49
+ .installer-status-error{
50
+ color: #f00;
51
+ }
52
+
53
+ .installer-status-note{
54
+ color: #6F6E6D;
55
+ font-style: italic;
56
+ }
57
+
58
+ .installer-warn-box{
59
+ -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #962722;background-color:#F5C8C6;
60
+ color: #333;
61
+ padding: 5px;
62
+ }
63
+ .installer-warn-box span.details{
64
+ font-style: italic;
65
+ color:#777;
66
+ }
67
+
68
+ .installer-error-box{
69
+ color:#962722;
70
+ margin-top: 10px;
71
+ }
72
+ .installer-error-box p{
73
+ margin: 10px 0 10px 0;
74
+ -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #962722;background-color:#F5C8C6;
75
+ color: #333;
76
+ padding: 5px;
77
+ text-align: center;
78
+ }
79
+
80
+ .spinner-inline{
81
+ float: none;
82
+ display: inline-block;
83
+ visibility: visible;
84
+ }
85
+
86
+ .installer-q-icon:before{
87
+ content: '\f223' !important;
88
+ }
89
+
90
+ .otgsi_yellow_bg{
91
+ background-color: #f2f46b;
92
+ }
93
+
94
+ .otgs_wp_installer_table_compact{
95
+ width:480px;
96
+ border: solid 1px #999;
97
+ padding:10px;
98
+ border-radius: 5px;
99
+ }
100
+
101
+ .installer-plugins-list-compact{
102
+ background-color: #fff;
103
+ border-collapse: collapse;
104
+ border:solid 1px #C1DAD7;
105
+ width:100%;
106
+ }
107
+
108
+ .installer-plugins-list-compact tr th{
109
+ padding-top:3px;
110
+ background-color: #ccc;
111
+ }
112
+
113
+ .installer-plugins-list-compact tr{
114
+ background-color: #ddd;
115
+ }
116
+
117
+ .installer-plugins-list-compact tr.even{
118
+ background-color: #eee;
119
+ }
120
+
121
+ .installer-plugins-list-compact td{
122
+ padding:2px 5px 2px 5px;
123
+ border-right: 1px solid #C1DAD7;
124
+ border-bottom: 1px solid #C1DAD7;
125
+ }
126
+
127
+ .installer-plugins-list-compact td.twelve{
128
+ width:16px;
129
+ }
130
+
131
+ .otgs_wp_installer_table_compact .installer-status-downloading,
132
+ .otgs_wp_installer_table_compact .installer-status-downloaded,
133
+ .otgs_wp_installer_table_compact .installer-status-activating,
134
+ .otgs_wp_installer_table_compact .installer-status-activated{
135
+ display: none;
136
+ color:transparent; width: 12px; padding:2px;
137
+ }
138
+
139
+ .otgs_wp_installer_table_compact .installer-status-success,
140
+ .otgs_wp_installer_table_compact .installer-status-fail{
141
+ display: none;
142
+ }
143
+
144
+ .installer-status-success{
145
+ float: right;
146
+ color: #006600;
147
+ }
148
+
149
+ .otgs_wp_installer_table_compact .installer-status-downloading{background: url(../img/dn.gif) no-repeat center; }
150
+ .otgs_wp_installer_table_compact .installer-status-downloaded{background: url(../img/complete.png) no-repeat center;}
151
+ .otgs_wp_installer_table_compact .installer-status-activating{background: url(../img/dn.gif) no-repeat center; }
152
+ .otgs_wp_installer_table_compact .installer-status-activated{background: url(../img/complete.png) no-repeat center; }
153
+ .otgs_wp_installer_table_compact .installer-status-error{background: url(../img/icon_error.gif) no-repeat center; }
154
+
155
+ .installer_highlight{
156
+ color:#c5510b;
157
+ }
158
+
159
+ .installer_highlight_package{
160
+ background-color: #fff9c0;
161
+ }
162
+
163
+ .plugin_progress{
164
+ font-style: italic;
165
+ color: #777
166
+ }
167
+
168
+ .installer-download-progress-status{
169
+ display: none;
170
+ float:right;
171
+ color: #006600;
172
+ font-style: italic;
173
+ background: url('../img/spinner.gif') no-repeat;
174
+ padding-left:24px;
175
+ }
176
+
177
+ .otgs-is-dismissible {
178
+ position: relative;
179
+ padding-right: 38px;
180
+ }
181
+ .otgs-is-dismissible .notice-dismiss {
182
+ text-decoration: none;
183
+ }
184
+ .otgs-is-dismissible p [class*="button-"] {
185
+ margin: -5px 5px;
186
  }
embedded/otgs/installer/res/js/admin.js CHANGED
@@ -1,403 +1,403 @@
1
- var otgs_wp_installer = {
2
-
3
- init: function(){
4
-
5
- jQuery('.otgs_wp_installer_table').on('click', '.enter_site_key_js', otgs_wp_installer.show_site_key_form);
6
- jQuery('.otgs_wp_installer_table').on('click', '.cancel_site_key_js', otgs_wp_installer.hide_site_key_form);
7
-
8
- jQuery('.otgs_wp_installer_table').on('click', '.remove_site_key_js', otgs_wp_installer.remove_site_key);
9
- jQuery('.otgs_wp_installer_table').on('click', '.update_site_key_js', otgs_wp_installer.update_site_key);
10
-
11
- jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_site_key_form', otgs_wp_installer.save_site_key);
12
- jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_downloads_form', otgs_wp_installer.download_downloads);
13
- jQuery('.otgs_wp_installer_table').on('change', '.otgsi_downloads_form :checkbox[name="downloads[]"]', otgs_wp_installer.update_downloads_form);
14
-
15
- jQuery('.installer-dismiss-nag').click(otgs_wp_installer.dismiss_nag);
16
-
17
- jQuery('.otgs_wp_installer_table').on('click', '.installer_expand_button', otgs_wp_installer.toggle_subpackages);
18
-
19
- otgs_wp_installer.scroll_to_repository();
20
-
21
- if( typeof pagenow != 'undefined' && pagenow == 'plugins'){
22
-
23
- jQuery(document).ajaxSuccess(function(event, xhr, settings) {
24
- var data = otgs_wp_installer.getQueryParameters(settings.data);
25
- if(typeof data.action != 'undefined' && data.action == 'update-plugin'){
26
- response = xhr.responseJSON.data;
27
- console.log(typeof response.error);
28
- if(typeof response.error != 'undefined'){
29
- var default_error = jQuery('#' + response.slug + '-update .update-message').html();
30
- jQuery('#' + response.slug + '-update .update-message').html(default_error + ' &raquo;<span class="installer-red-text"> ' + response.error + '</span>');
31
- }
32
- }
33
- return false;
34
- });
35
-
36
- }
37
-
38
- },
39
-
40
- getQueryParameters : function(str) {
41
- return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
42
- },
43
-
44
- reset_errors: function(){
45
- jQuery('.installer-error-box').html('').hide();
46
- },
47
-
48
- show_error: function(repo, text){
49
- jQuery('#installer_repo_' + repo).find('.installer-error-box').html(text).show();
50
- },
51
-
52
- show_site_key_form: function(){
53
- otgs_wp_installer.reset_errors();
54
-
55
- var form = jQuery(this).parent().find('form.otgsi_site_key_form');
56
- jQuery(this).prev().hide();
57
- jQuery(this).hide();
58
- form.css('display', 'inline');
59
- form.find('input[name^=site_key_]').focus().val('');
60
- form.find('input').removeAttr('disabled');
61
-
62
- form.closest('.otgsi_register_product_wrap').addClass('otgsi_yellow_bg');
63
-
64
- return false;
65
- },
66
-
67
- hide_site_key_form: function(){
68
- var form = jQuery(this).closest('form');
69
- form.hide();
70
- form.parent().find('.enter_site_key_js').show();
71
- form.parent().find('.enter_site_key_js').prev().show();
72
-
73
- form.closest('.otgsi_register_product_wrap').removeClass('otgsi_yellow_bg');
74
- otgs_wp_installer.reset_errors();
75
- return false;
76
- },
77
-
78
- save_site_key: function(){
79
-
80
- var thisf = jQuery(this);
81
- var data = jQuery(this).serialize();
82
- jQuery(this).find('input').attr('disabled', 'disabled');
83
-
84
- var spinner = jQuery('<span class="spinner"></span>');
85
- spinner.css({display: 'inline-block', float: 'none'}).prependTo(jQuery(this));
86
-
87
- otgs_wp_installer.reset_errors();
88
-
89
- jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
90
- function(ret){
91
- if(!ret.error){
92
- otgs_wp_installer.saved_site_key();
93
- }else{
94
- otgs_wp_installer.show_error(thisf.find('[name=repository_id]').val(), ret.error);
95
- thisf.find('input').removeAttr('disabled');
96
- }
97
-
98
- if(typeof ret.debug != 'undefined'){
99
- thisf.append('<textarea style="width:100%" rows="20">' + ret.debug + '</textarea>');
100
- }
101
-
102
- spinner.remove();
103
- }
104
- });
105
-
106
- return false;
107
-
108
- },
109
-
110
- saved_site_key: function(){
111
- location.reload();
112
- },
113
-
114
- remove_site_key: function(){
115
-
116
- if(confirm(jQuery(this).data('confirmation'))){
117
-
118
- jQuery('<span class="spinner"></span>').css({visibility: 'visible', float: 'none'}).prependTo(jQuery(this).parent());
119
- data = {action: 'remove_site_key', repository_id: jQuery(this).data('repository'), nonce: jQuery(this).data('nonce')}
120
- jQuery.ajax({url: ajaxurl, type: 'POST', data: data, success: otgs_wp_installer.removed_site_key});
121
- }
122
-
123
- return false;
124
- },
125
-
126
- removed_site_key: function(){
127
- location.reload();
128
- },
129
-
130
- update_site_key: function(){
131
- var error_wrap = jQuery(this).closest('.otgsi_register_product_wrap').find('.installer-error-box');
132
- error_wrap.html('');
133
-
134
- var spinner = jQuery('<span class="spinner"></span>');
135
-
136
- spinner.css({visibility: 'visible', float: 'none'}).prependTo(jQuery(this).parent());
137
- data = {action: 'update_site_key', repository_id: jQuery(this).data('repository'), nonce: jQuery(this).data('nonce')}
138
- jQuery.ajax({
139
- url: ajaxurl,
140
- type: 'POST',
141
- data: data,
142
- dataType: 'json',
143
- complete: function( event, xhr, settings ){
144
- var error = '';
145
- if(xhr == 'success') {
146
- var ret = event.responseJSON;
147
- if(ret.error){
148
- error = ret.error;
149
- }else{
150
- otgs_wp_installer.updated_site_key(ret);
151
- }
152
- }else{
153
- error = 'Error processing request (' + xhr + '). Please try again!';
154
- }
155
-
156
- if( error ){
157
- error_wrap.html('<p>' + error + '</p>').show();
158
- spinner.remove();
159
- }
160
-
161
- }
162
- });
163
-
164
- return false;
165
-
166
- },
167
-
168
- updated_site_key: function(ret){
169
- location.reload();
170
- },
171
-
172
- update_downloads_form: function(){
173
-
174
- var checked = jQuery('.otgsi_downloads_form :checkbox:checked[name="downloads[]"]').length;
175
-
176
- if(checked){
177
- jQuery(this).closest('form').find(':submit, :checkbox[name=activate]').removeAttr('disabled');
178
- }else{
179
- jQuery(this).closest('form').find(':submit, :checkbox[name=activate]').attr('disabled', 'disabled');
180
- }
181
-
182
-
183
- },
184
-
185
- download_downloads: function(){
186
-
187
- var activate = jQuery(this).find(":checkbox:checked[name=activate]").val(),
188
- action_button = jQuery(this).find('input[type="submit"]');
189
- downloads_form = jQuery(this),
190
- idx = 0,
191
- checkboxes = [];
192
-
193
- jQuery(this).find(':checkbox:checked[name="downloads[]"]').each(function(){
194
- if(jQuery(this).attr('disabled')) return;
195
- checkboxes[idx] = jQuery(this);
196
- idx++;
197
- jQuery(this).attr('disabled', 'disabled');
198
- });
199
-
200
- idx = 0;
201
-
202
- if( typeof checkboxes[idx] != 'undefined' ){
203
- download_and_activate( checkboxes[idx] );
204
- action_button.attr('disabled', 'disabled');
205
- }
206
-
207
- function download_and_activate( elem ){
208
-
209
- var this_tr = elem.closest('tr');
210
- var is_update = this_tr.find('.installer-red-text').length;
211
- if(is_update){
212
- var installing = this_tr.find('.installer-status-updating');
213
- var installed = this_tr.find('.installer-status-updated');
214
- }else{
215
- var installing = this_tr.find('.installer-status-installing');
216
- var installed = this_tr.find('.installer-status-installed');
217
-
218
- }
219
- if(activate){
220
- var activating = this_tr.find('.installer-status-activating');
221
- var activated = this_tr.find('.installer-status-activated');
222
- }
223
-
224
- if( this_tr.find('.for_spinner_js .spinner').length > 0 ){
225
- var spinner = this_tr.find('.for_spinner_js .spinner');
226
- }else{
227
- var spinner = this_tr.find('.installer-status-downloading');
228
- }
229
-
230
- otgs_wp_installer.reset_errors();
231
- downloads_form.find('div.installer-status-success').hide();
232
- spinner.css('visibility', 'visible');
233
- installing.show();
234
-
235
- var plugin_name = this_tr.find('.installer_plugin_name').html();
236
- if(is_update){
237
- otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.updating.replace('%s', plugin_name));
238
- }else{
239
- otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.installing.replace('%s', plugin_name));
240
- }
241
-
242
-
243
- data = {action: 'installer_download_plugin', data: elem.val(), activate: activate}
244
-
245
- jQuery.ajax({
246
- url: ajaxurl,
247
- type: 'POST',
248
- dataType: 'json',
249
- data: data,
250
- success: function(ret){
251
- installing.hide();
252
-
253
- if(!ret.success){
254
- installed.addClass('installer-status-error');
255
- installed.html(installed.data('fail'));
256
-
257
- if(ret.message){
258
- installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + ret.message + '</p>').show();
259
- }else{
260
- installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + downloads_form.find('.installer-revalidate-message').html() + '</p>').show();
261
- }
262
-
263
-
264
- }
265
-
266
- installed.show();
267
- spinner.fadeOut();
268
-
269
- if(ret.version){
270
- this_tr.find('.installer_version_installed').html('<span class="installer-green-text">' + ret.version + '</span>');
271
- }
272
-
273
- if(ret.success && activate){
274
-
275
- otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.activating.replace('%s', plugin_name));
276
- activating.show();
277
- spinner.show();
278
- this_tr.find('.installer-red-text').removeClass('installer-red-text').addClass('installer-green-text').html(ret.version);
279
-
280
- jQuery.ajax({
281
- url: ajaxurl,
282
- type: 'POST',
283
- dataType: 'json',
284
- data: {action: 'installer_activate_plugin', plugin_id: ret.plugin_id, nonce: ret.nonce},
285
- success: function(ret){
286
- activating.hide();
287
- if(!ret.error ){
288
- activated.show();
289
- }
290
-
291
- spinner.fadeOut();
292
-
293
- idx++;
294
- if( typeof checkboxes[idx] != 'undefined' ){
295
- download_and_activate( checkboxes[idx] );
296
- }else{
297
- otgs_wp_installer.hide_download_progress_status(downloads_form);
298
- downloads_form.find('div.installer-status-success').show();
299
- action_button.removeAttr('disabled');
300
- }
301
- }
302
- });
303
- }else{
304
- idx++;
305
- if( typeof checkboxes[idx] != 'undefined' ){
306
- download_and_activate( checkboxes[idx] );
307
- }else{
308
- otgs_wp_installer.hide_download_progress_status(downloads_form);
309
- downloads_form.find('div.installer-status-success').show();
310
- action_button.removeAttr('disabled');
311
- }
312
- }
313
- }
314
-
315
- });
316
-
317
- };
318
-
319
- return false;
320
- },
321
-
322
-
323
- show_download_progress_status: function(downloads_form, text){
324
-
325
- downloads_form.find('.installer-download-progress-status').html(text).fadeIn();
326
-
327
- },
328
-
329
- hide_download_progress_status: function(downloads_form){
330
-
331
- downloads_form.find('.installer-download-progress-status').html('').fadeOut();
332
-
333
- },
334
-
335
- dismiss_nag: function(){
336
-
337
- var thisa = jQuery(this);
338
-
339
- data = {action: 'installer_dismiss_nag', repository: jQuery(this).data('repository')}
340
-
341
- jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
342
- function(ret){
343
- thisa.closest('.otgs-is-dismissible').remove();
344
- }
345
- });
346
-
347
- return false;
348
- },
349
-
350
- toggle_subpackages: function(){
351
- var list = jQuery(this).closest('td').find('.otgs_wp_installer_subtable');
352
-
353
- if(list.is(':visible')){
354
- list.slideUp('fast');
355
- }else{
356
- list.slideDown('fast');
357
- }
358
-
359
-
360
- return false;
361
-
362
- },
363
-
364
- scroll_to_repository: function(){
365
-
366
- var ref = window.location.hash.replace('#', '');
367
-
368
- if(ref) {
369
- var split = ref.split('/');
370
- var repo = split[0];
371
-
372
- if(typeof split[1] != 'undefined'){
373
- var package = split[1];
374
- var repo_element = jQuery('#repository-' + repo);
375
-
376
-
377
-
378
- if(repo_element.length){
379
-
380
- jQuery('html, body').animate({
381
- scrollTop: repo_element.offset().top
382
- }, 1000);
383
-
384
- var package_element = jQuery('#repository-' + repo +'_' + package);
385
-
386
- if(package_element.length && !package_element.is(':visible')){
387
- package_element.parents('.otgs_wp_installer_subtable').slideDown();
388
- package_element.addClass('installer_highlight_package');
389
- }
390
-
391
- package_element.find('.button-secondary').removeClass('button-secondary').addClass('button-primary');
392
- }
393
- }
394
-
395
- }
396
-
397
- }
398
-
399
-
400
- }
401
-
402
-
403
  jQuery(document).ready(otgs_wp_installer.init);
1
+ var otgs_wp_installer = {
2
+
3
+ init: function(){
4
+
5
+ jQuery('.otgs_wp_installer_table').on('click', '.enter_site_key_js', otgs_wp_installer.show_site_key_form);
6
+ jQuery('.otgs_wp_installer_table').on('click', '.cancel_site_key_js', otgs_wp_installer.hide_site_key_form);
7
+
8
+ jQuery('.otgs_wp_installer_table').on('click', '.remove_site_key_js', otgs_wp_installer.remove_site_key);
9
+ jQuery('.otgs_wp_installer_table').on('click', '.update_site_key_js', otgs_wp_installer.update_site_key);
10
+
11
+ jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_site_key_form', otgs_wp_installer.save_site_key);
12
+ jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_downloads_form', otgs_wp_installer.download_downloads);
13
+ jQuery('.otgs_wp_installer_table').on('change', '.otgsi_downloads_form :checkbox[name="downloads[]"]', otgs_wp_installer.update_downloads_form);
14
+
15
+ jQuery('.installer-dismiss-nag').click(otgs_wp_installer.dismiss_nag);
16
+
17
+ jQuery('.otgs_wp_installer_table').on('click', '.installer_expand_button', otgs_wp_installer.toggle_subpackages);
18
+
19
+ otgs_wp_installer.scroll_to_repository();
20
+
21
+ if( typeof pagenow != 'undefined' && pagenow == 'plugins'){
22
+
23
+ jQuery(document).ajaxSuccess(function(event, xhr, settings) {
24
+ var data = otgs_wp_installer.getQueryParameters(settings.data);
25
+ if(typeof data.action != 'undefined' && data.action == 'update-plugin'){
26
+ response = xhr.responseJSON.data;
27
+ console.log(typeof response.error);
28
+ if(typeof response.error != 'undefined'){
29
+ var default_error = jQuery('#' + response.slug + '-update .update-message').html();
30
+ jQuery('#' + response.slug + '-update .update-message').html(default_error + ' &raquo;<span class="installer-red-text"> ' + response.error + '</span>');
31
+ }
32
+ }
33
+ return false;
34
+ });
35
+
36
+ }
37
+
38
+ },
39
+
40
+ getQueryParameters : function(str) {
41
+ return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
42
+ },
43
+
44
+ reset_errors: function(){
45
+ jQuery('.installer-error-box').html('').hide();
46
+ },
47
+
48
+ show_error: function(repo, text){
49
+ jQuery('#installer_repo_' + repo).find('.installer-error-box').html(text).show();
50
+ },
51
+
52
+ show_site_key_form: function(){
53
+ otgs_wp_installer.reset_errors();
54
+
55
+ var form = jQuery(this).parent().find('form.otgsi_site_key_form');
56
+ jQuery(this).prev().hide();
57
+ jQuery(this).hide();
58
+ form.css('display', 'inline');
59
+ form.find('input[name^=site_key_]').focus().val('');
60
+ form.find('input').removeAttr('disabled');
61
+
62
+ form.closest('.otgsi_register_product_wrap').addClass('otgsi_yellow_bg');
63
+
64
+ return false;
65
+ },
66
+
67
+ hide_site_key_form: function(){
68
+ var form = jQuery(this).closest('form');
69
+ form.hide();
70
+ form.parent().find('.enter_site_key_js').show();
71
+ form.parent().find('.enter_site_key_js').prev().show();
72
+
73
+ form.closest('.otgsi_register_product_wrap').removeClass('otgsi_yellow_bg');
74
+ otgs_wp_installer.reset_errors();
75
+ return false;
76
+ },
77
+
78
+ save_site_key: function(){
79
+
80
+ var thisf = jQuery(this);
81
+ var data = jQuery(this).serialize();
82
+ jQuery(this).find('input').attr('disabled', 'disabled');
83
+
84
+ var spinner = jQuery('<span class="spinner"></span>');
85
+ spinner.css({display: 'inline-block', float: 'none'}).prependTo(jQuery(this));
86
+
87
+ otgs_wp_installer.reset_errors();
88
+
89
+ jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
90
+ function(ret){
91
+ if(!ret.error){
92
+ otgs_wp_installer.saved_site_key();
93
+ }else{
94
+ otgs_wp_installer.show_error(thisf.find('[name=repository_id]').val(), ret.error);
95
+ thisf.find('input').removeAttr('disabled');
96
+ }
97
+
98
+ if(typeof ret.debug != 'undefined'){
99
+ thisf.append('<textarea style="width:100%" rows="20">' + ret.debug + '</textarea>');
100
+ }
101
+
102
+ spinner.remove();
103
+ }
104
+ });
105
+
106
+ return false;
107
+
108
+ },
109
+
110
+ saved_site_key: function(){
111
+ location.reload();
112
+ },
113
+
114
+ remove_site_key: function(){
115
+
116
+ if(confirm(jQuery(this).data('confirmation'))){
117
+
118
+ jQuery('<span class="spinner"></span>').css({visibility: 'visible', float: 'none'}).prependTo(jQuery(this).parent());
119
+ data = {action: 'remove_site_key', repository_id: jQuery(this).data('repository'), nonce: jQuery(this).data('nonce')}
120
+ jQuery.ajax({url: ajaxurl, type: 'POST', data: data, success: otgs_wp_installer.removed_site_key});
121
+ }
122
+
123
+ return false;
124
+ },
125
+
126
+ removed_site_key: function(){
127
+ location.reload();
128
+ },
129
+
130
+ update_site_key: function(){
131
+ var error_wrap = jQuery(this).closest('.otgsi_register_product_wrap').find('.installer-error-box');
132
+ error_wrap.html('');
133
+
134
+ var spinner = jQuery('<span class="spinner"></span>');
135
+
136
+ spinner.css({visibility: 'visible', float: 'none'}).prependTo(jQuery(this).parent());
137
+ data = {action: 'update_site_key', repository_id: jQuery(this).data('repository'), nonce: jQuery(this).data('nonce')}
138
+ jQuery.ajax({
139
+ url: ajaxurl,
140
+ type: 'POST',
141
+ data: data,
142
+ dataType: 'json',
143
+ complete: function( event, xhr, settings ){
144
+ var error = '';
145
+ if(xhr == 'success') {
146
+ var ret = event.responseJSON;
147
+ if(ret.error){
148
+ error = ret.error;
149
+ }else{
150
+ otgs_wp_installer.updated_site_key(ret);
151
+ }
152
+ }else{
153
+ error = 'Error processing request (' + xhr + '). Please try again!';
154
+ }
155
+
156
+ if( error ){
157
+ error_wrap.html('<p>' + error + '</p>').show();
158
+ spinner.remove();
159
+ }
160
+
161
+ }
162
+ });
163
+
164
+ return false;
165
+
166
+ },
167
+
168
+ updated_site_key: function(ret){
169
+ location.reload();
170
+ },
171
+
172
+ update_downloads_form: function(){
173
+
174
+ var checked = jQuery('.otgsi_downloads_form :checkbox:checked[name="downloads[]"]').length;
175
+
176
+ if(checked){
177
+ jQuery(this).closest('form').find(':submit, :checkbox[name=activate]').removeAttr('disabled');
178
+ }else{
179
+ jQuery(this).closest('form').find(':submit, :checkbox[name=activate]').attr('disabled', 'disabled');
180
+ }
181
+
182
+
183
+ },
184
+
185
+ download_downloads: function(){
186
+
187
+ var activate = jQuery(this).find(":checkbox:checked[name=activate]").val(),
188
+ action_button = jQuery(this).find('input[type="submit"]');
189
+ downloads_form = jQuery(this),
190
+ idx = 0,
191
+ checkboxes = [];
192
+
193
+ jQuery(this).find(':checkbox:checked[name="downloads[]"]').each(function(){
194
+ if(jQuery(this).attr('disabled')) return;
195
+ checkboxes[idx] = jQuery(this);
196
+ idx++;
197
+ jQuery(this).attr('disabled', 'disabled');
198
+ });
199
+
200
+ idx = 0;
201
+
202
+ if( typeof checkboxes[idx] != 'undefined' ){
203
+ download_and_activate( checkboxes[idx] );
204
+ action_button.attr('disabled', 'disabled');
205
+ }
206
+
207
+ function download_and_activate( elem ){
208
+
209
+ var this_tr = elem.closest('tr');
210
+ var is_update = this_tr.find('.installer-red-text').length;
211
+ if(is_update){
212
+ var installing = this_tr.find('.installer-status-updating');
213
+ var installed = this_tr.find('.installer-status-updated');
214
+ }else{
215
+ var installing = this_tr.find('.installer-status-installing');
216
+ var installed = this_tr.find('.installer-status-installed');
217
+
218
+ }
219
+ if(activate){
220
+ var activating = this_tr.find('.installer-status-activating');
221
+ var activated = this_tr.find('.installer-status-activated');
222
+ }
223
+
224
+ if( this_tr.find('.for_spinner_js .spinner').length > 0 ){
225
+ var spinner = this_tr.find('.for_spinner_js .spinner');
226
+ }else{
227
+ var spinner = this_tr.find('.installer-status-downloading');
228
+ }
229
+
230
+ otgs_wp_installer.reset_errors();
231
+ downloads_form.find('div.installer-status-success').hide();
232
+ spinner.css('visibility', 'visible');
233
+ installing.show();
234
+
235
+ var plugin_name = this_tr.find('.installer_plugin_name').html();
236
+ if(is_update){
237
+ otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.updating.replace('%s', plugin_name));
238
+ }else{
239
+ otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.installing.replace('%s', plugin_name));
240
+ }
241
+
242
+
243
+ data = {action: 'installer_download_plugin', data: elem.val(), activate: activate}
244
+
245
+ jQuery.ajax({
246
+ url: ajaxurl,
247
+ type: 'POST',
248
+ dataType: 'json',
249
+ data: data,
250
+ success: function(ret){
251
+ installing.hide();
252
+
253
+ if(!ret.success){
254
+ installed.addClass('installer-status-error');
255
+ installed.html(installed.data('fail'));
256
+
257
+ if(ret.message){
258
+ installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + ret.message + '</p>').show();
259
+ }else{
260
+ installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + downloads_form.find('.installer-revalidate-message').html() + '</p>').show();
261
+ }
262
+
263
+
264
+ }
265
+
266
+ installed.show();
267
+ spinner.fadeOut();
268
+
269
+ if(ret.version){
270
+ this_tr.find('.installer_version_installed').html('<span class="installer-green-text">' + ret.version + '</span>');
271
+ }
272
+
273
+ if(ret.success && activate){
274
+
275
+ otgs_wp_installer.show_download_progress_status(downloads_form, installer_strings.activating.replace('%s', plugin_name));
276
+ activating.show();
277
+ spinner.show();
278
+ this_tr.find('.installer-red-text').removeClass('installer-red-text').addClass('installer-green-text').html(ret.version);
279
+
280
+ jQuery.ajax({
281
+ url: ajaxurl,
282
+ type: 'POST',
283
+ dataType: 'json',
284
+ data: {action: 'installer_activate_plugin', plugin_id: ret.plugin_id, nonce: ret.nonce},
285
+ success: function(ret){
286
+ activating.hide();
287
+ if(!ret.error ){
288
+ activated.show();
289
+ }
290
+
291
+ spinner.fadeOut();
292
+
293
+ idx++;
294
+ if( typeof checkboxes[idx] != 'undefined' ){
295
+ download_and_activate( checkboxes[idx] );
296
+ }else{
297
+ otgs_wp_installer.hide_download_progress_status(downloads_form);
298
+ downloads_form.find('div.installer-status-success').show();
299
+ action_button.removeAttr('disabled');
300
+ }
301
+ }
302
+ });
303
+ }else{
304
+ idx++;
305
+ if( typeof checkboxes[idx] != 'undefined' ){
306
+ download_and_activate( checkboxes[idx] );
307
+ }else{
308
+ otgs_wp_installer.hide_download_progress_status(downloads_form);
309
+ downloads_form.find('div.installer-status-success').show();
310
+ action_button.removeAttr('disabled');
311
+ }
312
+ }
313
+ }
314
+
315
+ });
316
+
317
+ };
318
+
319
+ return false;
320
+ },
321
+
322
+
323
+ show_download_progress_status: function(downloads_form, text){
324
+
325
+ downloads_form.find('.installer-download-progress-status').html(text).fadeIn();
326
+
327
+ },
328
+
329
+ hide_download_progress_status: function(downloads_form){
330
+
331
+ downloads_form.find('.installer-download-progress-status').html('').fadeOut();
332
+
333
+ },
334
+
335
+ dismiss_nag: function(){
336
+
337
+ var thisa = jQuery(this);
338
+
339
+ data = {action: 'installer_dismiss_nag', repository: jQuery(this).data('repository')}
340
+
341
+ jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
342
+ function(ret){
343
+ thisa.closest('.otgs-is-dismissible').remove();
344
+ }
345
+ });
346
+
347
+ return false;
348
+ },
349
+
350
+ toggle_subpackages: function(){
351
+ var list = jQuery(this).closest('td').find('.otgs_wp_installer_subtable');
352
+
353
+ if(list.is(':visible')){
354
+ list.slideUp('fast');
355
+ }else{
356
+ list.slideDown('fast');
357
+ }
358
+
359
+
360
+ return false;
361
+
362
+ },
363
+
364
+ scroll_to_repository: function(){
365
+
366
+ var ref = window.location.hash.replace('#', '');
367
+
368
+ if(ref) {
369
+ var split = ref.split('/');
370
+ var repo = split[0];
371
+
372
+ if(typeof split[1] != 'undefined'){
373
+ var package = split[1];
374
+ var repo_element = jQuery('#repository-' + repo);
375
+
376
+
377
+
378
+ if(repo_element.length){
379
+
380
+ jQuery('html, body').animate({
381
+ scrollTop: repo_element.offset().top
382
+ }, 1000);
383
+
384
+ var package_element = jQuery('#repository-' + repo +'_' + package);
385
+
386
+ if(package_element.length && !package_element.is(':visible')){
387
+ package_element.parents('.otgs_wp_installer_subtable').slideDown();
388
+ package_element.addClass('installer_highlight_package');
389
+ }
390
+
391
+ package_element.find('.button-secondary').removeClass('button-secondary').addClass('button-primary');
392
+ }
393
+ }
394
+
395
+ }
396
+
397
+ }
398
+
399
+
400
+ }
401
+
402
+
403
  jQuery(document).ready(otgs_wp_installer.init);
embedded/otgs/installer/res/js/iframeResizer.min.js CHANGED
@@ -1,10 +1,10 @@
1
- /*! iFrame Resizer (iframeSizer.min.js ) - v2.6.1 - 2014-09-03
2
- * Desc: Force cross domain iframes to size to content.
3
- * Requires: iframeResizer.contentWindow.min.js to be loaded into the target frame.
4
- * Copyright: (c) 2014 David J. Bradshaw - dave@bradshaw.net
5
- * License: MIT
6
- */
7
-
8
- !function(){"use strict";function a(a,b,c){"addEventListener"in window?a.addEventListener(b,c,!1):"attachEvent"in window&&a.attachEvent("on"+b,c)}function b(){var a,b=["moz","webkit","o","ms"];for(a=0;a<b.length&&!w;a+=1)w=window[b[a]+"RequestAnimationFrame"];w||c(" RequestAnimationFrame not supported")}function c(a){y.log&&"object"==typeof console&&console.log(s+"[Host page"+u+"]"+a)}function d(a){function b(){function a(){h(z),f(),y.resizedCallback(z)}i(a,z,"resetPage")}function d(a){var b=a.id;c(" Removing iFrame: "+b),a.parentNode.removeChild(a),y.closedCallback(b),c(" --")}function e(){var a=x.substr(t).split(":");return{iframe:document.getElementById(a[0]),id:a[0],height:a[1],width:a[2],type:a[3]}}function j(a){var b=Number(y["max"+a]),d=Number(y["min"+a]),e=a.toLowerCase(),f=Number(z[e]);if(d>b)throw new Error("Value for min"+a+" can not be greater than max"+a);c(" Checking "+e+" is in range "+d+"-"+b),d>f&&(f=d,c(" Set "+e+" to min value")),f>b&&(f=b,c(" Set "+e+" to max value")),z[e]=""+f}function k(){var b=a.origin,d=z.iframe.src.split("/").slice(0,3).join("/");if(y.checkOrigin&&(c(" Checking connection is from: "+d),""+b!="null"&&b!==d))throw new Error("Unexpected message received from: "+b+" for "+z.iframe.id+". Message was: "+a.data+". This error can be disabled by adding the checkOrigin: false option.");return!0}function l(){return s===(""+x).substr(0,t)}function m(){var a=z.type in{"true":1,"false":1};return a&&c(" Ignoring init message from meta parent page"),a}function n(){var a=x.substr(x.indexOf(":")+r+6);c(" MessageCallback passed: {iframe: "+z.iframe.id+", message: "+a+"}"),y.messageCallback({iframe:z.iframe,message:a}),c(" --")}function o(){if(null===z.iframe)throw new Error("iFrame ("+z.id+") does not exist on "+u);return!0}function q(){c(" Reposition requested from iFrame"),v={x:z.width,y:z.height},f()}function w(){switch(z.type){case"close":d(z.iframe),y.resizedCallback(z);break;case"message":n();break;case"scrollTo":q();break;case"reset":g(z);break;case"init":b(),y.initCallback(z.iframe);break;default:b()}}var x=a.data,z={};l()&&(c(" Received: "+x),z=e(),j("Height"),j("Width"),!m()&&o()&&k()&&(w(),p=!1))}function e(){null===v&&(v={x:void 0!==window.pageXOffset?window.pageXOffset:document.documentElement.scrollLeft,y:void 0!==window.pageYOffset?window.pageYOffset:document.documentElement.scrollTop},c(" Get position: "+v.x+","+v.y))}function f(){null!==v&&(window.scrollTo(v.x,v.y),c(" Set position: "+v.x+","+v.y),v=null)}function g(a){function b(){h(a),j("reset","reset",a.iframe)}c(" Size reset requested by "+("init"===a.type?"host page":"iFrame")),e(),i(b,a,"init")}function h(a){function b(b){a.iframe.style[b]=a[b]+"px",c(" IFrame ("+a.iframe.id+") "+b+" set to "+a[b]+"px")}y.sizeHeight&&b("height"),y.sizeWidth&&b("width")}function i(a,b,d){d!==b.type&&w?(c(" Requesting animation frame"),w(a)):a()}function j(a,b,d){c("["+a+"] Sending msg to iframe ("+b+")"),d.contentWindow.postMessage(s+b,"*")}function k(){function b(){function a(a){1/0!==y[a]&&0!==y[a]&&(k.style[a]=y[a]+"px",c(" Set "+a+" = "+y[a]+"px"))}a("maxHeight"),a("minHeight"),a("maxWidth"),a("minWidth")}function d(a){return""===a&&(k.id=a="iFrameResizer"+o++,c(" Added missing iframe ID: "+a+" ("+k.src+")")),a}function e(){c(" IFrame scrolling "+(y.scrolling?"enabled":"disabled")+" for "+l),k.style.overflow=!1===y.scrolling?"hidden":"auto",k.scrolling=!1===y.scrolling?"no":"yes"}function f(){("number"==typeof y.bodyMargin||"0"===y.bodyMargin)&&(y.bodyMarginV1=y.bodyMargin,y.bodyMargin=""+y.bodyMargin+"px")}function h(){return l+":"+y.bodyMarginV1+":"+y.sizeWidth+":"+y.log+":"+y.interval+":"+y.enablePublicMethods+":"+y.autoResize+":"+y.bodyMargin+":"+y.heightCalculationMethod+":"+y.bodyBackground+":"+y.bodyPadding+":"+y.tolerance}function i(b){a(k,"load",function(){var a=p;j("iFrame.onload",b,k),!a&&y.heightCalculationMethod in x&&g({iframe:k,height:0,width:0,type:"init"})}),j("init",b,k)}var k=this,l=d(k.id);e(),b(),f(),i(h())}function l(a){if("object"!=typeof a)throw new TypeError("Options is not an object.")}function m(){function a(a){if("IFRAME"!==a.tagName.toUpperCase())throw new TypeError("Expected <IFRAME> tag, found <"+a.tagName+">.");k.call(a)}function b(a){a=a||{},l(a);for(var b in z)z.hasOwnProperty(b)&&(y[b]=a.hasOwnProperty(b)?a[b]:z[b])}return function(c,d){b(c),Array.prototype.forEach.call(document.querySelectorAll(d||"iframe"),a)}}function n(a){a.fn.iFrameResize=function(b){return b=b||{},l(b),y=a.extend({},z,b),this.filter("iframe").each(k).end()}}var o=0,p=!0,q="message",r=q.length,s="[iFrameSizer]",t=s.length,u="",v=null,w=window.requestAnimationFrame,x={max:1,scroll:1,bodyScroll:1,documentElementScroll:1},y={},z={autoResize:!0,bodyBackground:null,bodyMargin:null,bodyMarginV1:8,bodyPadding:null,checkOrigin:!0,enablePublicMethods:!1,heightCalculationMethod:"offset",interval:32,log:!1,maxHeight:1/0,maxWidth:1/0,minHeight:0,minWidth:0,scrolling:!1,sizeHeight:!0,sizeWidth:!1,tolerance:0,closedCallback:function(){},initCallback:function(){},messageCallback:function(){},resizedCallback:function(){}};b(),a(window,"message",d),"jQuery"in window&&n(jQuery),"function"==typeof define&&define.amd?define(function(){return m()}):window.iFrameResize=m()}();
9
- //# sourceMappingURL=../src/iframeResizer.map
10
-
1
+ /*! iFrame Resizer (iframeSizer.min.js ) - v2.6.1 - 2014-09-03
2
+ * Desc: Force cross domain iframes to size to content.
3
+ * Requires: iframeResizer.contentWindow.min.js to be loaded into the target frame.
4
+ * Copyright: (c) 2014 David J. Bradshaw - dave@bradshaw.net
5
+ * License: MIT
6
+ */
7
+
8
+ !function(){"use strict";function a(a,b,c){"addEventListener"in window?a.addEventListener(b,c,!1):"attachEvent"in window&&a.attachEvent("on"+b,c)}function b(){var a,b=["moz","webkit","o","ms"];for(a=0;a<b.length&&!w;a+=1)w=window[b[a]+"RequestAnimationFrame"];w||c(" RequestAnimationFrame not supported")}function c(a){y.log&&"object"==typeof console&&console.log(s+"[Host page"+u+"]"+a)}function d(a){function b(){function a(){h(z),f(),y.resizedCallback(z)}i(a,z,"resetPage")}function d(a){var b=a.id;c(" Removing iFrame: "+b),a.parentNode.removeChild(a),y.closedCallback(b),c(" --")}function e(){var a=x.substr(t).split(":");return{iframe:document.getElementById(a[0]),id:a[0],height:a[1],width:a[2],type:a[3]}}function j(a){var b=Number(y["max"+a]),d=Number(y["min"+a]),e=a.toLowerCase(),f=Number(z[e]);if(d>b)throw new Error("Value for min"+a+" can not be greater than max"+a);c(" Checking "+e+" is in range "+d+"-"+b),d>f&&(f=d,c(" Set "+e+" to min value")),f>b&&(f=b,c(" Set "+e+" to max value")),z[e]=""+f}function k(){var b=a.origin,d=z.iframe.src.split("/").slice(0,3).join("/");if(y.checkOrigin&&(c(" Checking connection is from: "+d),""+b!="null"&&b!==d))throw new Error("Unexpected message received from: "+b+" for "+z.iframe.id+". Message was: "+a.data+". This error can be disabled by adding the checkOrigin: false option.");return!0}function l(){return s===(""+x).substr(0,t)}function m(){var a=z.type in{"true":1,"false":1};return a&&c(" Ignoring init message from meta parent page"),a}function n(){var a=x.substr(x.indexOf(":")+r+6);c(" MessageCallback passed: {iframe: "+z.iframe.id+", message: "+a+"}"),y.messageCallback({iframe:z.iframe,message:a}),c(" --")}function o(){if(null===z.iframe)throw new Error("iFrame ("+z.id+") does not exist on "+u);return!0}function q(){c(" Reposition requested from iFrame"),v={x:z.width,y:z.height},f()}function w(){switch(z.type){case"close":d(z.iframe),y.resizedCallback(z);break;case"message":n();break;case"scrollTo":q();break;case"reset":g(z);break;case"init":b(),y.initCallback(z.iframe);break;default:b()}}var x=a.data,z={};l()&&(c(" Received: "+x),z=e(),j("Height"),j("Width"),!m()&&o()&&k()&&(w(),p=!1))}function e(){null===v&&(v={x:void 0!==window.pageXOffset?window.pageXOffset:document.documentElement.scrollLeft,y:void 0!==window.pageYOffset?window.pageYOffset:document.documentElement.scrollTop},c(" Get position: "+v.x+","+v.y))}function f(){null!==v&&(window.scrollTo(v.x,v.y),c(" Set position: "+v.x+","+v.y),v=null)}function g(a){function b(){h(a),j("reset","reset",a.iframe)}c(" Size reset requested by "+("init"===a.type?"host page":"iFrame")),e(),i(b,a,"init")}function h(a){function b(b){a.iframe.style[b]=a[b]+"px",c(" IFrame ("+a.iframe.id+") "+b+" set to "+a[b]+"px")}y.sizeHeight&&b("height"),y.sizeWidth&&b("width")}function i(a,b,d){d!==b.type&&w?(c(" Requesting animation frame"),w(a)):a()}function j(a,b,d){c("["+a+"] Sending msg to iframe ("+b+")"),d.contentWindow.postMessage(s+b,"*")}function k(){function b(){function a(a){1/0!==y[a]&&0!==y[a]&&(k.style[a]=y[a]+"px",c(" Set "+a+" = "+y[a]+"px"))}a("maxHeight"),a("minHeight"),a("maxWidth"),a("minWidth")}function d(a){return""===a&&(k.id=a="iFrameResizer"+o++,c(" Added missing iframe ID: "+a+" ("+k.src+")")),a}function e(){c(" IFrame scrolling "+(y.scrolling?"enabled":"disabled")+" for "+l),k.style.overflow=!1===y.scrolling?"hidden":"auto",k.scrolling=!1===y.scrolling?"no":"yes"}function f(){("number"==typeof y.bodyMargin||"0"===y.bodyMargin)&&(y.bodyMarginV1=y.bodyMargin,y.bodyMargin=""+y.bodyMargin+"px")}function h(){return l+":"+y.bodyMarginV1+":"+y.sizeWidth+":"+y.log+":"+y.interval+":"+y.enablePublicMethods+":"+y.autoResize+":"+y.bodyMargin+":"+y.heightCalculationMethod+":"+y.bodyBackground+":"+y.bodyPadding+":"+y.tolerance}function i(b){a(k,"load",function(){var a=p;j("iFrame.onload",b,k),!a&&y.heightCalculationMethod in x&&g({iframe:k,height:0,width:0,type:"init"})}),j("init",b,k)}var k=this,l=d(k.id);e(),b(),f(),i(h())}function l(a){if("object"!=typeof a)throw new TypeError("Options is not an object.")}function m(){function a(a){if("IFRAME"!==a.tagName.toUpperCase())throw new TypeError("Expected <IFRAME> tag, found <"+a.tagName+">.");k.call(a)}function b(a){a=a||{},l(a);for(var b in z)z.hasOwnProperty(b)&&(y[b]=a.hasOwnProperty(b)?a[b]:z[b])}return function(c,d){b(c),Array.prototype.forEach.call(document.querySelectorAll(d||"iframe"),a)}}function n(a){a.fn.iFrameResize=function(b){return b=b||{},l(b),y=a.extend({},z,b),this.filter("iframe").each(k).end()}}var o=0,p=!0,q="message",r=q.length,s="[iFrameSizer]",t=s.length,u="",v=null,w=window.requestAnimationFrame,x={max:1,scroll:1,bodyScroll:1,documentElementScroll:1},y={},z={autoResize:!0,bodyBackground:null,bodyMargin:null,bodyMarginV1:8,bodyPadding:null,checkOrigin:!0,enablePublicMethods:!1,heightCalculationMethod:"offset",interval:32,log:!1,maxHeight:1/0,maxWidth:1/0,minHeight:0,minWidth:0,scrolling:!1,sizeHeight:!0,sizeWidth:!1,tolerance:0,closedCallback:function(){},initCallback:function(){},messageCallback:function(){},resizedCallback:function(){}};b(),a(window,"message",d),"jQuery"in window&&n(jQuery),"function"==typeof define&&define.amd?define(function(){return m()}):window.iFrameResize=m()}();
9
+ //# sourceMappingURL=../src/iframeResizer.map
10
+
embedded/otgs/installer/res/js/installer_theme_install.js CHANGED
@@ -1,97 +1,97 @@
1
- jQuery( document ).ready( function( $ ) {
2
-
3
- /** Append OTGS Theme tab */
4
- var js_array= installer_theme_install_localize.js_array_installer;
5
-
6
- if (!($.isEmptyObject(js_array))) {
7
- //Unempty
8
- for(var key in js_array) {
9
- //Dont append if we are on commercial plugins tab page and if there are no themes
10
- if ((!(js_array[key]['is_commercial_plugin_tab'])) && (!(installer_theme_install_localize.no_associated_themes))) {
11
- $('div.wp-filter ul.filter-links').append('<li><a data-sort="'+key+'" href="#">'+ js_array[key]['the_hyperlink_text'] +'</a></li>');
12
- }
13
- }
14
- }
15
-
16
- /** Page load event tab selected identifier */
17
- var loaded_browsing_tab=installer_theme_extended_object.getParameterByName('browse');
18
- if (loaded_browsing_tab.length > 0) {
19
-
20
- var frontend_tab_selected_tab = loaded_browsing_tab;
21
-
22
- } else if (0 == loaded_browsing_tab.length){
23
-
24
- //WordPress defaults to 'Featured' when theme install is loaded without the browse parameter
25
- var frontend_tab_selected_tab = 'featured';
26
- }
27
-
28
- /** Prepare data on page load event for AJAX */
29
- var data = {
30
- action: 'installer_theme_frontend_selected_tab',
31
- installer_theme_frontend_selected_tab_nonce: installer_theme_install_localize.installer_theme_frontend_selected_tab_nonce,
32
- frontend_tab_selected :frontend_tab_selected_tab
33
- };
34
-
35
- //Call AJAX
36
- installer_theme_extended_object.doAJAX(data,frontend_tab_selected_tab,js_array);
37
-
38
- /** When user clicks on any tab */
39
- $(document).on('click','.filter-links li > a',function () {
40
-
41
- //Get data_sort
42
- var data_sort =$(this).attr('data-sort');
43
-
44
- if (data_sort) {
45
- //data_sort is set, prepare data
46
- var data = {
47
- action: 'installer_theme_frontend_selected_tab',
48
- installer_theme_frontend_selected_tab_nonce: installer_theme_install_localize.installer_theme_frontend_selected_tab_nonce,
49
- frontend_tab_selected : data_sort
50
- };
51
-
52
- //Call AJAX
53
- installer_theme_extended_object.doAJAX(data,data_sort,js_array);
54
-
55
- }
56
- });
57
-
58
- var fullhash = window.location.hash;
59
- if (fullhash.length > 0) {
60
- var product_selector=fullhash+' '+'.enter_site_key_js';
61
- if ($(product_selector).length ) {
62
- $(product_selector).click();
63
- }
64
- }
65
- });
66
-
67
- //Installer theme extended JS object for methods
68
- var installer_theme_extended_object = {
69
-
70
- getParameterByName: function(name) {
71
- name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
72
- var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
73
- results = regex.exec(location.search);
74
- return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
75
- },
76
-
77
- doAJAX: function(data,data_sort,js_array) {
78
-
79
- //We only want to post to AJAX if its an OTGS tab
80
- jQuery.post(installer_theme_install_localize.ajaxurl, data, function(response) {
81
- //AJAX response
82
- var myObject = jQuery.parseJSON(response);
83
- if (typeof myObject != "undefined") {
84
- if(myObject.hasOwnProperty("output")){
85
- var tab_selected= myObject.output;
86
- if (data_sort in js_array) {
87
- if (!(installer_theme_install_localize.js_array_installer[tab_selected]['registration_status'])) {
88
- //Not registered, no theme response
89
- var unregistered_message= myObject.unregistered_messages;
90
- jQuery('.no-themes').html(unregistered_message);
91
- }
92
- }
93
- }
94
- }
95
- });
96
- }
97
  };
1
+ jQuery( document ).ready( function( $ ) {
2
+
3
+ /** Append OTGS Theme tab */
4
+ var js_array= installer_theme_install_localize.js_array_installer;
5
+
6
+ if (!($.isEmptyObject(js_array))) {
7
+ //Unempty
8
+ for(var key in js_array) {
9
+ //Dont append if we are on commercial plugins tab page and if there are no themes
10
+ if ((!(js_array[key]['is_commercial_plugin_tab'])) && (!(installer_theme_install_localize.no_associated_themes))) {
11
+ $('div.wp-filter ul.filter-links').append('<li><a data-sort="'+key+'" href="#">'+ js_array[key]['the_hyperlink_text'] +'</a></li>');
12
+ }
13
+ }
14
+ }
15
+
16
+ /** Page load event tab selected identifier */
17
+ var loaded_browsing_tab=installer_theme_extended_object.getParameterByName('browse');
18
+ if (loaded_browsing_tab.length > 0) {
19
+
20
+ var frontend_tab_selected_tab = loaded_browsing_tab;
21
+
22
+ } else if (0 == loaded_browsing_tab.length){
23
+
24
+ //WordPress defaults to 'Featured' when theme install is loaded without the browse parameter
25
+ var frontend_tab_selected_tab = 'featured';
26
+ }
27
+
28
+ /** Prepare data on page load event for AJAX */
29
+ var data = {
30
+ action: 'installer_theme_frontend_selected_tab',
31
+ installer_theme_frontend_selected_tab_nonce: installer_theme_install_localize.installer_theme_frontend_selected_tab_nonce,
32
+ frontend_tab_selected :frontend_tab_selected_tab
33
+ };
34
+
35
+ //Call AJAX
36
+ installer_theme_extended_object.doAJAX(data,frontend_tab_selected_tab,js_array);
37
+
38
+ /** When user clicks on any tab */
39
+ $(document).on('click','.filter-links li > a',function () {
40
+
41
+ //Get data_sort
42
+ var data_sort =$(this).attr('data-sort');
43
+
44
+ if (data_sort) {
45
+ //data_sort is set, prepare data
46
+ var data = {
47
+ action: 'installer_theme_frontend_selected_tab',
48
+ installer_theme_frontend_selected_tab_nonce: installer_theme_install_localize.installer_theme_frontend_selected_tab_nonce,
49
+ frontend_tab_selected : data_sort
50
+ };
51
+
52
+ //Call AJAX
53
+ installer_theme_extended_object.doAJAX(data,data_sort,js_array);
54
+
55
+ }
56
+ });
57
+
58
+ var fullhash = window.location.hash;
59
+ if (fullhash.length > 0) {
60
+ var product_selector=fullhash+' '+'.enter_site_key_js';
61
+ if ($(product_selector).length ) {
62
+ $(product_selector).click();
63
+ }
64
+ }
65
+ });
66
+
67
+ //Installer theme extended JS object for methods
68
+ var installer_theme_extended_object = {
69
+
70
+ getParameterByName: function(name) {
71
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
72
+ var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
73
+ results = regex.exec(location.search);
74
+ return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
75
+ },
76
+
77
+ doAJAX: function(data,data_sort,js_array) {
78
+
79
+ //We only want to post to AJAX if its an OTGS tab
80
+ jQuery.post(installer_theme_install_localize.ajaxurl, data, function(response) {
81
+ //AJAX response
82
+ var myObject = jQuery.parseJSON(response);
83
+ if (typeof myObject != "undefined") {
84
+ if(myObject.hasOwnProperty("output")){
85
+ var tab_selected= myObject.output;
86
+ if (data_sort in js_array) {
87
+ if (!(installer_theme_install_localize.js_array_installer[tab_selected]['registration_status'])) {
88
+ //Not registered, no theme response
89
+ var unregistered_message= myObject.unregistered_messages;
90
+ jQuery('.no-themes').html(unregistered_message);
91
+ }
92
+ }
93
+ }
94
+ }
95
+ });
96
+ }
97
  };
embedded/otgs/installer/templates/downloads-list-compact.php CHANGED
@@ -1,80 +1,80 @@
1
-
2
- <form method="post" class="otgsi_downloads_form">
3
-
4
- <table class="installer-plugins-list-compact">
5
- <thead>
6
- <tr>
7
- <th>&nbsp;</th>
8
- <th><?php _e('Plugin', 'installer') ?></th>
9
- <th><img src="<?php echo $this->plugin_url() ?>/res/img/globe.png" alt="<?php esc_attr_e('Available', 'installer') ?>" width="16" height="16"></th>
10
- <th><img src="<?php echo $this->plugin_url() ?>/res/img/computer.png" alt="<?php esc_attr_e('Installed', 'installer') ?>" width="16" height="16"></th>
11
- <th><img src="<?php echo $this->plugin_url() ?>/res/img/dn2.gif" alt="<?php esc_attr_e('Downloading', 'installer') ?>" width="16" height="16"></th>
12
- <th><img src="<?php echo $this->plugin_url() ?>/res/img/on.png" alt="<?php esc_attr_e('Activate', 'installer') ?>" width="16" height="16"></th>
13
- </tr>
14
- </thead>
15
- <tbody>
16
- <?php foreach($product['downloads'] as $download): ?>
17
- <?php if(empty($tr_oddeven) || $tr_oddeven == 'even') $tr_oddeven = 'odd'; else $tr_oddeven = 'even'; ?>
18
- <tr class="<?php echo $tr_oddeven ?>">
19
- <td>
20
- <label>
21
- <?php
22
- $url = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id );
23
-
24
- $download_data = array(
25
- 'url' => $url,
26
- 'slug' => $download['slug'],
27
- 'nonce' => wp_create_nonce('install_plugin_' . $url),
28
- 'repository_id' => $repository_id
29
- );
30
-
31
- $disabled = $expired ||
32
- (
33
- $this->plugin_is_installed($download['name'], $download['slug'], $download['version']) &&
34
- !$this->plugin_is_embedded_version($download['name'], $download['slug'])
35
- ) || WP_Installer()->dependencies->cant_download( $repository_id );
36
-
37
- ?>
38
- <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" <?php
39
- if($disabled): ?>disabled="disabled"<?php endif; ?> />&nbsp;
40
-
41
- </label>
42
- </td>
43
- <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
44
- <td><?php echo $download['version'] ?></td>
45
- <td class="installer_version_installed">
46
- <?php if($v = $this->plugin_is_installed($download['name'], $download['slug'])):
47
- $class = version_compare($v, $download['version'], '>=') ? 'installer-green-text' : 'installer-red-text'; ?>
48
- <span class="<?php echo $class ?>"><?php echo $v; ?></span>
49
- <?php endif; ?>
50
- </td>
51
- <td class="twelve">
52
- <div class="installer-status-downloading"><?php _e('downloading...', 'installer') ?></div>
53
- <div class="installer-status-downloaded" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('downloaded', 'installer') ?></div>
54
- </td>
55
- <td class="twelve">
56
- <div class="installer-status-activating"><?php _e('activating', 'installer') ?></div>
57
- <div class="installer-status-activated"><?php _e('activated', 'installer') ?></div>
58
- </td>
59
- </tr>
60
- <?php endforeach; ?>
61
- </tbody>
62
- </table>
63
-
64
- <?php if( !WP_Installer()->dependencies->is_uploading_allowed() ): ?>
65
- <p class="installer-error-box"><?php printf(__('Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s.', 'installer'),
66
- '<a href="http://codex.wordpress.org/Changing_File_Permissions">', '</a>') ?></p>
67
- <?php elseif( WP_Installer()->dependencies->is_win_paths_exception($repository_id) ): ?>
68
- <p><?php echo WP_Installer()->dependencies->win_paths_exception_message() ?></p>
69
- <?php endif;?>
70
-
71
- <br />
72
- <input type="submit" class="button-secondary" value="<?php esc_attr_e('Download', 'installer') ?>" disabled="disabled" />
73
- &nbsp;
74
- <label><input name="activate" type="checkbox" value="1" disabled="disabled" />&nbsp;<?php _e('Activate after download', 'installer') ?></label>
75
-
76
- <div class="installer-download-progress-status"></div>
77
- <div class="installer-status-success"><?php _e('Operation complete!', 'installer') ?></div>
78
-
79
- <span class="installer-revalidate-message hidden"><?php _e("Download failed!\n\nClick OK to revalidate your subscription or CANCEL to try again.", 'installer') ?></span>
80
- </form>
1
+
2
+ <form method="post" class="otgsi_downloads_form">
3
+
4
+ <table class="installer-plugins-list-compact">
5
+ <thead>
6
+ <tr>
7
+ <th>&nbsp;</th>
8
+ <th><?php _e('Plugin', 'installer') ?></th>
9
+ <th><img src="<?php echo $this->plugin_url() ?>/res/img/globe.png" alt="<?php esc_attr_e('Available', 'installer') ?>" width="16" height="16"></th>
10
+ <th><img src="<?php echo $this->plugin_url() ?>/res/img/computer.png" alt="<?php esc_attr_e('Installed', 'installer') ?>" width="16" height="16"></th>
11
+ <th><img src="<?php echo $this->plugin_url() ?>/res/img/dn2.gif" alt="<?php esc_attr_e('Downloading', 'installer') ?>" width="16" height="16"></th>
12
+ <th><img src="<?php echo $this->plugin_url() ?>/res/img/on.png" alt="<?php esc_attr_e('Activate', 'installer') ?>" width="16" height="16"></th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <?php foreach($product['downloads'] as $download): ?>
17
+ <?php if(empty($tr_oddeven) || $tr_oddeven == 'even') $tr_oddeven = 'odd'; else $tr_oddeven = 'even'; ?>
18
+ <tr class="<?php echo $tr_oddeven ?>">
19
+ <td>
20
+ <label>
21
+ <?php
22
+ $url = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id );
23
+
24
+ $download_data = array(
25
+ 'url' => $url,
26
+ 'slug' => $download['slug'],
27
+ 'nonce' => wp_create_nonce('install_plugin_' . $url),
28
+ 'repository_id' => $repository_id
29
+ );
30
+
31
+ $disabled = $expired ||
32
+ (
33
+ $this->plugin_is_installed($download['name'], $download['slug'], $download['version']) &&
34
+ !$this->plugin_is_embedded_version($download['name'], $download['slug'])
35
+ ) || WP_Installer()->dependencies->cant_download( $repository_id );
36
+
37
+ ?>
38
+ <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" <?php
39
+ if($disabled): ?>disabled="disabled"<?php endif; ?> />&nbsp;
40
+
41
+ </label>
42
+ </td>
43
+ <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
44
+ <td><?php echo $download['version'] ?></td>
45
+ <td class="installer_version_installed">
46
+ <?php if($v = $this->plugin_is_installed($download['name'], $download['slug'])):
47
+ $class = version_compare($v, $download['version'], '>=') ? 'installer-green-text' : 'installer-red-text'; ?>
48
+ <span class="<?php echo $class ?>"><?php echo $v; ?></span>
49
+ <?php endif; ?>
50
+ </td>
51
+ <td class="twelve">
52
+ <div class="installer-status-downloading"><?php _e('downloading...', 'installer') ?></div>
53
+ <div class="installer-status-downloaded" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('downloaded', 'installer') ?></div>
54
+ </td>
55
+ <td class="twelve">
56
+ <div class="installer-status-activating"><?php _e('activating', 'installer') ?></div>
57
+ <div class="installer-status-activated"><?php _e('activated', 'installer') ?></div>
58
+ </td>
59
+ </tr>
60
+ <?php endforeach; ?>
61
+ </tbody>
62
+ </table>
63
+
64
+ <?php if( !WP_Installer()->dependencies->is_uploading_allowed() ): ?>
65
+ <p class="installer-error-box"><?php printf(__('Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s.', 'installer'),
66
+ '<a href="http://codex.wordpress.org/Changing_File_Permissions">', '</a>') ?></p>
67
+ <?php elseif( WP_Installer()->dependencies->is_win_paths_exception($repository_id) ): ?>
68
+ <p><?php echo WP_Installer()->dependencies->win_paths_exception_message() ?></p>
69
+ <?php endif;?>
70
+
71
+ <br />
72
+ <input type="submit" class="button-secondary" value="<?php esc_attr_e('Download', 'installer') ?>" disabled="disabled" />
73
+ &nbsp;
74
+ <label><input name="activate" type="checkbox" value="1" disabled="disabled" />&nbsp;<?php _e('Activate after download', 'installer') ?></label>
75
+
76
+ <div class="installer-download-progress-status"></div>
77
+ <div class="installer-status-success"><?php _e('Operation complete!', 'installer') ?></div>
78
+
79
+ <span class="installer-revalidate-message hidden"><?php _e("Download failed!\n\nClick OK to revalidate your subscription or CANCEL to try again.", 'installer') ?></span>
80
+ </form>
embedded/otgs/installer/templates/downloads-list.php CHANGED
@@ -1,85 +1,85 @@
1
- <br clear="all" /><br />
2
- <strong><?php _e('Downloads:', 'installer') ?></strong>
3
-
4
- <form method="post" class="otgsi_downloads_form">
5
-
6
- <table class="widefat">
7
- <thead>
8
- <tr>
9
- <th>&nbsp;</th>
10
- <th><?php _e('Plugin', 'installer') ?></th>
11
- <th><?php _e('Current version', 'installer') ?></th>
12
- <th><?php _e('Released', 'installer') ?></th>
13
- <th><?php _e('Installed version', 'installer') ?></th>
14
- <th>&nbsp;</th>
15
- <th>&nbsp;</th>
16
- <th>&nbsp;</th>
17
- </tr>
18
- </thead>
19
- <tbody>
20
- <?php
21
- foreach($package['downloads'] as $download): ?>
22
- <tr>
23
- <td>
24
- <label>
25
- <?php
26
- $url = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
27
-
28
- $download_data = array(
29
- 'url' => $url,
30
- 'slug' => $download['slug'],
31
- 'nonce' => wp_create_nonce('install_plugin_' . $url),
32
- 'repository_id' => $repository_id
33
- );
34
- ?>
35
- <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" <?php
36
- if($this->plugin_is_installed($download['name'], $download['slug'], $download['version']) && !$this->plugin_is_embedded_version($download['name'], $download['slug']) || WP_Installer()->dependencies->cant_download($repository_id) ): ?>disabled="disabled"<?php endif; ?> />&nbsp;
37
-
38
- </label>
39
- </td>
40
- <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
41
- <td><?php echo $download['version'] ?></td>
42
- <td><?php echo date_i18n('F j, Y', strtotime($download['date'])) ?></td>
43
- <td class="installer_version_installed">
44
- <?php if($v = $this->plugin_is_installed($download['name'], $download['slug'])): $class = version_compare($v, $download['version'], '>=') ? 'installer-green-text' : 'installer-red-text'; ?>
45
- <span class="<?php echo $class ?>"><?php echo $v; ?></span>
46
- <?php if($this->plugin_is_embedded_version($download['name'], $download['slug'])): ?>&nbsp;<?php _e('(embedded)', 'installer'); ?><?php endif; ?>
47
- <?php endif; ?>
48
- </td>
49
- <td>
50
- <span class="installer-status-installing"><?php _e('installing...', 'installer') ?></span>
51
- <span class="installer-status-updating"><?php _e('updating...', 'installer') ?></span>
52
- <span class="installer-status-installed" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('installed', 'installer') ?></span>
53
- <span class="installer-status-updated" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('updated', 'installer') ?></span>
54
- </td>
55
- <td>
56
- <span class="installer-status-activating"><?php _e('activating', 'installer') ?></span>
57
- <span class="installer-status-activated"><?php _e('activated', 'installer') ?></span>
58
- </td>
59
- <td class="for_spinner_js"><span class="spinner"></span></td>
60
- </tr>
61
- <?php endforeach; ?>
62
- </tbody>
63
- </table>
64
-
65
- <br />
66
-
67
- <div class="installer-error-box">
68
- <?php if( !WP_Installer()->dependencies->is_uploading_allowed() ): ?>
69
- <p><?php printf(__('Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s.', 'installer'),
70
- '<a href="http://codex.wordpress.org/Changing_File_Permissions">', '</a>') ?></p>
71
- <?php elseif( WP_Installer()->dependencies->is_win_paths_exception($repository_id) ): ?>
72
- <p><?php echo WP_Installer()->dependencies->win_paths_exception_message() ?></p>
73
- <?php endif; ?>
74
- </div>
75
-
76
- <input type="submit" class="button-secondary" value="<?php esc_attr_e('Download', 'installer') ?>" disabled="disabled" />
77
- &nbsp;
78
- <label><input name="activate" type="checkbox" value="1" disabled="disabled" />&nbsp;<?php _e('Activate after download', 'installer') ?></label>
79
-
80
- <div class="installer-download-progress-status"></div>
81
-
82
- <div class="installer-status-success"><?php _e('Operation complete!', 'installer') ?></div>
83
-
84
- <span class="installer-revalidate-message hidden"><?php _e("Download failed!\n\nPlease refresh the page and try again.", 'installer') ?></span>
85
- </form>
1
+ <br clear="all" /><br />
2
+ <strong><?php _e('Downloads:', 'installer') ?></strong>
3
+
4
+ <form method="post" class="otgsi_downloads_form">
5
+
6
+ <table class="widefat">
7
+ <thead>
8
+ <tr>
9
+ <th>&nbsp;</th>
10
+ <th><?php _e('Plugin', 'installer') ?></th>
11
+ <th><?php _e('Current version', 'installer') ?></th>
12
+ <th><?php _e('Released', 'installer') ?></th>
13
+ <th><?php _e('Installed version', 'installer') ?></th>
14
+ <th>&nbsp;</th>
15
+ <th>&nbsp;</th>
16
+ <th>&nbsp;</th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <?php
21
+ foreach($package['downloads'] as $download): ?>
22
+ <tr>
23
+ <td>
24
+ <label>
25
+ <?php
26
+ $url = $this->append_site_key_to_download_url($download['url'], $site_key, $repository_id);
27
+
28
+ $download_data = array(
29
+ 'url' => $url,
30
+ 'slug' => $download['slug'],
31
+ 'nonce' => wp_create_nonce('install_plugin_' . $url),
32
+ 'repository_id' => $repository_id
33
+ );
34
+ ?>
35
+ <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" <?php
36
+ if($this->plugin_is_installed($download['name'], $download['slug'], $download['version']) && !$this->plugin_is_embedded_version($download['name'], $download['slug']) || WP_Installer()->dependencies->cant_download($repository_id) ): ?>disabled="disabled"<?php endif; ?> />&nbsp;
37
+
38
+ </label>
39
+ </td>
40
+ <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
41
+ <td><?php echo $download['version'] ?></td>
42
+ <td><?php echo date_i18n('F j, Y', strtotime($download['date'])) ?></td>
43
+ <td class="installer_version_installed">
44
+ <?php if($v = $this->plugin_is_installed($download['name'], $download['slug'])): $class = version_compare($v, $download['version'], '>=') ? 'installer-green-text' : 'installer-red-text'; ?>
45
+ <span class="<?php echo $class ?>"><?php echo $v; ?></span>
46
+ <?php if($this->plugin_is_embedded_version($download['name'], $download['slug'])): ?>&nbsp;<?php _e('(embedded)', 'installer'); ?><?php endif; ?>
47
+ <?php endif; ?>
48
+ </td>
49
+ <td>
50
+ <span class="installer-status-installing"><?php _e('installing...', 'installer') ?></span>
51
+ <span class="installer-status-updating"><?php _e('updating...', 'installer') ?></span>
52
+ <span class="installer-status-installed" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('installed', 'installer') ?></span>
53
+ <span class="installer-status-updated" data-fail="<?php _e('failed!', 'installer') ?>"><?php _e('updated', 'installer') ?></span>
54
+ </td>
55
+ <td>
56
+ <span class="installer-status-activating"><?php _e('activating', 'installer') ?></span>
57
+ <span class="installer-status-activated"><?php _e('activated', 'installer') ?></span>
58
+ </td>
59
+ <td class="for_spinner_js"><span class="spinner"></span></td>
60
+ </tr>
61
+ <?php endforeach; ?>
62
+ </tbody>
63
+ </table>
64
+
65
+ <br />
66
+
67
+ <div class="installer-error-box">
68
+ <?php if( !WP_Installer()->dependencies->is_uploading_allowed() ): ?>
69
+ <p><?php printf(__('Downloading is not possible because WordPress cannot write into the plugins folder. %sHow to fix%s.', 'installer'),
70
+ '<a href="http://codex.wordpress.org/Changing_File_Permissions">', '</a>') ?></p>
71
+ <?php elseif( WP_Installer()->dependencies->is_win_paths_exception($repository_id) ): ?>
72
+ <p><?php echo WP_Installer()->dependencies->win_paths_exception_message() ?></p>
73
+ <?php endif; ?>
74
+ </div>
75
+
76
+ <input type="submit" class="button-secondary" value="<?php esc_attr_e('Download', 'installer') ?>" disabled="disabled" />
77
+ &nbsp;
78
+ <label><input name="activate" type="checkbox" value="1" disabled="disabled" />&nbsp;<?php _e('Activate after download', 'installer') ?></label>
79
+
80
+ <div class="installer-download-progress-status"></div>
81
+
82
+ <div class="installer-status-success"><?php _e('Operation complete!', 'installer') ?></div>
83
+
84
+ <span class="installer-revalidate-message hidden"><?php _e("Download failed!\n\nPlease refresh the page and try again.", 'installer') ?></span>
85
+ </form>
embedded/otgs/installer/templates/products-compact.php CHANGED
@@ -1,129 +1,129 @@
1
- <h3><?php echo $args['box_title'] ?></h3>
2
-
3
- <?php
4
- if(empty($args['repository']) || empty($args['package']) || empty($args['product'])){
5
- echo __('Incorrect setup', 'installer');
6
- return;
7
- }
8
-
9
- $product = false;
10
- foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package_idx => $package){
11
-
12
- //pre 1.3 backwardds compatibility
13
- if(!isset($package['id'])){
14
- $package['id'] = sanitize_title_with_dashes($package['name']);
15
- }
16
-
17
- if($package['id'] == $args['package']){
18
- $product = $this->settings['repositories'][$repository_id]['data']['packages'][$package_idx]['products'][$args['product']];
19
- break;
20
- }
21
- }
22
-
23
-
24
- if(!$product){
25
- echo __('Invalid product', 'installer');
26
- return;
27
- }
28
-
29
- if(isset($this->settings['repositories'][$repository_id])){
30
- if(isset($this->settings['repositories'][$repository_id]['subscription']['key'])){
31
- $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
32
- }else{
33
- $site_key = false;
34
- }
35
- }else{
36
- echo __('Unknown repository', 'installer');
37
- return;
38
- }
39
-
40
- $subscription_type = $this->get_subscription_type_for_repository($repository_id);
41
- $expired = false;
42
-
43
- if($subscription_type != $product['subscription_type'] && !$this->have_superior_subscription($subscription_type, $product) && $site_key){
44
- $subscription_no_match = sprintf(__(' Your current site key (%s) does not match the selected product (%s).', 'installer'), $site_key, $product['name']);
45
- }
46
-
47
- if(!isset($args['product_name'])) $args['product_name'] = $product['name'];
48
-
49
- ?>
50
-
51
- <div class="otgs_wp_installer_table otgs_wp_installer_table_compact">
52
-
53
- <p><?php echo $args['box_description'] ?></p>
54
-
55
-
56
- <?php if(!$this->repository_has_subscription($repository_id) || !empty($subscription_no_match)): ?>
57
-
58
- <?php if(!empty($subscription_no_match)): ?>
59
- <div class="installer-warn-box">
60
- <?php echo $subscription_no_match; ?>
61
- </div>
62
- <br />
63
- <?php endif; ?>
64
-
65
- <a class="button-primary" href="<?php echo $this->append_parameters_to_buy_url($product['url'], $repository_id, $args) ?>"><?php printf(__('Buy %s', 'installer'), $args['product_name']) ?></a>
66
-
67
- <div>
68
- <br />
69
- <?php printf(__('Already bought %s?', 'installer'), $args['product_name']) ?>
70
- <a class="enter_site_key_js" href="#"><?php _e('Enter site key', 'installer') ?></a>&nbsp;&nbsp;
71
-
72
- <form class="otgsi_site_key_form" method="post">
73
- <input type="hidden" name="action" value="save_site_key" />
74
- <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('save_site_key_' . $repository_id) ?>" />
75
- <input type="hidden" name="repository_id" value="<?php echo $repository_id ?>">
76
- <input type="text" size="10" name="site_key_<?php echo $repository_id ?>" />
77
- <input class="button-secondary" type="submit" value="<?php esc_attr_e('Add', 'installer') ?>" />
78
- </form>
79
- <div class="installer-error-box hidden" style="margin-top:10px;"></div>
80
- </div>
81
-
82
- <?php else: ?>
83
-
84
- <?php if($this->repository_has_expired_subscription($repository_id)): $expired = true; ?>
85
-
86
- <div><p class="installer-warn-box"><?php _e('Subscription is expired.', 'installer') ?></p></div>
87
-
88
- <?php else: ?>
89
-
90
- <?php if($this->show_subscription_renew_warning($repository_id, $subscription_type)): ?>
91
-
92
- <ul class="installer-products-list">
93
- <?php foreach($product['renewals'] as $renewal): ?>
94
- <li>
95
- <a href="<?php echo $this->append_parameters_to_buy_url($renewal['url'], $repository_id, $args) ?>"><?php printf(__('Renew %s', 'installer'), $args['product_name']) ?></a>
96
- </li>
97
- <?php endforeach; ?>
98
- </ul>
99
-
100
- <?php endif; ?>
101
-
102
- <?php endif; ?>
103
-
104
- <center>
105
- <a class="remove_site_key_js" href="#" data-repository=<?php echo $repository_id ?> data-confirmation="<?php esc_attr_e('Are you sure you want to remove this site key?', 'installer') ?>" data-nonce="<?php echo wp_create_nonce('remove_site_key_' . $repository_id) ?>"><?php printf(__("Remove current site key (%s)", 'installer'), $site_key) ?></a>
106
- </center>
107
- <br />
108
-
109
- <?php include $this->plugin_path() . '/templates/downloads-list-compact.php'; ?>
110
-
111
-
112
-
113
- <?php endif; ?>
114
-
115
- <?php
116
- if( isset( $args[ 'name' ] ) ):
117
- $support_link = $this->get_support_tag_by_name($args['name'], $args['repository']); ?>
118
-
119
- <?php if($support_link): ?>
120
- <p><a href="<?php echo $support_link ?>" target="_blank"><?php printf(__('%s support on wpml.org', 'installer'), $args['name'] ) ?></a></p>
121
-
122
- <?php endif; ?>
123
- <?php
124
- // compatibility for installer 1.1
125
- elseif( isset( $args[ 'support_link' ] ) ): ?>
126
- <p><?php echo $args[ 'support_link' ]; ?></p>
127
- <?php endif; ?>
128
-
129
  </div>
1
+ <h3><?php echo $args['box_title'] ?></h3>
2
+
3
+ <?php
4
+ if(empty($args['repository']) || empty($args['package']) || empty($args['product'])){
5
+ echo __('Incorrect setup', 'installer');
6
+ return;
7
+ }
8
+
9
+ $product = false;
10
+ foreach($this->settings['repositories'][$repository_id]['data']['packages'] as $package_idx => $package){
11
+
12
+ //pre 1.3 backwardds compatibility
13
+ if(!isset($package['id'])){
14
+ $package['id'] = sanitize_title_with_dashes($package['name']);
15
+ }
16
+
17
+ if($package['id'] == $args['package']){
18
+ $product = $this->settings['repositories'][$repository_id]['data']['packages'][$package_idx]['products'][$args['product']];
19
+ break;
20
+ }
21
+ }
22
+
23
+
24
+ if(!$product){
25
+ echo __('Invalid product', 'installer');
26
+ return;
27
+ }
28
+
29
+ if(isset($this->settings['repositories'][$repository_id])){
30
+ if(isset($this->settings['repositories'][$repository_id]['subscription']['key'])){
31
+ $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
32
+ }else{
33
+ $site_key = false;
34
+ }
35
+ }else{
36
+ echo __('Unknown repository', 'installer');
37
+ return;
38
+ }
39
+
40
+ $subscription_type = $this->get_subscription_type_for_repository($repository_id);
41
+ $expired = false;
42
+
43
+ if($subscription_type != $product['subscription_type'] && !$this->have_superior_subscription($subscription_type, $product) && $site_key){
44
+ $subscription_no_match = sprintf(__(' Your current site key (%s) does not match the selected product (%s).', 'installer'), $site_key, $product['name']);
45
+ }
46
+
47
+ if(!isset($args['product_name'])) $args['product_name'] = $product['name'];
48
+
49
+ ?>
50
+
51
+ <div class="otgs_wp_installer_table otgs_wp_installer_table_compact">
52
+
53
+ <p><?php echo $args['box_description'] ?></p>
54
+
55
+
56
+ <?php if(!$this->repository_has_subscription($repository_id) || !empty($subscription_no_match)): ?>
57
+
58
+ <?php if(!empty($subscription_no_match)): ?>
59
+ <div class="installer-warn-box">
60
+ <?php echo $subscription_no_match; ?>
61
+ </div>
62
+ <br />
63
+ <?php endif; ?>
64
+
65
+ <a class="button-primary" href="<?php echo $this->append_parameters_to_buy_url($product['url'], $repository_id, $args) ?>"><?php printf(__('Buy %s', 'installer'), $args['product_name']) ?></a>
66
+
67
+ <div>
68
+ <br />
69
+ <?php printf(__('Already bought %s?', 'installer'), $args['product_name']) ?>
70
+ <a class="enter_site_key_js" href="#"><?php _e('Enter site key', 'installer') ?></a>&nbsp;&nbsp;
71
+
72
+ <form class="otgsi_site_key_form" method="post">
73
+ <input type="hidden" name="action" value="save_site_key" />
74
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('save_site_key_' . $repository_id) ?>" />
75
+ <input type="hidden" name="repository_id" value="<?php echo $repository_id ?>">
76
+ <input type="text" size="10" name="site_key_<?php echo $repository_id ?>" />
77
+ <input class="button-secondary" type="submit" value="<?php esc_attr_e('Add', 'installer') ?>" />
78
+ </form>
79
+ <div class="installer-error-box hidden" style="margin-top:10px;"></div>
80
+ </div>
81
+
82
+ <?php else: ?>
83
+
84
+ <?php if($this->repository_has_expired_subscription($repository_id)): $expired = true; ?>
85
+
86
+ <div><p class="installer-warn-box"><?php _e('Subscription is expired.', 'installer') ?></p></div>
87
+
88
+ <?php else: ?>
89
+
90
+ <?php if($this->show_subscription_renew_warning($repository_id, $subscription_type)): ?>
91
+
92
+ <ul class="installer-products-list">
93
+ <?php foreach($product['renewals'] as $renewal): ?>
94
+ <li>
95
+ <a href="<?php echo $this->append_parameters_to_buy_url($renewal['url'], $repository_id, $args) ?>"><?php printf(__('Renew %s', 'installer'), $args['product_name']) ?></a>
96
+ </li>
97
+ <?php endforeach; ?>
98
+ </ul>
99
+
100
+ <?php endif; ?>
101
+
102
+ <?php endif; ?>
103
+
104
+ <center>
105
+ <a class="remove_site_key_js" href="#" data-repository=<?php echo $repository_id ?> data-confirmation="<?php esc_attr_e('Are you sure you want to remove this site key?', 'installer') ?>" data-nonce="<?php echo wp_create_nonce('remove_site_key_' . $repository_id) ?>"><?php printf(__("Remove current site key (%s)", 'installer'), $site_key) ?></a>
106
+ </center>
107
+ <br />
108
+
109
+ <?php include $this->plugin_path() . '/templates/downloads-list-compact.php'; ?>
110
+
111
+
112
+
113
+ <?php endif; ?>
114
+
115
+ <?php
116
+ if( isset( $args[ 'name' ] ) ):
117
+ $support_link = $this->get_support_tag_by_name($args['name'], $args['repository']); ?>
118
+
119
+ <?php if($support_link): ?>
120
+ <p><a href="<?php echo $support_link ?>" target="_blank"><?php printf(__('%s support on wpml.org', 'installer'), $args['name'] ) ?></a></p>
121
+
122
+ <?php endif; ?>
123
+ <?php
124
+ // compatibility for installer 1.1
125
+ elseif( isset( $args[ 'support_link' ] ) ): ?>
126
+ <p><?php echo $args[ 'support_link' ]; ?></p>
127
+ <?php endif; ?>
128
+
129
  </div>
embedded/otgs/installer/templates/repository-listing.php CHANGED
@@ -1,179 +1,179 @@
1
- <?php if((!$this->repository_has_subscription($repository_id) && $match = $this->get_matching_cp($repository)) && $match['exp']): ?>
2
- <p class="alignright installer_highlight"><strong><?php printf('Price offers available until %s', date_i18n(get_option( 'date_format' ), $match['exp'])) ?></strong></p>
3
- <?php endif; ?>
4
-
5
- <h3 id="repository-<?php echo $repository_id ?>"><?php echo $repository['data']['name'] ?></h3>
6
- <?php
7
- $generic_product_name = $this->settings['repositories'][$repository_id]['data']['product-name'];
8
- ?>
9
- <table class="widefat otgs_wp_installer_table" id="installer_repo_<?php echo $repository_id ?>">
10
-
11
- <tr>
12
- <td>&nbsp;</td>
13
- <td class="otgsi_register_product_wrap" align="center" valign="top">
14
- <?php // IF NO SUBSCRIPTION ?>
15
- <?php if(!$this->repository_has_subscription($repository_id)): ?>
16
-
17
- <div style="text-align: right;">
18
- <span><?php _e('Already bought?', 'installer'); ?>&nbsp;</span>
19
- <a class="enter_site_key_js button-primary" href="#"><?php printf(__('Register %s', 'installer'), $generic_product_name); ?></a>&nbsp;&nbsp;
20
- <form class="otgsi_site_key_form" method="post">
21
- <input type="hidden" name="action" value="save_site_key" />
22
- <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('save_site_key_' . $repository_id) ?>" />
23
- <input type="hidden" name="repository_id" value="<?php echo $repository_id ?>">
24
- <?php _e('2. Enter your site key', 'installer'); ?>
25
- <input type="text" size="10" name="site_key_<?php echo $repository_id ?>" placeholder="<?php echo esc_attr('site key') ?>" />
26
- <input class="button-primary" type="submit" value="<?php esc_attr_e('OK', 'installer') ?>" />
27
- <input class="button-secondary cancel_site_key_js" type="button" value="<?php esc_attr_e('Cancel', 'installer') ?>" />
28
-
29
- <div class="alignleft" style="margin-top:6px;"><?php printf(__('1. Go to your %s%s account%s and add this site URL: %s', 'installer'),
30
- '<a href="' . $this->settings['repositories'][$repository_id]['data']['site_keys_management_url'] . '?add='.urlencode($this->get_installer_site_url( $repository_id )).'">',
31
- $generic_product_name, '</a>', $this->get_installer_site_url( $repository_id )); ?></div>
32
- </form>
33
-
34
-
35
- </div>
36
-
37
- <?php
38
- $site_key = false;
39
-
40
- // IF SUBSCRIPTION
41
- else:
42
-
43
- $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
44
- $subscription_type = $this->get_subscription_type_for_repository($repository_id);
45
-
46
- $upgrade_options = $this->get_upgrade_options($repository_id);
47
- $expired = false;
48
-
49
- ?>
50
-
51
- <?php if($this->repository_has_expired_subscription($repository_id)): $expired = true; ?>
52
- <div>
53
- <p class="installer-warn-box">
54
- <?php _e('Subscription expired. You need to either purchase a new subscription or upgrade if available.', 'installer') ?>
55
- <span class="alignright">
56
- <a class="update_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-nonce="<?php echo wp_create_nonce('update_site_key_' . $repository_id) ?>">
57
- <?php _e('Revalidate subscription', 'installer'); ?>
58
- </a>
59
- </span>
60
- <br />
61
- <span class="details"><?php _e("If you have already purchased or renewed your subscription and you can still see this message, please revalidate your subscription", 'installer') ?></span>
62
- </p>
63
- </div>
64
- <?php else: ?>
65
- <?php $this->show_subscription_renew_warning($repository_id, $subscription_type); ?>
66
- <?php endif; ?>
67
-
68
- <div class="alignright">
69
- <a class="remove_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-confirmation="<?php esc_attr_e('Are you sure you want to unregister?', 'installer') ?>" data-nonce="<?php echo wp_create_nonce('remove_site_key_' . $repository_id) ?>"><?php printf(__("Unregister %s from this site", 'installer'), $generic_product_name) ?></a>&nbsp;
70
- <a class="update_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-nonce="<?php echo wp_create_nonce('update_site_key_' . $repository_id) ?>">
71
- <?php _e('Check for updates', 'installer'); ?>
72
- </a>
73
- </div>
74
-
75
- <?php if(empty($expired)): ?>
76
- <div class="alignleft">
77
- <?php if($expires = $this->settings['repositories'][$repository_id]['subscription']['data']->expires): ?>
78
- <?php printf(__('%s is registered on this site. You will receive automatic updates until %s', 'installer'), $generic_product_name, date_i18n('F j, Y', strtotime($expires))); ?>
79
- <?php else: ?>
80
- <?php printf(__('%s is registered on this site. Your Lifetime account gives you updates for life.', 'installer'), $generic_product_name); ?>
81
- <?php endif; ?>
82
- </div>
83
- <?php endif; //if(empty($expired)) ?>
84
-
85
- <?php endif; // if(!repository_has_subscription) ?>
86
- <br clear="all" />
87
- <div class="installer-error-box hidden"></div>
88
-
89
- </td>
90
- </tr>
91
-
92
- <?php
93
-
94
- $subscription_type = isset($subscription_type) ? $subscription_type : null;
95
- $expired = isset($expired) ? $expired : null;
96
- $upgrade_options = isset($upgrade_options) ? $upgrade_options : null;
97
- $packages = $this->_render_product_packages($repository['data']['packages'], $subscription_type, $expired, $upgrade_options, $repository_id);
98
- if(empty($subscription_type) || $expired){
99
- $subpackages_expandable = true;
100
- }else{
101
- $subpackages_expandable = false;
102
- }
103
-
104
- ?>
105
-
106
- <?php foreach($packages as $package): ?>
107
- <tr id="repository-<?php echo $repository_id ?>_<?php echo $package['id'] ?>">
108
- <td><img width="140" height="140" src="<?php echo $package['image_url'] ?>" /></td>
109
- <td>
110
- <p><strong><?php echo $package['name'] ?></strong></p>
111
- <p><?php echo $package['description'] ?></p>
112
-
113
- <?php if($package['products']): ?>
114
- <?php foreach($package['products'] as $product): ?>
115
- <ul class="installer-products-list" style="display:inline">
116
- <li>
117
- <a class="button-secondary" href="<?php echo $product['url'] ?>"><?php echo $product['label'] ?></a>
118
- </li>
119
- </ul>
120
- <?php endforeach; ?>
121
- <?php endif; ?>
122
-
123
- <?php if($package['downloads']): ?>
124
- <?php include $this->plugin_path() . '/templates/downloads-list.php'; ?>
125
- <?php endif; ?>
126
-
127
- <?php if(!empty($package['sub-packages'])): ?>
128
-
129
- <?php $subpackages = $this->_render_product_packages($package['sub-packages'], $subscription_type, $expired, $upgrade_options, $repository_id); ?>
130
-
131
- <?php if($subpackages): ?>
132
-
133
- <?php if($subpackages_expandable): ?>
134
- <h5><a class="installer_expand_button" href="#" title="<?php esc_attr_e('Click to see individual components options.', 'installer') ?>"><?php _e('Individual components', 'installer') ?></a></h5>
135
- <?php endif; ?>
136
-
137
- <table class="otgs_wp_installer_subtable" style="<?php if($subpackages_expandable) echo 'display:none' ?>">
138
- <?php foreach($subpackages as $package): ?>
139
- <tr id="repository-<?php echo $repository_id ?>_<?php echo $package['id'] ?>">
140
- <td><img width="70" height="70" src="<?php echo $package['image_url'] ?>" /></td>
141
- <td>
142
- <p><strong><?php echo $package['name'] ?></strong></p>
143
- <p><?php echo $package['description'] ?></p>
144
-
145
- <?php if($package['products']): ?>
146
- <?php foreach($package['products'] as $product): ?>
147
- <ul class="installer-products-list" style="display:inline">
148
- <li>
149
- <a class="button-secondary" href="<?php echo $product['url'] ?>"><?php echo $product['label'] ?></a>
150
- </li>
151
- </ul>
152
- <?php endforeach; ?>
153
- <?php endif; ?>
154
-
155
- <?php if($package['downloads']): ?>
156
- <?php include $this->plugin_path() . '/templates/downloads-list.php'; ?>
157
- <?php endif; ?>
158
- </td>
159
- </tr>
160
- <?php endforeach; ?>
161
- </table>
162
- <?php endif; ?>
163
-
164
- <?php endif; ?>
165
-
166
-
167
- </td>
168
- </tr>
169
-
170
- <?php endforeach; ?>
171
-
172
- </table>
173
-
174
-
175
- <p><i><?php printf(__('This page lets you install plugins and update existing plugins. To remove any of these plugins, go to the %splugins%s page and if you have the permission to remove plugins you should be able to do this.', 'installer'), '<a href="' . admin_url('plugins.php') . '">' , '</a>'); ?></i></p>
176
-
177
-
178
-
179
  <br />
1
+ <?php if((!$this->repository_has_subscription($repository_id) && $match = $this->get_matching_cp($repository)) && $match['exp']): ?>
2
+ <p class="alignright installer_highlight"><strong><?php printf('Price offers available until %s', date_i18n(get_option( 'date_format' ), $match['exp'])) ?></strong></p>
3
+ <?php endif; ?>
4
+
5
+ <h3 id="repository-<?php echo $repository_id ?>"><?php echo $repository['data']['name'] ?></h3>
6
+ <?php
7
+ $generic_product_name = $this->settings['repositories'][$repository_id]['data']['product-name'];
8
+ ?>
9
+ <table class="widefat otgs_wp_installer_table" id="installer_repo_<?php echo $repository_id ?>">
10
+
11
+ <tr>
12
+ <td>&nbsp;</td>
13
+ <td class="otgsi_register_product_wrap" align="center" valign="top">
14
+ <?php // IF NO SUBSCRIPTION ?>
15
+ <?php if(!$this->repository_has_subscription($repository_id)): ?>
16
+
17
+ <div style="text-align: right;">
18
+ <span><?php _e('Already bought?', 'installer'); ?>&nbsp;</span>
19
+ <a class="enter_site_key_js button-primary" href="#"><?php printf(__('Register %s', 'installer'), $generic_product_name); ?></a>&nbsp;&nbsp;
20
+ <form class="otgsi_site_key_form" method="post">
21
+ <input type="hidden" name="action" value="save_site_key" />
22
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('save_site_key_' . $repository_id) ?>" />
23
+ <input type="hidden" name="repository_id" value="<?php echo $repository_id ?>">
24
+ <?php _e('2. Enter your site key', 'installer'); ?>
25
+ <input type="text" size="10" name="site_key_<?php echo $repository_id ?>" placeholder="<?php echo esc_attr('site key') ?>" />
26
+ <input class="button-primary" type="submit" value="<?php esc_attr_e('OK', 'installer') ?>" />
27
+ <input class="button-secondary cancel_site_key_js" type="button" value="<?php esc_attr_e('Cancel', 'installer') ?>" />
28
+
29
+ <div class="alignleft" style="margin-top:6px;"><?php printf(__('1. Go to your %s%s account%s and add this site URL: %s', 'installer'),
30
+ '<a href="' . $this->settings['repositories'][$repository_id]['data']['site_keys_management_url'] . '?add='.urlencode($this->get_installer_site_url( $repository_id )).'">',
31
+ $generic_product_name, '</a>', $this->get_installer_site_url( $repository_id )); ?></div>
32
+ </form>
33
+
34
+
35
+ </div>
36
+
37
+ <?php
38
+ $site_key = false;
39
+
40
+ // IF SUBSCRIPTION
41
+ else:
42
+
43
+ $site_key = $this->settings['repositories'][$repository_id]['subscription']['key'];
44
+ $subscription_type = $this->get_subscription_type_for_repository($repository_id);
45
+
46
+ $upgrade_options = $this->get_upgrade_options($repository_id);
47
+ $expired = false;
48
+
49
+ ?>
50
+
51
+ <?php if($this->repository_has_expired_subscription($repository_id)): $expired = true; ?>
52
+ <div>
53
+ <p class="installer-warn-box">
54
+ <?php _e('Subscription expired. You need to either purchase a new subscription or upgrade if available.', 'installer') ?>
55
+ <span class="alignright">
56
+ <a class="update_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-nonce="<?php echo wp_create_nonce('update_site_key_' . $repository_id) ?>">
57
+ <?php _e('Revalidate subscription', 'installer'); ?>
58
+ </a>
59
+ </span>
60
+ <br />
61
+ <span class="details"><?php _e("If you have already purchased or renewed your subscription and you can still see this message, please revalidate your subscription", 'installer') ?></span>
62
+ </p>
63
+ </div>
64
+ <?php else: ?>
65
+ <?php $this->show_subscription_renew_warning($repository_id, $subscription_type); ?>
66
+ <?php endif; ?>
67
+
68
+ <div class="alignright">
69
+ <a class="remove_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-confirmation="<?php esc_attr_e('Are you sure you want to unregister?', 'installer') ?>" data-nonce="<?php echo wp_create_nonce('remove_site_key_' . $repository_id) ?>"><?php printf(__("Unregister %s from this site", 'installer'), $generic_product_name) ?></a>&nbsp;
70
+ <a class="update_site_key_js button-secondary" href="#" data-repository=<?php echo $repository_id ?> data-nonce="<?php echo wp_create_nonce('update_site_key_' . $repository_id) ?>">
71
+ <?php _e('Check for updates', 'installer'); ?>
72
+ </a>
73
+ </div>
74
+
75
+ <?php if(empty($expired)): ?>
76
+ <div class="alignleft">
77
+ <?php if($expires = $this->settings['repositories'][$repository_id]['subscription']['data']->expires): ?>
78
+ <?php printf(__('%s is registered on this site. You will receive automatic updates until %s', 'installer'), $generic_product_name, date_i18n('F j, Y', strtotime($expires))); ?>
79
+ <?php else: ?>
80
+ <?php printf(__('%s is registered on this site. Your Lifetime account gives you updates for life.', 'installer'), $generic_product_name); ?>
81
+ <?php endif; ?>
82
+ </div>
83
+ <?php endif; //if(empty($expired)) ?>
84
+
85
+ <?php endif; // if(!repository_has_subscription) ?>
86
+ <br clear="all" />
87
+ <div class="installer-error-box hidden"></div>
88
+
89
+ </td>
90
+ </tr>
91
+
92
+ <?php
93
+
94
+ $subscription_type = isset($subscription_type) ? $subscription_type : null;
95
+ $expired = isset($expired) ? $expired : null;
96
+ $upgrade_options = isset($upgrade_options) ? $upgrade_options : null;
97
+ $packages = $this->_render_product_packages($repository['data']['packages'], $subscription_type, $expired, $upgrade_options, $repository_id);
98
+ if(empty($subscription_type) || $expired){
99
+ $subpackages_expandable = true;
100
+ }else{
101
+ $subpackages_expandable = false;
102
+ }
103
+
104
+ ?>
105
+
106
+ <?php foreach($packages as $package): ?>
107
+ <tr id="repository-<?php echo $repository_id ?>_<?php echo $package['id'] ?>">
108
+ <td><img width="140" height="140" src="<?php echo $package['image_url'] ?>" /></td>
109
+ <td>
110
+ <p><strong><?php echo $package['name'] ?></strong></p>
111
+ <p><?php echo $package['description'] ?></p>
112
+
113
+ <?php if($package['products']): ?>
114
+ <?php foreach($package['products'] as $product): ?>
115
+ <ul class="installer-products-list" style="display:inline">
116
+ <li>
117
+ <a class="button-secondary" href="<?php echo $product['url'] ?>"><?php echo $product['label'] ?></a>
118
+ </li>
119
+ </ul>
120
+ <?php endforeach; ?>
121
+ <?php endif; ?>
122
+
123
+ <?php if($package['downloads']): ?>
124
+ <?php include $this->plugin_path() . '/templates/downloads-list.php'; ?>
125
+ <?php endif; ?>
126
+
127
+ <?php if(!empty($package['sub-packages'])): ?>
128
+
129
+ <?php $subpackages = $this->_render_product_packages($package['sub-packages'], $subscription_type, $expired, $upgrade_options, $repository_id); ?>
130
+
131
+ <?php if($subpackages): ?>
132
+
133
+ <?php if($subpackages_expandable): ?>
134
+ <h5><a class="installer_expand_button" href="#" title="<?php esc_attr_e('Click to see individual components options.', 'installer') ?>"><?php _e('Individual components', 'installer') ?></a></h5>
135
+ <?php endif; ?>
136
+
137
+ <table class="otgs_wp_installer_subtable" style="<?php if($subpackages_expandable) echo 'display:none' ?>">
138
+ <?php foreach($subpackages as $package): ?>
139
+ <tr id="repository-<?php echo $repository_id ?>_<?php echo $package['id'] ?>">
140
+ <td><img width="70" height="70" src="<?php echo $package['image_url'] ?>" /></td>
141
+ <td>
142
+ <p><strong><?php echo $package['name'] ?></strong></p>
143
+ <p><?php echo $package['description'] ?></p>
144
+
145
+ <?php if($package['products']): ?>
146
+ <?php foreach($package['products'] as $product): ?>
147
+ <ul class="installer-products-list" style="display:inline">
148
+ <li>
149
+ <a class="button-secondary" href="<?php echo $product['url'] ?>"><?php echo $product['label'] ?></a>
150
+ </li>
151
+ </ul>
152
+ <?php endforeach; ?>
153
+ <?php endif; ?>
154
+
155
+ <?php if($package['downloads']): ?>
156
+ <?php include $this->plugin_path() . '/templates/downloads-list.php'; ?>
157
+ <?php endif; ?>
158
+ </td>
159
+ </tr>
160
+ <?php endforeach; ?>
161
+ </table>
162
+ <?php endif; ?>
163
+
164
+ <?php endif; ?>
165
+
166
+
167
+ </td>
168
+ </tr>
169
+
170
+ <?php endforeach; ?>
171
+
172
+ </table>
173
+
174
+
175
+ <p><i><?php printf(__('This page lets you install plugins and update existing plugins. To remove any of these plugins, go to the %splugins%s page and if you have the permission to remove plugins you should be able to do this.', 'installer'), '<a href="' . admin_url('plugins.php') . '">' , '</a>'); ?></i></p>
176
+
177
+
178
+
179
  <br />
embedded/xrstf/composer-php52/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2013 Christoph Mewes
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
embedded/xrstf/composer-php52/README.md ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ PHP 5.2 Autoloading for Composer
2
+ ================================
3
+
4
+ This package provides an easy way to get a PHP 5.2 compatible autoloader out of Composer. The generated autoloader is fully compatible to the original and is written into separate files, each ending with `_52.php`.
5
+
6
+ Legacy
7
+ ------
8
+
9
+ Please do not use this, if you can avoid it. It's a horrible hack, often breaks and is extremely tied to Composer's interna. This package was originally developed in 2012, when PHP 5.2 was much more common on cheap webhosts.
10
+
11
+ In 2016, this package has been moved from Bitbucket to a Github organization, because the original developer could no longer reliably maintain it. This is the reason for this legacy package name ``xrstf/...``.
12
+
13
+ Usage
14
+ -----
15
+
16
+ In your project's `composer.json`, add the following lines:
17
+
18
+ ```json
19
+ {
20
+ "require": {
21
+ "xrstf/composer-php52": "1.*"
22
+ },
23
+ "scripts": {
24
+ "post-install-cmd": [
25
+ "xrstf\\Composer52\\Generator::onPostInstallCmd"
26
+ ],
27
+ "post-update-cmd": [
28
+ "xrstf\\Composer52\\Generator::onPostInstallCmd"
29
+ ],
30
+ "post-autoload-dump": [
31
+ "xrstf\\Composer52\\Generator::onPostInstallCmd"
32
+ ]
33
+ }
34
+ }
35
+ ```
36
+
37
+ After the next update/install, you will have a `vendor/autoload_52.php` file, that you can simply include and use in PHP 5.2 projects.
embedded/xrstf/composer-php52/lib/xrstf/Composer52/AutoloadGenerator.php ADDED
@@ -0,0 +1,346 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright (c) 2013, Christoph Mewes, http://www.xrstf.de
4
+ *
5
+ * This file is released under the terms of the MIT license. You can find the
6
+ * complete text in the attached LICENSE file or online at:
7
+ *
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ *
10
+ * --------------------------------------------------------------------------
11
+ *
12
+ * 99% of this is copied as-is from the original Composer source code and is
13
+ * released under MIT license as well. Copyright goes to:
14
+ *
15
+ * - Igor Wiedler <igor@wiedler.ch>
16
+ * - Jordi Boggiano <j.boggiano@seld.be>
17
+ */
18
+
19
+ namespace xrstf\Composer52;
20
+
21
+ use Composer\Autoload\AutoloadGenerator as BaseGenerator;
22
+ use Composer\Autoload\ClassMapGenerator;
23
+ use Composer\Config;
24
+ use Composer\Installer\InstallationManager;
25
+ use Composer\Package\AliasPackage;
26
+ use Composer\Package\PackageInterface;
27
+ use Composer\Repository\InstalledRepositoryInterface;
28
+ use Composer\Util\Filesystem;
29
+
30
+ class AutoloadGenerator extends BaseGenerator {
31
+
32
+ /**
33
+ * @var bool
34
+ */
35
+ private $classMapAuthoritative = false;
36
+
37
+ public function __construct() {
38
+ // do nothing (but keep this constructor so we can build an instance without the need for an event dispatcher)
39
+ }
40
+
41
+ /**
42
+ * Whether or not generated autoloader considers the class map
43
+ * authoritative.
44
+ *
45
+ * @param bool $classMapAuthoritative
46
+ */
47
+ public function setClassMapAuthoritative($classMapAuthoritative)
48
+ {
49
+ $this->classMapAuthoritative = (boolean) $classMapAuthoritative;
50
+ }
51
+
52
+ public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '') {
53
+ if ($this->classMapAuthoritative) {
54
+ // Force scanPsr0Packages when classmap is authoritative
55
+ $scanPsr0Packages = true;
56
+ }
57
+
58
+ $filesystem = new Filesystem();
59
+ $filesystem->ensureDirectoryExists($config->get('vendor-dir'));
60
+
61
+ $cwd = getcwd();
62
+ $basePath = $filesystem->normalizePath($cwd);
63
+ $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir')));
64
+ $targetDir = $vendorPath.'/'.$targetDir;
65
+ $filesystem->ensureDirectoryExists($targetDir);
66
+
67
+ $useGlobalIncludePath = (bool) $config->get('use-include-path');
68
+ $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true';
69
+ $classMapAuthoritative = $config->get('classmap-authoritative');
70
+
71
+ $vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
72
+ $vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true);
73
+
74
+ $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true);
75
+ $appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode);
76
+
77
+ // add 5.2 compat
78
+ $vendorPathCode = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode);
79
+ $vendorPathToTargetDirCode = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathToTargetDirCode);
80
+
81
+ $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages());
82
+ $autoloads = $this->parseAutoloads($packageMap, $mainPackage);
83
+
84
+ // add custom psr-0 autoloading if the root package has a target dir
85
+ $targetDirLoader = null;
86
+ $mainAutoload = $mainPackage->getAutoload();
87
+ if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) {
88
+ $levels = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir())));
89
+ $prefixes = implode(', ', array_map(function ($prefix) {
90
+ return var_export($prefix, true);
91
+ }, array_keys($mainAutoload['psr-0'])));
92
+
93
+ $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true);
94
+
95
+ $targetDirLoader = <<<EOF
96
+
97
+ public static function autoload(\$class) {
98
+ \$dir = $baseDirFromTargetDirCode.'/';
99
+ \$prefixes = array($prefixes);
100
+
101
+ foreach (\$prefixes as \$prefix) {
102
+ if (0 !== strpos(\$class, \$prefix)) {
103
+ continue;
104
+ }
105
+
106
+ \$path = explode(DIRECTORY_SEPARATOR, self::getClassPath(\$class));
107
+ \$path = \$dir.implode('/', array_slice(\$path, $levels));
108
+
109
+ if (!\$path = self::resolveIncludePath(\$path)) {
110
+ return false;
111
+ }
112
+
113
+ require \$path;
114
+ return true;
115
+ }
116
+ }
117
+
118
+ EOF;
119
+ }
120
+
121
+ $filesCode = "";
122
+ $autoloads['files'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['files']));
123
+ foreach ($autoloads['files'] as $functionFile) {
124
+ // don't include file if it is using PHP 5.3+ syntax
125
+ // https://bitbucket.org/xrstf/composer-php52/issue/4
126
+ if ($this->isPHP53($functionFile)) {
127
+ $filesCode .= '// require '.$this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile)."; // disabled because of PHP 5.3 syntax\n";
128
+ }
129
+ else {
130
+ $filesCode .= ' require '.$this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile).";\n";
131
+ }
132
+ }
133
+
134
+ if (!$suffix) {
135
+ $suffix = md5(uniqid('', true));
136
+ }
137
+
138
+ $includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode);
139
+
140
+ file_put_contents($vendorPath.'/autoload_52.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
141
+ file_put_contents($targetDir.'/autoload_real_52.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, $filesCode, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader));
142
+
143
+ // use stream_copy_to_stream instead of copy
144
+ // to work around https://bugs.php.net/bug.php?id=64634
145
+ $sourceLoader = fopen(__DIR__.'/ClassLoader.php', 'r');
146
+ $targetLoader = fopen($targetDir.'/ClassLoader52.php', 'w+');
147
+ stream_copy_to_stream($sourceLoader, $targetLoader);
148
+ fclose($sourceLoader);
149
+ fclose($targetLoader);
150
+ unset($sourceLoader, $targetLoader);
151
+ }
152
+
153
+ protected function isPHP53($file) {
154
+ $tokens = token_get_all(file_get_contents($file));
155
+ $php53 = array(T_DIR, T_GOTO, T_NAMESPACE, T_NS_C, T_NS_SEPARATOR, T_USE);
156
+
157
+ // PHP 5.4+
158
+ if (defined('T_TRAIT')) {
159
+ $php53[] = T_TRAIT;
160
+ $php53[] = T_TRAIT_C;
161
+ $php53[] = T_TRAIT_C;
162
+ }
163
+
164
+ // PHP 5.5+
165
+ if (defined('T_FINALLY')) {
166
+ $php53[] = T_FINALLY;
167
+ $php53[] = T_YIELD;
168
+ }
169
+
170
+ foreach ($tokens as $token) {
171
+ if (is_array($token) && in_array($token[0], $php53)) {
172
+ return true;
173
+ }
174
+ }
175
+
176
+ return false;
177
+ }
178
+
179
+ protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode) {
180
+ $includePaths = array();
181
+
182
+ foreach ($packageMap as $item) {
183
+ list($package, $installPath) = $item;
184
+
185
+ if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) {
186
+ $installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
187
+ }
188
+
189
+ foreach ($package->getIncludePaths() as $includePath) {
190
+ $includePath = trim($includePath, '/');
191
+ $includePaths[] = empty($installPath) ? $includePath : $installPath.'/'.$includePath;
192
+ }
193
+ }
194
+
195
+ if (!$includePaths) {
196
+ return;
197
+ }
198
+
199
+ $includePathsFile = <<<EOF
200
+ <?php
201
+
202
+ // include_paths_52.php generated by xrstf/composer-php52
203
+
204
+ \$vendorDir = $vendorPathCode;
205
+ \$baseDir = $appBaseDirCode;
206
+
207
+ return array(
208
+
209
+ EOF;
210
+
211
+ foreach ($includePaths as $path) {
212
+ $includePathsFile .= "\t" . $this->getPathCode($filesystem, $basePath, $vendorPath, $path) . ",\n";
213
+ }
214
+
215
+ return $includePathsFile . ");\n";
216
+ }
217
+
218
+ protected function getAutoloadFile($vendorPathToTargetDirCode, $suffix) {
219
+ return <<<AUTOLOAD
220
+ <?php
221
+
222
+ // autoload_52.php generated by xrstf/composer-php52
223
+
224
+ require_once $vendorPathToTargetDirCode.'/autoload_real_52.php';
225
+
226
+ return ComposerAutoloaderInit$suffix::getLoader();
227
+
228
+ AUTOLOAD;
229
+ }
230
+
231
+ protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $filesCode, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion = 70000) {
232
+ // TODO the class ComposerAutoloaderInit should be revert to a closure
233
+ // when APC has been fixed:
234
+ // - https://github.com/composer/composer/issues/959
235
+ // - https://bugs.php.net/bug.php?id=52144
236
+ // - https://bugs.php.net/bug.php?id=61576
237
+ // - https://bugs.php.net/bug.php?id=59298
238
+
239
+ if ($filesCode) {
240
+ $filesCode = "\n\n".rtrim($filesCode);
241
+ }
242
+
243
+ $file = <<<HEADER
244
+ <?php
245
+
246
+ // autoload_real_52.php generated by xrstf/composer-php52
247
+
248
+ class ComposerAutoloaderInit$suffix {
249
+ private static \$loader;
250
+
251
+ public static function loadClassLoader(\$class) {
252
+ if ('xrstf_Composer52_ClassLoader' === \$class) {
253
+ require dirname(__FILE__).'/ClassLoader52.php';
254
+ }
255
+ }
256
+
257
+ /**
258
+ * @return xrstf_Composer52_ClassLoader
259
+ */
260
+ public static function getLoader() {
261
+ if (null !== self::\$loader) {
262
+ return self::\$loader;
263
+ }
264
+
265
+ spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'), true /*, true */);
266
+ self::\$loader = \$loader = new xrstf_Composer52_ClassLoader();
267
+ spl_autoload_unregister(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'));
268
+
269
+ \$vendorDir = $vendorPathCode;
270
+ \$baseDir = $appBaseDirCode;
271
+ \$dir = dirname(__FILE__);
272
+
273
+
274
+ HEADER;
275
+
276
+ if ($useIncludePath) {
277
+ $file .= <<<'INCLUDE_PATH'
278
+ $includePaths = require $dir.'/include_paths.php';
279
+ array_push($includePaths, get_include_path());
280
+ set_include_path(implode(PATH_SEPARATOR, $includePaths));
281
+
282
+
283
+ INCLUDE_PATH;
284
+ }
285
+
286
+ $file .= <<<'PSR0'
287
+ $map = require $dir.'/autoload_namespaces.php';
288
+ foreach ($map as $namespace => $path) {
289
+ $loader->add($namespace, $path);
290
+ }
291
+
292
+
293
+ PSR0;
294
+
295
+ if ($useClassMap) {
296
+ $file .= <<<'CLASSMAP'
297
+ $classMap = require $dir.'/autoload_classmap.php';
298
+ if ($classMap) {
299
+ $loader->addClassMap($classMap);
300
+ }
301
+
302
+
303
+ CLASSMAP;
304
+ }
305
+
306
+ if ($this->classMapAuthoritative) {
307
+ $file .= <<<'CLASSMAPAUTHORITATIVE'
308
+ $loader->setClassMapAuthoritative(true);
309
+
310
+ CLASSMAPAUTHORITATIVE;
311
+ }
312
+
313
+ if ($useGlobalIncludePath) {
314
+ $file .= <<<'INCLUDEPATH'
315
+ $loader->setUseIncludePath(true);
316
+
317
+
318
+ INCLUDEPATH;
319
+ }
320
+
321
+ if ($targetDirLoader) {
322
+ $file .= <<<REGISTER_AUTOLOAD
323
+ spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'autoload'), true);
324
+
325
+
326
+ REGISTER_AUTOLOAD;
327
+
328
+ }
329
+
330
+ $file .= <<<METHOD_FOOTER
331
+ \$loader->register($prependAutoloader);{$filesCode}
332
+
333
+ return \$loader;
334
+ }
335
+
336
+ METHOD_FOOTER;
337
+
338
+ $file .= $targetDirLoader;
339
+
340
+ return $file . <<<FOOTER
341
+ }
342
+
343
+ FOOTER;
344
+
345
+ }
346
+ }
embedded/xrstf/composer-php52/lib/xrstf/Composer52/ClassLoader.php ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright (c) 2013, Christoph Mewes, http://www.xrstf.de
4
+ *
5
+ * This file is released under the terms of the MIT license. You can find the
6
+ * complete text in the attached LICENSE file or online at:
7
+ *
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ *
10
+ * --------------------------------------------------------------------------
11
+ *
12
+ * 99% of this is copied as-is from the original Composer source code and is
13
+ * released under MIT license as well. Copyright goes to:
14
+ *
15
+ * - Fabien Potencier <fabien@symfony.com>
16
+ * - Jordi Boggiano <j.boggiano@seld.be>
17
+ */
18
+
19
+ class xrstf_Composer52_ClassLoader {
20
+ private $prefixes = array();
21
+ private $fallbackDirs = array();
22
+ private $useIncludePath = false;
23
+ private $classMap = array();
24
+ private $classMapAuthoratative = false;
25
+ private $allowUnderscore = false;
26
+
27
+ /**
28
+ * @param boolean $flag true to allow class names with a leading underscore, false to disable
29
+ */
30
+ public function setAllowUnderscore($flag) {
31
+ $this->allowUnderscore = (boolean) $flag;
32
+ }
33
+
34
+ /**
35
+ * @return array
36
+ */
37
+ public function getPrefixes() {
38
+ return $this->prefixes;
39
+ }
40
+
41
+ /**
42
+ * Turns off searching the prefix and fallback directories for classes
43
+ * that have not been registered with the class map.
44
+ *
45
+ * @param bool $classMapAuthoratative
46
+ */
47
+ public function setClassMapAuthoritative($classMapAuthoratative) {
48
+ $this->classMapAuthoratative = $classMapAuthoratative;
49
+ }
50
+
51
+ /**
52
+ * Should class lookup fail if not found in the current class map?
53
+ *
54
+ * @return bool
55
+ */
56
+ public function getClassMapAuthoratative() {
57
+ return $this->classMapAuthoratative;
58
+ }
59
+
60
+ /**
61
+ * @return array
62
+ */
63
+ public function getFallbackDirs() {
64
+ return $this->fallbackDirs;
65
+ }
66
+
67
+ /**
68
+ * @return array
69
+ */
70
+ public function getClassMap() {
71
+ return $this->classMap;
72
+ }
73
+
74
+ /**
75
+ * @param array $classMap class to filename map
76
+ */
77
+ public function addClassMap(array $classMap) {
78
+ if ($this->classMap) {
79
+ $this->classMap = array_merge($this->classMap, $classMap);
80
+ }
81
+ else {
82
+ $this->classMap = $classMap;
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Registers a set of classes, merging with any others previously set.
88
+ *
89
+ * @param string $prefix the classes prefix
90
+ * @param array|string $paths the location(s) of the classes
91
+ * @param bool $prepend prepend the location(s)
92
+ */
93
+ public function add($prefix, $paths, $prepend = false) {
94
+ if (!$prefix) {
95
+ if ($prepend) {
96
+ $this->fallbackDirs = array_merge(
97
+ (array) $paths,
98
+ $this->fallbackDirs
99
+ );
100
+ }
101
+ else {
102
+ $this->fallbackDirs = array_merge(
103
+ $this->fallbackDirs,
104
+ (array) $paths
105
+ );
106
+ }
107
+
108
+ return;
109
+ }
110
+
111
+ if (!isset($this->prefixes[$prefix])) {
112
+ $this->prefixes[$prefix] = (array) $paths;
113
+ return;
114
+ }
115
+
116
+ if ($prepend) {
117
+ $this->prefixes[$prefix] = array_merge(
118
+ (array) $paths,
119
+ $this->prefixes[$prefix]
120
+ );
121
+ }
122
+ else {
123
+ $this->prefixes[$prefix] = array_merge(
124
+ $this->prefixes[$prefix],
125
+ (array) $paths
126
+ );
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Registers a set of classes, replacing any others previously set.
132
+ *
133
+ * @param string $prefix the classes prefix
134
+ * @param array|string $paths the location(s) of the classes
135
+ */
136
+ public function set($prefix, $paths) {
137
+ if (!$prefix) {
138
+ $this->fallbackDirs = (array) $paths;
139
+ return;
140
+ }
141
+
142
+ $this->prefixes[$prefix] = (array) $paths;
143
+ }
144
+
145
+ /**
146
+ * Turns on searching the include path for class files.
147
+ *
148
+ * @param bool $useIncludePath
149
+ */
150
+ public function setUseIncludePath($useIncludePath) {
151
+ $this->useIncludePath = $useIncludePath;
152
+ }
153
+
154
+ /**
155
+ * Can be used to check if the autoloader uses the include path to check
156
+ * for classes.
157
+ *
158
+ * @return bool
159
+ */
160
+ public function getUseIncludePath() {
161
+ return $this->useIncludePath;
162
+ }
163
+
164
+ /**
165
+ * Registers this instance as an autoloader.
166
+ */
167
+ public function register() {
168
+ spl_autoload_register(array($this, 'loadClass'), true);
169
+ }
170
+
171
+ /**
172
+ * Unregisters this instance as an autoloader.
173
+ */
174
+ public function unregister() {
175
+ spl_autoload_unregister(array($this, 'loadClass'));
176
+ }
177
+
178
+ /**
179
+ * Loads the given class or interface.
180
+ *
181
+ * @param string $class the name of the class
182
+ * @return bool|null true, if loaded
183
+ */
184
+ public function loadClass($class) {
185
+ if ($file = $this->findFile($class)) {
186
+ include $file;
187
+ return true;
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Finds the path to the file where the class is defined.
193
+ *
194
+ * @param string $class the name of the class
195
+ * @return string|null the path, if found
196
+ */
197
+ public function findFile($class) {
198
+ if ('\\' === $class[0]) {
199
+ $class = substr($class, 1);
200
+ }
201
+
202
+ if (isset($this->classMap[$class])) {
203
+ return $this->classMap[$class];
204
+ }
205
+ elseif ($this->classMapAuthoratative) {
206
+ return false;
207
+ }
208
+
209
+ $classPath = $this->getClassPath($class);
210
+
211
+ foreach ($this->prefixes as $prefix => $dirs) {
212
+ if (0 === strpos($class, $prefix)) {
213
+ foreach ($dirs as $dir) {
214
+ if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) {
215
+ return $dir.DIRECTORY_SEPARATOR.$classPath;
216
+ }
217
+ }
218
+ }
219
+ }
220
+
221
+ foreach ($this->fallbackDirs as $dir) {
222
+ if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) {
223
+ return $dir.DIRECTORY_SEPARATOR.$classPath;
224
+ }
225
+ }
226
+
227
+ if ($this->useIncludePath && $file = self::resolveIncludePath($classPath)) {
228
+ return $file;
229
+ }
230
+
231
+ return $this->classMap[$class] = false;
232
+ }
233
+
234
+ private function getClassPath($class) {
235
+ if (false !== $pos = strrpos($class, '\\')) {
236
+ // namespaced class name
237
+ $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)).DIRECTORY_SEPARATOR;
238
+ $className = substr($class, $pos + 1);
239
+ }
240
+ else {
241
+ // PEAR-like class name
242
+ $classPath = null;
243
+ $className = $class;
244
+ }
245
+
246
+ $className = str_replace('_', DIRECTORY_SEPARATOR, $className);
247
+
248
+ // restore the prefix
249
+ if ($this->allowUnderscore && DIRECTORY_SEPARATOR === $className[0]) {
250
+ $className[0] = '_';
251
+ }
252
+
253
+ $classPath .= $className.'.php';
254
+
255
+ return $classPath;
256
+ }
257
+
258
+ public static function resolveIncludePath($classPath) {
259
+ $paths = explode(PATH_SEPARATOR, get_include_path());
260
+
261
+ foreach ($paths as $path) {
262
+ $path = rtrim($path, '/\\');
263
+
264
+ if ($file = file_exists($path.DIRECTORY_SEPARATOR.$file)) {
265
+ return $file;
266
+ }
267
+ }
268
+
269
+ return false;
270
+ }
271
+ }
embedded/xrstf/composer-php52/lib/xrstf/Composer52/Generator.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright (c) 2013, Christoph Mewes, http://www.xrstf.de
4
+ *
5
+ * This file is released under the terms of the MIT license. You can find the
6
+ * complete text in the attached LICENSE file or online at:
7
+ *
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ */
10
+
11
+ namespace xrstf\Composer52;
12
+
13
+ use Composer\Repository\CompositeRepository;
14
+ use Composer\Script\Event;
15
+
16
+ class Generator {
17
+ public static function onPostInstallCmd(Event $event) {
18
+ $composer = $event->getComposer();
19
+ $installationManager = $composer->getInstallationManager();
20
+ $repoManager = $composer->getRepositoryManager();
21
+ $localRepo = $repoManager->getLocalRepository();
22
+ $package = $composer->getPackage();
23
+ $config = $composer->getConfig();
24
+
25
+ // We can't gain access to the Command's input object, so we have to look
26
+ // for -o / --optimize-autoloader ourselves. Sadly, neither getopt() works
27
+ // (always returns an empty array), nor does Symfony's Console Input, as
28
+ // it expects a full definition of the current command line and we can't
29
+ // provide that.
30
+
31
+ $args = $_SERVER['argv'];
32
+ $optimize = in_array('-o', $args) || in_array('--optimize-autoloader', $args) || in_array('--optimize', $args);
33
+
34
+ $suffix = $config->get('autoloader-suffix');
35
+
36
+ $generator = new AutoloadGenerator();
37
+ $generator->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize, $suffix);
38
+ }
39
+ }
inc/admin-menus/class-wcml-admin-menus.php CHANGED
@@ -4,23 +4,27 @@ class WCML_Admin_Menus{
4
 
5
  private static $woocommerce_wpml;
6
  private static $sitepress;
 
7
 
8
- public static function set_up_menus( &$woocommerce_wpml, &$sitepress, $check_dependencies ){
9
  self::$woocommerce_wpml =& $woocommerce_wpml;
10
  self::$sitepress =& $sitepress;
11
-
12
- add_action('admin_menu', array(__CLASS__, 'register_menus'));
 
13
 
14
  if( self::is_page_without_admin_language_switcher() ){
15
  self::remove_wpml_admin_language_switcher();
16
  }
17
 
18
  if( is_admin() && !is_null( $sitepress ) && $check_dependencies ){
19
- add_action('admin_footer', array(__CLASS__, 'documentation_links'));
20
  add_action( 'admin_head', array( __CLASS__, 'hide_multilingual_content_setup_box' ) );
21
  add_action( 'admin_init', array( __CLASS__, 'restrict_admin_with_redirect' ) );
22
  }
23
 
 
 
24
  }
25
 
26
  public static function register_menus(){
@@ -32,8 +36,7 @@ class WCML_Admin_Menus{
32
  __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'wpml_manage_woocommerce_multilingual', 'wpml-wcml', array(__CLASS__, 'render_menus'));
33
 
34
  }else{
35
- global $wpdb, $sitepress;
36
- $user_lang_pairs = get_user_meta(get_current_user_id(), $wpdb->prefix.'language_pairs', true);
37
  if( !empty( $user_lang_pairs ) ){
38
  add_menu_page(__('WooCommerce Multilingual', 'woocommerce-multilingual'),
39
  __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'translate',
@@ -241,4 +244,16 @@ class WCML_Admin_Menus{
241
  echo $message;
242
  }
243
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  }
4
 
5
  private static $woocommerce_wpml;
6
  private static $sitepress;
7
+ private static $wpdb;
8
 
9
+ public static function set_up_menus( &$woocommerce_wpml, &$sitepress, &$wpdb, $check_dependencies ){
10
  self::$woocommerce_wpml =& $woocommerce_wpml;
11
  self::$sitepress =& $sitepress;
12
+ self::$wpdb =& $wpdb;
13
+
14
+ add_action( 'admin_menu', array(__CLASS__, 'register_menus' ) );
15
 
16
  if( self::is_page_without_admin_language_switcher() ){
17
  self::remove_wpml_admin_language_switcher();
18
  }
19
 
20
  if( is_admin() && !is_null( $sitepress ) && $check_dependencies ){
21
+ add_action( 'admin_footer', array(__CLASS__, 'documentation_links' ) );
22
  add_action( 'admin_head', array( __CLASS__, 'hide_multilingual_content_setup_box' ) );
23
  add_action( 'admin_init', array( __CLASS__, 'restrict_admin_with_redirect' ) );
24
  }
25
 
26
+ add_filter( 'woocommerce_prevent_admin_access', array( __CLASS__, 'check_user_admin_access' ) );
27
+
28
  }
29
 
30
  public static function register_menus(){
36
  __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'wpml_manage_woocommerce_multilingual', 'wpml-wcml', array(__CLASS__, 'render_menus'));
37
 
38
  }else{
39
+ $user_lang_pairs = get_user_meta(get_current_user_id(), self::$wpdb->prefix.'language_pairs', true);
 
40
  if( !empty( $user_lang_pairs ) ){
41
  add_menu_page(__('WooCommerce Multilingual', 'woocommerce-multilingual'),
42
  __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'translate',
244
  echo $message;
245
  }
246
 
247
+ public static function check_user_admin_access( $prevent_access ){
248
+
249
+ if( self::$woocommerce_wpml->check_dependencies && self::$woocommerce_wpml->check_design_update ){
250
+ $user_lang_pairs = get_user_meta( get_current_user_id(), self::$wpdb->prefix.'language_pairs', true );
251
+ if( current_user_can( 'wpml_manage_woocommerce_multilingual' ) || !empty( $user_lang_pairs ) ){
252
+ return false;
253
+ }
254
+ }
255
+
256
+ return $prevent_access;
257
+ }
258
+
259
  }
inc/admin-menus/class-wcml-setup.php CHANGED
@@ -147,6 +147,7 @@ class WCML_Setup {
147
  }
148
 
149
  private function setup_header() {
 
150
  ?>
151
  <!DOCTYPE html>
152
  <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
147
  }
148
 
149
  private function setup_header() {
150
+ set_current_screen('wcml-setup');
151
  ?>
152
  <!DOCTYPE html>
153
  <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
inc/class-wcml-autoloader.php DELETED
@@ -1,72 +0,0 @@
1
- <?php
2
-
3
- class WCML_Autoloader {
4
-
5
- private $include_paths = array();
6
-
7
- public function __construct() {
8
- if ( function_exists( "__autoload" ) ) {
9
- spl_autoload_register( "__autoload" );
10
- }
11
-
12
- spl_autoload_register( array( $this, 'autoload' ) );
13
-
14
- $this->include_paths = array(
15
- WCML_PLUGIN_PATH . '/inc',
16
- WCML_PLUGIN_PATH . '/inc/template-classes/*',
17
- WCML_PLUGIN_PATH . '/inc/currencies',
18
- WCML_PLUGIN_PATH . '/inc/admin-menus',
19
- WCML_PLUGIN_PATH . '/inc/translation-editor',
20
- WCML_PLUGIN_PATH . '/compatibility'
21
- );
22
-
23
- $this->set_real_include_paths();
24
- }
25
-
26
- public function set_real_include_paths(){
27
- $paths = array();
28
-
29
- foreach( $this->include_paths as $path ){
30
- if( preg_match('#/\*$#', $path) ){
31
- $path = preg_replace( '#/\*$#', '', $path );
32
- $paths[] = $path;
33
- $folders = scandir( $path );
34
- foreach( $folders as $folder ){
35
- if ( $folder != '.' && $folder != '..' && is_dir( $path . '/' . $folder)){
36
- $paths[] = $path . '/' . $folder;
37
- }
38
- }
39
- }else{
40
- $paths[] = $path;
41
- }
42
- }
43
-
44
- $this->include_paths = $paths;
45
- }
46
-
47
- private function get_file_name_from_class( $class ) {
48
- return 'class-' . str_replace( '_', '-', $class ) . '.php';
49
- }
50
-
51
- private function load_file( $path ) {
52
- if ( $path && is_readable( $path ) ) {
53
- include_once( $path );
54
- return true;
55
- }
56
- return false;
57
- }
58
-
59
- public function autoload( $class ) {
60
- $class = strtolower( $class );
61
- $file = $this->get_file_name_from_class( $class );
62
-
63
- foreach( $this->include_paths as $path ){
64
- if( $this->load_file( $path . '/' . $file) ){
65
- break;
66
- }
67
- }
68
-
69
- }
70
- }
71
-
72
- new WCML_Autoloader();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/class-wcml-cart.php CHANGED
@@ -111,7 +111,7 @@ class WCML_Cart
111
  global $woocommerce;
112
 
113
  $exists_products = array();
114
- remove_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ) );
115
 
116
  foreach( $cart_contents as $key => $cart_content ){
117
  $cart_contents = apply_filters( 'wcml_check_on_duplicated_products_in_cart', $cart_contents, $key, $cart_content );
@@ -128,7 +128,7 @@ class WCML_Cart
128
  }
129
  }
130
 
131
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ) );
132
  return $cart_contents;
133
  }
134
 
@@ -186,7 +186,7 @@ class WCML_Cart
186
 
187
  public function translate_cart_subtotal( $cart ) {
188
 
189
- if( apply_filters( 'wcml_calculate_totals_exception', true ) ){
190
  $cart->calculate_totals();
191
  }
192
 
111
  global $woocommerce;
112
 
113
  $exists_products = array();
114
+ remove_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
115
 
116
  foreach( $cart_contents as $key => $cart_content ){
117
  $cart_contents = apply_filters( 'wcml_check_on_duplicated_products_in_cart', $cart_contents, $key, $cart_content );
128
  }
129
  }
130
 
131
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
132
  return $cart_contents;
133
  }
134
 
186
 
187
  public function translate_cart_subtotal( $cart ) {
188
 
189
+ if( apply_filters( 'wcml_calculate_totals_exception', true, $cart ) ){
190
  $cart->calculate_totals();
191
  }
192
 
inc/class-wcml-compatibility.php CHANGED
@@ -36,7 +36,7 @@ class WCML_Compatibility {
36
 
37
  //WooCommerce Table Rate Shipping plugin
38
  if(defined('TABLE_RATE_SHIPPING_VERSION')){
39
- $this->table_rate_shipping = new WCML_Table_Rate_Shipping();
40
  }
41
 
42
  //WooCommerce Subscriptions
@@ -51,7 +51,7 @@ class WCML_Compatibility {
51
 
52
  //Product Bundle
53
  if(class_exists('WC_Product_Bundle')){
54
- $this->product_bundles = new WCML_Product_Bundles();
55
  }
56
 
57
  // WooCommerce Variation Swatches and Photos
@@ -61,7 +61,7 @@ class WCML_Compatibility {
61
 
62
  // Product Add-ons
63
  if(class_exists( 'Product_Addon_Display' )){
64
- $this->product_addons = new WCML_Product_Addons();
65
  }
66
 
67
  // Product Per Product Shipping
@@ -89,8 +89,8 @@ class WCML_Compatibility {
89
  }
90
 
91
  // Dynamic Pricing
92
- if(class_exists( 'WC_Dynamic_Pricing' )){
93
- $this->dynamic_pricing = new WCML_Dynamic_Pricing();
94
  }
95
 
96
  // WooCommerce Bookings
@@ -99,7 +99,7 @@ class WCML_Compatibility {
99
 
100
  // WooCommerce Accommodation Bookings
101
  if( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) ){
102
- $this->bookings = new WCML_Accommodation_Bookings();
103
  }
104
  }
105
 
@@ -124,7 +124,7 @@ class WCML_Compatibility {
124
 
125
  // woocommerce composite products
126
  if ( isset( $GLOBALS[ 'woocommerce_composite_products' ] ) ) {
127
- $this->wc_composite_products = new WCML_Composite_Products();
128
  }
129
 
130
  // woocommerce checkout addons
@@ -155,6 +155,11 @@ class WCML_Compatibility {
155
  new WCML_Aurum();
156
  }
157
 
 
 
 
 
 
158
  }
159
 
160
  }
36
 
37
  //WooCommerce Table Rate Shipping plugin
38
  if(defined('TABLE_RATE_SHIPPING_VERSION')){
39
+ $this->table_rate_shipping = new WCML_Table_Rate_Shipping( $this->sitepress, $this->woocommerce_wpml );
40
  }
41
 
42
  //WooCommerce Subscriptions
51
 
52
  //Product Bundle
53
  if(class_exists('WC_Product_Bundle')){
54
+ $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml );
55
  }
56
 
57
  // WooCommerce Variation Swatches and Photos
61
 
62
  // Product Add-ons
63
  if(class_exists( 'Product_Addon_Display' )){
64
+ $this->product_addons = new WCML_Product_Addons( $this->sitepress );
65
  }
66
 
67
  // Product Per Product Shipping
89
  }
90
 
91
  // Dynamic Pricing
92
+ if ( class_exists('WC_Dynamic_Pricing') ) {
93
+ $this->dynamic_pricing = new WCML_Dynamic_Pricing( $this->sitepress );
94
  }
95
 
96
  // WooCommerce Bookings
99
 
100
  // WooCommerce Accommodation Bookings
101
  if( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) ){
102
+ $this->accomodation_bookings = new WCML_Accommodation_Bookings( $this->woocommerce_wpml );
103
  }
104
  }
105
 
124
 
125
  // woocommerce composite products
126
  if ( isset( $GLOBALS[ 'woocommerce_composite_products' ] ) ) {
127
+ $this->wc_composite_products = new WCML_Composite_Products( $this->sitepress, $this->woocommerce_wpml );
128
  }
129
 
130
  // woocommerce checkout addons
155
  new WCML_Aurum();
156
  }
157
 
158
+ // Visual Products Configurator
159
+ if( class_exists( 'Vpc' ) ){
160
+ $this->vpc = new WCML_Vpc();
161
+ }
162
+
163
  }
164
 
165
  }
inc/class-wcml-emails.php CHANGED
@@ -2,10 +2,13 @@
2
  class WCML_Emails{
3
 
4
  private $order_id = false;
5
-
6
  private $locale = false;
 
 
7
 
8
- function __construct( ) {
 
 
9
  add_action( 'init', array( $this, 'init' ) );
10
  }
11
 
@@ -48,6 +51,7 @@ class WCML_Emails{
48
  add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'admin_email' ), 9 );
49
  add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'admin_email' ), 9 );
50
  add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'admin_email' ), 9 );
 
51
 
52
  add_filter( 'icl_st_admin_string_return_cached', array( $this, 'admin_string_return_cached' ), 10, 2 );
53
 
@@ -57,6 +61,10 @@ class WCML_Emails{
57
  add_action('admin_footer', array($this, 'show_language_links_for_wc_emails'));
58
  $this->set_emails_string_lamguage();
59
  }
 
 
 
 
60
  }
61
 
62
  function email_refresh_in_ajax(){
@@ -83,7 +91,7 @@ class WCML_Emails{
83
  */
84
  function email_header($order) {
85
 
86
-
87
  if (is_array($order)) {
88
  $order = $order['order_id'];
89
  } elseif (is_object($order)) {
@@ -116,14 +124,11 @@ class WCML_Emails{
116
  * After email translation switch language to default.
117
  */
118
  function email_footer() {
119
- global $sitepress;
120
- $sitepress->switch_lang($sitepress->get_default_language());
121
- }
122
 
123
  function comments_language(){
124
- global $woocommerce_wpml;
125
-
126
- $this->change_email_language( $woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
127
 
128
  }
129
 
@@ -198,17 +203,17 @@ class WCML_Emails{
198
 
199
 
200
  function admin_email($order_id){
201
- global $woocommerce,$sitepress;
202
- if(class_exists('WC_Email_New_Order')){
203
  $recipients = explode(',',$woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient());
204
  foreach($recipients as $recipient){
205
  $user = get_user_by('email',$recipient);
206
  if($user){
207
- $user_lang = $sitepress->get_user_admin_language($user->ID);
208
  }else{
209
  $user_lang = get_post_meta($order_id, 'wpml_language', TRUE);
210
  }
211
- icl_get_string_translations_by_id(1);
212
  $this->change_email_language($user_lang);
213
 
214
  $woocommerce->mailer()->emails['WC_Email_New_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]heading' );
@@ -224,18 +229,101 @@ class WCML_Emails{
224
  }
225
  }
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  function change_email_language($lang){
228
- global $sitepress,$woocommerce;
229
- $sitepress->switch_lang($lang,true);
230
- $this->locale = $sitepress->get_locale( $lang );
231
  unload_textdomain('woocommerce');
232
  unload_textdomain('default');
233
  $woocommerce->load_plugin_textdomain();
234
  load_default_textdomain();
235
  global $wp_locale;
236
  $wp_locale = new WP_Locale();
237
- }
238
-
239
  function admin_string_return_cached( $value, $option ){
240
  if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
241
  return false;
@@ -262,7 +350,7 @@ class WCML_Emails{
262
  function icl_current_string_language( $current_language, $name ){
263
  $order_id = false;
264
 
265
- if( isset($_POST['action']) && $_POST['action'] == 'editpost' && isset($_POST['post_type']) && $_POST['post_type'] == 'shop_order' ){
266
  $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
267
  }elseif( isset($_POST['action']) && $_POST['action'] == 'woocommerce_add_order_note' && isset($_POST['note_type']) && $_POST['note_type'] == 'customer' ) {
268
  $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
@@ -279,8 +367,7 @@ class WCML_Emails{
279
  if( $order_language ){
280
  $current_language = $order_language;
281
  }else{
282
- global $sitepress;
283
- $current_language = $sitepress->get_current_language();
284
  }
285
  }
286
 
@@ -298,7 +385,6 @@ class WCML_Emails{
298
  }
299
 
300
  function show_language_links_for_wc_emails(){
301
- global $sitepress, $woocommerce_wpml;
302
 
303
  $emails_options = array(
304
  'woocommerce_new_order_settings',
@@ -339,21 +425,21 @@ class WCML_Emails{
339
  if ( in_array( $setting_key, $text_keys ) ) {
340
  $input_name = str_replace( '_settings', '', $emails_option ).'_'.$setting_key;
341
 
342
- $lang_selector = new WPML_Simple_Language_Selector($sitepress);
343
- $language = $woocommerce_wpml->strings->get_string_language( $setting_value, 'admin_texts_'.$emails_option, '['.$emails_option.']'.$setting_key );
344
  if( is_null( $language ) ) {
345
- $language = $sitepress->get_default_language();
346
  }
347
 
348
  $lang_selector->render( array(
349
- 'id' => $emails_option.'_'.$setting_key.'_language_selector',
350
- 'name' => 'wcml_lang-'.$emails_option.'-'.$setting_key,
351
- 'selected' => $language,
352
- 'show_please_select' => false,
353
- 'echo' => true,
354
- 'style' => 'width: 18%;float: left'
355
- )
356
- );
357
 
358
  $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=admin_texts_'.$emails_option.'&search='.$setting_value );
359
  ?>
@@ -372,7 +458,6 @@ class WCML_Emails{
372
  }
373
 
374
  function set_emails_string_lamguage(){
375
- global $woocommerce_wpml;
376
 
377
  foreach( $_POST as $key => $post_value ){
378
  if( substr( $key, 0, 9 ) == 'wcml_lang' ){
@@ -381,7 +466,7 @@ class WCML_Emails{
381
  $email_settings = get_option( $email_string[1], true );
382
 
383
  if( isset( $email_string[2] ) ){
384
- $woocommerce_wpml->strings->set_string_language( $email_settings[ $email_string[2] ], 'admin_texts_'.$email_string[1] , '['.$email_string[1].']'.$email_string[2], $post_value );
385
  }
386
  }
387
  }
2
  class WCML_Emails{
3
 
4
  private $order_id = false;
 
5
  private $locale = false;
6
+ private $woocommerce_wpml;
7
+ private $sitepress;
8
 
9
+ function __construct( &$woocommerce_wpml, &$sitepress ) {
10
+ $this->woocommerce_wpml = $woocommerce_wpml;
11
+ $this->sitepress = $sitepress;
12
  add_action( 'init', array( $this, 'init' ) );
13
  }
14
 
51
  add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'admin_email' ), 9 );
52
  add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'admin_email' ), 9 );
53
  add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'admin_email' ), 9 );
54
+ add_action( 'woocommerce_before_resend_order_emails', array( $this, 'admin_email' ), 9 );
55
 
56
  add_filter( 'icl_st_admin_string_return_cached', array( $this, 'admin_string_return_cached' ), 10, 2 );
57
 
61
  add_action('admin_footer', array($this, 'show_language_links_for_wc_emails'));
62
  $this->set_emails_string_lamguage();
63
  }
64
+
65
+ add_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
66
+ add_filter( 'woocommerce_order_get_items', array( $this, 'filter_order_items' ), 10, 2 );
67
+ add_filter( 'woocommerce_order_items_meta_get_formatted', array( $this, 'filter_formatted_items' ), 10, 2 );
68
  }
69
 
70
  function email_refresh_in_ajax(){
91
  */
92
  function email_header($order) {
93
 
94
+
95
  if (is_array($order)) {
96
  $order = $order['order_id'];
97
  } elseif (is_object($order)) {
124
  * After email translation switch language to default.
125
  */
126
  function email_footer() {
127
+ $this->sitepress->switch_lang($this->sitepress->get_default_language());
128
+ }
 
129
 
130
  function comments_language(){
131
+ $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
 
 
132
 
133
  }
134
 
203
 
204
 
205
  function admin_email($order_id){
206
+ global $woocommerce;
207
+ if(isset( $woocommerce->mailer()->emails['WC_Email_New_Order'] )){
208
  $recipients = explode(',',$woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient());
209
  foreach($recipients as $recipient){
210
  $user = get_user_by('email',$recipient);
211
  if($user){
212
+ $user_lang = $this->sitepress->get_user_admin_language($user->ID, true);
213
  }else{
214
  $user_lang = get_post_meta($order_id, 'wpml_language', TRUE);
215
  }
216
+
217
  $this->change_email_language($user_lang);
218
 
219
  $woocommerce->mailer()->emails['WC_Email_New_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]heading' );
229
  }
230
  }
231
 
232
+ function filter_payment_method_string( $check, $object_id, $meta_key, $single ){
233
+ if( $meta_key == '_payment_method_title' ){
234
+
235
+ $payment_method = get_post_meta( $object_id, '_payment_method', true );
236
+
237
+ if( $payment_method ){
238
+
239
+ $payment_gateways = WC()->payment_gateways->payment_gateways();
240
+ if( isset( $payment_gateways[ $payment_method ] ) ){
241
+ $title = $this->woocommerce_wpml->gateways->translate_gateway_title( $payment_gateways[ $payment_method ]->title, $payment_method, $this->sitepress->get_current_language() );
242
+
243
+ return $title;
244
+ }
245
+ }
246
+
247
+
248
+ }
249
+ return $check;
250
+ }
251
+
252
+ function filter_order_items( $items, $object){
253
+
254
+ foreach( $items as $item_key => $item ){
255
+
256
+ foreach( $item as $key => $item_meta ){
257
+
258
+ if( $key == 'type' && $item_meta == 'line_item' ){
259
+
260
+ $current_prod_id = apply_filters( 'translate_object_id', $item[ 'product_id' ], 'product', false, $this->sitepress->get_current_language() );
261
+ if( !is_null( $current_prod_id ) ){
262
+ $items[ $item_key ][ 'name' ] = wc_get_product( $current_prod_id )->get_title();
263
+ }
264
+
265
+ } elseif( $key == 'type' && $item_meta == 'shipping' && isset( $item[ 'method_id' ] ) ){
266
+
267
+ $items[ $item_key ][ 'name' ] = $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item[ 'name' ], $item[ 'method_id' ], $this->sitepress->get_current_language() );
268
+
269
+ }
270
+
271
+ }
272
+
273
+ }
274
+
275
+
276
+ return $items;
277
+ }
278
+
279
+ function filter_formatted_items( $formatted_meta, $object ){
280
+
281
+ if( $object->product->variation_id ){
282
+
283
+ $current_prod_variation_id = apply_filters( 'translate_object_id', $object->product->variation_id, 'product_variation', false );
284
+
285
+ if( !is_null( $current_prod_variation_id ) ) {
286
+
287
+ $var_data = wc_get_product( $object->product->id )->get_available_variation( $current_prod_variation_id );
288
+
289
+ foreach( $formatted_meta as $key => $formatted_var ){
290
+
291
+ foreach( $var_data[ 'attributes' ] as $attr_full_key => $attribute ){
292
+
293
+ $attr_key = substr( $attr_full_key, 10 );
294
+
295
+ if( $formatted_var[ 'key' ] == $attr_key ){
296
+
297
+ $formatted_meta[ $key ][ 'value' ] = $attribute;
298
+
299
+ if( !taxonomy_exists( wc_sanitize_taxonomy_name ( $attr_key ) ) ){
300
+
301
+ $custom_attr_trnsl = $this->woocommerce_wpml->attributes->get_custom_attribute_translation( $object->product->id, $attr_key, array('is_taxonomy' => false), $this->sitepress->get_current_language() );
302
+
303
+ $formatted_meta[ $key ][ 'label' ] = $custom_attr_trnsl['name'];
304
+ }
305
+ }
306
+ }
307
+ }
308
+ }
309
+ }
310
+
311
+ return $formatted_meta;
312
+
313
+ }
314
+
315
  function change_email_language($lang){
316
+ global $woocommerce;
317
+ $this->sitepress->switch_lang($lang,true);
318
+ $this->locale = $this->sitepress->get_locale( $lang );
319
  unload_textdomain('woocommerce');
320
  unload_textdomain('default');
321
  $woocommerce->load_plugin_textdomain();
322
  load_default_textdomain();
323
  global $wp_locale;
324
  $wp_locale = new WP_Locale();
325
+ }
326
+
327
  function admin_string_return_cached( $value, $option ){
328
  if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
329
  return false;
350
  function icl_current_string_language( $current_language, $name ){
351
  $order_id = false;
352
 
353
+ if( isset($_POST['action']) && $_POST['action'] == 'editpost' && isset($_POST['post_type']) && $_POST['post_type'] == 'shop_order' && isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] != 'send_email_new_order' ){
354
  $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
355
  }elseif( isset($_POST['action']) && $_POST['action'] == 'woocommerce_add_order_note' && isset($_POST['note_type']) && $_POST['note_type'] == 'customer' ) {
356
  $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
367
  if( $order_language ){
368
  $current_language = $order_language;
369
  }else{
370
+ $current_language = $this->sitepress->get_current_language();
 
371
  }
372
  }
373
 
385
  }
386
 
387
  function show_language_links_for_wc_emails(){
 
388
 
389
  $emails_options = array(
390
  'woocommerce_new_order_settings',
425
  if ( in_array( $setting_key, $text_keys ) ) {
426
  $input_name = str_replace( '_settings', '', $emails_option ).'_'.$setting_key;
427
 
428
+ $lang_selector = new WPML_Simple_Language_Selector($this->sitepress);
429
+ $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'admin_texts_'.$emails_option, '['.$emails_option.']'.$setting_key );
430
  if( is_null( $language ) ) {
431
+ $language = $this->sitepress->get_default_language();
432
  }
433
 
434
  $lang_selector->render( array(
435
+ 'id' => $emails_option.'_'.$setting_key.'_language_selector',
436
+ 'name' => 'wcml_lang-'.$emails_option.'-'.$setting_key,
437
+ 'selected' => $language,
438
+ 'show_please_select' => false,
439
+ 'echo' => true,
440
+ 'style' => 'width: 18%;float: left'
441
+ )
442
+ );
443
 
444
  $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=admin_texts_'.$emails_option.'&search='.$setting_value );
445
  ?>
458
  }
459
 
460
  function set_emails_string_lamguage(){
 
461
 
462
  foreach( $_POST as $key => $post_value ){
463
  if( substr( $key, 0, 9 ) == 'wcml_lang' ){
466
  $email_settings = get_option( $email_string[1], true );
467
 
468
  if( isset( $email_string[2] ) ){
469
+ $this->woocommerce_wpml->strings->set_string_language( $email_settings[ $email_string[2] ], 'admin_texts_'.$email_string[1] , '['.$email_string[1].']'.$email_string[2], $post_value );
470
  }
471
  }
472
  }
inc/class-wcml-products.php CHANGED
@@ -412,4 +412,15 @@ class WCML_Products{
412
  return $args;
413
  }
414
 
 
 
 
 
 
 
 
 
 
 
 
415
  }
412
  return $args;
413
  }
414
 
415
+ /*
416
+ * get meta ids for multiple values post meta key
417
+ */
418
+ public function get_mid_ids_by_key( $post_id, $meta_key ) {
419
+ $ids = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT meta_id FROM {$this->wpdb->postmeta} WHERE post_id = %d AND meta_key = %s", $post_id, $meta_key ) );
420
+ if( $ids )
421
+ return $ids;
422
+
423
+ return false;
424
+ }
425
+
426
  }
inc/class-wcml-terms.php CHANGED
@@ -836,7 +836,7 @@ class WCML_Terms{
836
  if( $pagenow != 'post.php' && ( get_post_type($post_id) == 'product' || get_post_type($post_id) == 'product_variation' ) && $taxonomy == 'product_shipping_class'){
837
 
838
  remove_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
839
- $terms = get_the_terms( apply_filters( 'translate_object_id', $post_id, get_post_type($post_id), true, $this->woocommerce_wpml->products->get_original_product_language( $post_id ) ),'product_shipping_class');
840
  add_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
841
  return $terms;
842
  }
836
  if( $pagenow != 'post.php' && ( get_post_type($post_id) == 'product' || get_post_type($post_id) == 'product_variation' ) && $taxonomy == 'product_shipping_class'){
837
 
838
  remove_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
839
+ $terms = get_the_terms( apply_filters( 'translate_object_id', $post_id, get_post_type($post_id), true, $this->sitepress->get_current_language() ),'product_shipping_class');
840
  add_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
841
  return $terms;
842
  }
inc/class-wcml-url-translation.php CHANGED
@@ -32,6 +32,8 @@ class WCML_Url_Translation {
32
 
33
  add_action( 'wp_ajax_wcml_update_base_translation', array( $this, 'wcml_update_base_translation' ) );
34
 
 
 
35
  }
36
 
37
  function set_up() {
@@ -444,7 +446,8 @@ class WCML_Url_Translation {
444
  unset( $buff_value );
445
  }
446
  }
447
-
 
448
  return $value;
449
  }
450
 
@@ -685,4 +688,22 @@ class WCML_Url_Translation {
685
 
686
 
687
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
688
  }
32
 
33
  add_action( 'wp_ajax_wcml_update_base_translation', array( $this, 'wcml_update_base_translation' ) );
34
 
35
+ add_filter( 'redirect_canonical', array( $this, 'check_wc_tax_url_on_redirect' ), 10, 2 );
36
+
37
  }
38
 
39
  function set_up() {
446
  unset( $buff_value );
447
  }
448
  }
449
+
450
+
451
  return $value;
452
  }
453
 
688
 
689
 
690
  }
691
+
692
+ // return correct redirect URL for WC standard taxonomies when pretty permalink uses with lang as parametr in WPML
693
+ function check_wc_tax_url_on_redirect( $redirect_url, $requested_url ){
694
+ global $wp_query;
695
+
696
+ if( is_tax() ){
697
+ $original = @parse_url( $requested_url );
698
+ parse_str( $original['query'], $query_args ) ;
699
+ if( ( isset( $query_args[ 'product_cat' ] ) || isset( $query_args[ 'product_tag' ] ) ) && isset ( $query_args[ 'lang' ] ) ){
700
+ $obj = $wp_query->get_queried_object();
701
+ $tax_url = get_term_link( (int)$obj->term_id, $obj->taxonomy ) ;
702
+
703
+ return $tax_url;
704
+ }
705
+ }
706
+
707
+ return $redirect_url;
708
+ }
709
  }
inc/class-wcml-wc-gateways.php CHANGED
@@ -97,8 +97,8 @@ class WCML_WC_Gateways{
97
 
98
  }
99
 
100
- function translate_gateway_title( $title, $gateway_id ) {
101
- $title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $gateway_id .'_gateway_title', $this->current_language );
102
  return $title;
103
  }
104
 
97
 
98
  }
99
 
100
+ function translate_gateway_title( $title, $gateway_id, $language = false ) {
101
+ $title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $gateway_id .'_gateway_title', $language ? $language : $this->current_language );
102
  return $title;
103
  }
104
 
inc/class-wcml-wc-shipping.php CHANGED
@@ -118,9 +118,9 @@ class WCML_WC_Shipping{
118
  return $available_methods;
119
  }
120
 
121
- function translate_shipping_method_title( $title, $shipping_id ) {
122
  $shipping_id = str_replace( ':', '', $shipping_id );
123
- $title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $shipping_id .'_shipping_method_title', $this->current_language );
124
 
125
  return $title;
126
  }
118
  return $available_methods;
119
  }
120
 
121
+ function translate_shipping_method_title( $title, $shipping_id, $language = false ) {
122
  $shipping_id = str_replace( ':', '', $shipping_id );
123
+ $title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $shipping_id .'_shipping_method_title', $language ? $language : $this->current_language );
124
 
125
  return $title;
126
  }
inc/class-wcml-xdomain-data.php CHANGED
@@ -12,7 +12,7 @@ class WCML_xDomain_Data {
12
  */
13
  function __construct() {
14
  add_filter( 'wpml_cross_domain_language_data', array($this, 'pass_data_to_domain') );
15
- add_action( 'init', array($this, 'check_request') );
16
  }
17
 
18
  /**
@@ -74,11 +74,14 @@ class WCML_xDomain_Data {
74
 
75
  if ( isset($data['session']) ) {
76
  setcookie( 'wp_woocommerce_session_' . COOKIEHASH, $data['session'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
 
77
  }
78
 
79
  if ( isset($data['hash ']) ) {
80
  setcookie( 'woocommerce_cart_hash', $data['hash'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
81
  setcookie( 'woocommerce_items_in_cart', $data['items'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
 
 
82
  }
83
 
84
  }
12
  */
13
  function __construct() {
14
  add_filter( 'wpml_cross_domain_language_data', array($this, 'pass_data_to_domain') );
15
+ add_action( 'before_woocommerce_init', array($this, 'check_request') );
16
  }
17
 
18
  /**
74
 
75
  if ( isset($data['session']) ) {
76
  setcookie( 'wp_woocommerce_session_' . COOKIEHASH, $data['session'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
77
+ $_COOKIE[ 'wp_woocommerce_session_' . COOKIEHASH ] = $data['session'];
78
  }
79
 
80
  if ( isset($data['hash ']) ) {
81
  setcookie( 'woocommerce_cart_hash', $data['hash'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
82
  setcookie( 'woocommerce_items_in_cart', $data['items'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
83
+ $_COOKIE[ 'woocommerce_cart_hash' ] = $data['hash'];
84
+ $_COOKIE[ 'woocommerce_items_in_cart' ] = $data['items'];
85
  }
86
 
87
  }
inc/class-woocommerce-wpml.php CHANGED
@@ -73,6 +73,8 @@ class woocommerce_wpml {
73
 
74
  $this->currencies = new WCML_Currencies( $this );
75
 
 
 
76
  add_action('init', array($this, 'init'),2);
77
  }
78
 
@@ -102,7 +104,7 @@ class woocommerce_wpml {
102
  $this->check_dependencies = $this->dependencies->check();
103
  $this->check_design_update = $this->dependencies->check_design_update();
104
 
105
- WCML_Admin_Menus::set_up_menus( $this, $sitepress, $this->check_dependencies );
106
 
107
  if( !$this->check_dependencies ){
108
 
@@ -140,7 +142,7 @@ class woocommerce_wpml {
140
  $this->sync_product_data = new WCML_Synchronize_Product_Data( $this, $sitepress, $wpdb );
141
  $this->sync_variations_data = new WCML_Synchronize_Variations_Data( $this, $sitepress, $wpdb );
142
  $this->store = new WCML_Store_Pages;
143
- $this->emails = new WCML_Emails;
144
  $this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
145
  $this->attributes = new WCML_Attributes( $this, $sitepress, $wpdb );
146
  $this->orders = new WCML_Orders;
@@ -148,7 +150,6 @@ class woocommerce_wpml {
148
  $this->shipping = new WCML_WC_Shipping( $sitepress );
149
  $this->gateways = new WCML_WC_Gateways( $sitepress );
150
  $this->currencies = new WCML_Currencies( $this );
151
- $this->xdomain_data = new WCML_xDomain_Data;
152
  $this->languages_upgrader = new WCML_Languages_Upgrader;
153
  $this->url_translation = new WCML_Url_Translation ( $this, $sitepress );
154
  $this->requests = new WCML_Requests;
73
 
74
  $this->currencies = new WCML_Currencies( $this );
75
 
76
+ $this->xdomain_data = new WCML_xDomain_Data;
77
+
78
  add_action('init', array($this, 'init'),2);
79
  }
80
 
104
  $this->check_dependencies = $this->dependencies->check();
105
  $this->check_design_update = $this->dependencies->check_design_update();
106
 
107
+ WCML_Admin_Menus::set_up_menus( $this, $sitepress, $wpdb, $this->check_dependencies );
108
 
109
  if( !$this->check_dependencies ){
110
 
142
  $this->sync_product_data = new WCML_Synchronize_Product_Data( $this, $sitepress, $wpdb );
143
  $this->sync_variations_data = new WCML_Synchronize_Variations_Data( $this, $sitepress, $wpdb );
144
  $this->store = new WCML_Store_Pages;
145
+ $this->emails = new WCML_Emails( $this, $sitepress );
146
  $this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
147
  $this->attributes = new WCML_Attributes( $this, $sitepress, $wpdb );
148
  $this->orders = new WCML_Orders;
150
  $this->shipping = new WCML_WC_Shipping( $sitepress );
151
  $this->gateways = new WCML_WC_Gateways( $sitepress );
152
  $this->currencies = new WCML_Currencies( $this );
 
153
  $this->languages_upgrader = new WCML_Languages_Upgrader;
154
  $this->url_translation = new WCML_Url_Translation ( $this, $sitepress );
155
  $this->requests = new WCML_Requests;
inc/currencies/class-wcml-multi-currency-configuration.php CHANGED
@@ -344,8 +344,8 @@ class WCML_Multi_Currency_Configuration{
344
  foreach( $keys as $key ){
345
  $iclTranslationManagement->settings[ 'custom_fields_readonly_config' ][] = $key;
346
  if( !isset( $sitepress_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] ) ||
347
- $wpml_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] != 1 ) {
348
- $wpml_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] = 1;
349
  $save = true;
350
  }
351
 
@@ -355,8 +355,8 @@ class WCML_Multi_Currency_Configuration{
355
  $iclTranslationManagement->settings[ 'custom_fields_readonly_config' ][] = $new_key;
356
 
357
  if( !isset( $sitepress_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $new_key ] ) ||
358
- $wpml_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $new_key ] != 0) {
359
- $wpml_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $new_key ] = 0;
360
  $save = true;
361
  }
362
  }
344
  foreach( $keys as $key ){
345
  $iclTranslationManagement->settings[ 'custom_fields_readonly_config' ][] = $key;
346
  if( !isset( $sitepress_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] ) ||
347
+ $wpml_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] != WPML_COPY_CUSTOM_FIELD ) {
348
+ $wpml_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] = WPML_COPY_CUSTOM_FIELD;
349
  $save = true;
350
  }
351
 
355
  $iclTranslationManagement->settings[ 'custom_fields_readonly_config' ][] = $new_key;
356
 
357
  if( !isset( $sitepress_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $new_key ] ) ||
358
+ $wpml_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $new_key ] != WPML_IGNORE_CUSTOM_FIELD) {
359
+ $wpml_settings[ 'translation-management' ][ 'custom_fields_translation' ][ $new_key ] = WPML_IGNORE_CUSTOM_FIELD;
360
  $save = true;
361
  }
362
  }
inc/currencies/class-wcml-multi-currency-prices.php CHANGED
@@ -273,6 +273,10 @@ class WCML_Multi_Currency_Prices{
273
  $currency = $this->multi_currency->get_client_currency();
274
  }
275
 
 
 
 
 
276
  $currency_options = $this->woocommerce_wpml->settings['currency_options'][$currency];
277
 
278
  if( $currency_options['rounding'] != 'disabled' ){
@@ -523,6 +527,7 @@ class WCML_Multi_Currency_Prices{
523
  if(isset($this->multi_currency->currencies[$currency_code]['num_decimals']) ){
524
  $value = $this->multi_currency->currencies[$currency_code]['num_decimals'];
525
  }
 
526
  return $value;
527
  }
528
 
273
  $currency = $this->multi_currency->get_client_currency();
274
  }
275
 
276
+ if( is_null($this->woocommerce_wpml) ){
277
+ global $woocommerce_wpml;
278
+ $this->woocommerce_wpml = $woocommerce_wpml;
279
+ }
280
  $currency_options = $this->woocommerce_wpml->settings['currency_options'][$currency];
281
 
282
  if( $currency_options['rounding'] != 'disabled' ){
527
  if(isset($this->multi_currency->currencies[$currency_code]['num_decimals']) ){
528
  $value = $this->multi_currency->currencies[$currency_code]['num_decimals'];
529
  }
530
+
531
  return $value;
532
  }
533
 
inc/currencies/class-wcml-multi-currency-resources.php CHANGED
@@ -28,8 +28,12 @@ class WCML_Multi_Currency_Resources{
28
 
29
  wp_enqueue_script('wcml-mc-scripts');
30
 
31
- $script_vars['wcml_mc_nonce'] = wp_create_nonce( 'switch_currency' );
32
- $script_vars['wcml_spinner'] = WCML_PLUGIN_URL . '/res/images/ajax-loader.gif';
 
 
 
 
33
 
34
  if( !empty(self::$multi_currency->W3TC) ){
35
  $script_vars['w3tc'] = 1;
28
 
29
  wp_enqueue_script('wcml-mc-scripts');
30
 
31
+ $script_vars['wcml_mc_nonce'] = wp_create_nonce( 'switch_currency' );
32
+ $script_vars['wcml_spinner'] = WCML_PLUGIN_URL . '/res/images/ajax-loader.gif';
33
+ $script_vars['current_currency']= array(
34
+ 'code' => self::$multi_currency->get_client_currency(),
35
+ 'symbol'=> get_woocommerce_currency_symbol( self::$multi_currency->get_client_currency() )
36
+ );
37
 
38
  if( !empty(self::$multi_currency->W3TC) ){
39
  $script_vars['w3tc'] = 1;
inc/currencies/class-wcml-multi-currency-shipping.php CHANGED
@@ -5,57 +5,30 @@ class WCML_Multi_Currency_Shipping{
5
  private $multi_currency;
6
 
7
  public function __construct( &$multi_currency ) {
 
8
 
9
  $this->multi_currency =& $multi_currency;
10
 
11
- add_filter('woocommerce_package_rates', array($this, 'shipping_taxes_filter'));
 
 
 
 
12
 
13
  add_filter( 'wcml_shipping_price_amount', array($this, 'shipping_price_filter') ); // WCML filters
14
  add_filter( 'wcml_shipping_free_min_amount', array($this, 'shipping_free_min_amount') ); // WCML filters
15
 
16
  add_filter('option_woocommerce_free_shipping_settings', array($this, 'adjust_min_amount_required'));
17
- }
18
-
19
- public function shipping_taxes_filter($methods){
20
-
21
- global $woocommerce;
22
- $woocommerce->shipping->load_shipping_methods();
23
- $shipping_methods = $woocommerce->shipping->get_shipping_methods();
24
-
25
- foreach($methods as $k => $method){
26
-
27
- // exceptions
28
- $is_old_table_rate = defined('TABLE_RATE_SHIPPING_VERSION' ) &&
29
- version_compare( TABLE_RATE_SHIPPING_VERSION, '3.0', '<' ) &&
30
- preg_match('/^table_rate-[0-9]+ : [0-9]+$/', $k);
31
 
32
- if(
33
- isset($shipping_methods[$method->id]) &&
34
- isset($shipping_methods[$method->id]->settings['type']) &&
35
- $shipping_methods[$method->id]->settings['type'] == 'percent'
36
- || $is_old_table_rate
37
- ){
38
- continue;
39
- }
40
-
41
- foreach($method->taxes as $j => $tax){
42
-
43
- $methods[$k]->taxes[$j] = apply_filters('wcml_shipping_price_amount', $methods[$k]->taxes[$j]);
44
-
45
- }
46
-
47
- if($methods[$k]->cost){
48
-
49
- if( isset($shipping_methods[$method->id]) && preg_match('/percent/', $shipping_methods[$method->id]->settings['cost']) ){
50
- continue;
51
- }
52
 
53
- $methods[$k]->cost = apply_filters('wcml_shipping_price_amount', $methods[$k]->cost);
54
- }
55
 
 
 
56
  }
57
 
58
- return $methods;
59
  }
60
 
61
  public function shipping_price_filter($price) {
5
  private $multi_currency;
6
 
7
  public function __construct( &$multi_currency ) {
8
+ global $wpdb;
9
 
10
  $this->multi_currency =& $multi_currency;
11
 
12
+ $rates = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE method_id IN('flat_rate', 'local_pickup')" );
13
+ foreach( $rates as $method ){
14
+ $option_name = sprintf('woocommerce_%s_%d_settings', $method->method_id, $method->instance_id );
15
+ add_filter('option_' . $option_name, array($this, 'convert_shipping_cost'));
16
+ }
17
 
18
  add_filter( 'wcml_shipping_price_amount', array($this, 'shipping_price_filter') ); // WCML filters
19
  add_filter( 'wcml_shipping_free_min_amount', array($this, 'shipping_free_min_amount') ); // WCML filters
20
 
21
  add_filter('option_woocommerce_free_shipping_settings', array($this, 'adjust_min_amount_required'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ public function convert_shipping_cost( $settings ){
 
26
 
27
+ if( isset($settings['cost']) ){
28
+ $settings['cost'] = $this->multi_currency->prices->raw_price_filter($settings['cost'], $this->multi_currency->get_client_currency());
29
  }
30
 
31
+ return $settings;
32
  }
33
 
34
  public function shipping_price_filter($price) {
inc/currencies/class-wcml-multi-currency-ui.php DELETED
@@ -1,5 +0,0 @@
1
- <?php
2
-
3
- class WCML_Multi_Currency_UI{
4
-
5
- }
 
 
 
 
 
inc/installer-loader.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
 
 
2
 
3
- if( file_exists( WCML_PLUGIN_PATH . '/embedded/installer/loader.php' ) ){
4
-
5
- include WCML_PLUGIN_PATH . '/embedded/installer/loader.php' ;
6
  $args = array(
7
  'plugins_install_tab' => 1
8
  );
1
  <?php
2
+ $installer_path = 'embedded/otgs/installer';
3
+ if( file_exists( WCML_PLUGIN_PATH . '/' . $installer_path . '/loader.php' ) ){
4
 
5
+ include WCML_PLUGIN_PATH . '/' . $installer_path . '/loader.php' ;
 
 
6
  $args = array(
7
  'plugins_install_tab' => 1
8
  );
inc/missing-php-functions.php CHANGED
@@ -74,4 +74,28 @@ function wcml_translate_single_string_filter( $original_value, $context, $name,
74
  return $original_value;
75
  }
76
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  ?>
74
  return $original_value;
75
  }
76
  }
77
+
78
+ // two WordPress functions that were added in 4.4.0
79
+ if( version_compare( $GLOBALS['wp_version'], '4.4.0' , '<' ) ){
80
+
81
+ if( !function_exists( 'get_the_post_thumbnail_url' ) ){
82
+ function get_the_post_thumbnail_url( $post = null, $size = 'post-thumbnail' ) {
83
+ $post_thumbnail_id = get_post_thumbnail_id( $post );
84
+ if ( ! $post_thumbnail_id ) {
85
+ return false;
86
+ }
87
+ return wp_get_attachment_image_url( $post_thumbnail_id, $size );
88
+ }
89
+ }
90
+
91
+ if( !function_exists( 'wp_get_attachment_image_url' ) ) {
92
+ function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon = false ) {
93
+ $image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
94
+ return isset( $image['0'] ) ? $image['0'] : false;
95
+ }
96
+ }
97
+
98
+ }
99
+
100
+
101
  ?>
inc/translation-editor/class-wcml-editor-ui-product-job.php CHANGED
@@ -24,7 +24,7 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
24
  $this->not_display_fields_for_variables_product = array( '_purchase_note', '_regular_price', '_sale_price',
25
  '_price', '_min_variation_price', '_max_variation_price',
26
  '_min_variation_regular_price', '_max_variation_regular_price',
27
- '_min_variation_sale_price', '_max_variation_sale_price' );
28
 
29
  $this->job_details = $job_details;
30
  $this->product = wc_get_product( $job_details[ 'job_id' ] );
@@ -137,10 +137,9 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
137
 
138
  if( $custom_fields ) {
139
  $custom_fields_section = new WPML_Editor_UI_Field_Section( __( 'Custom Fields', 'woocommerce-multilingual' ) );
140
- foreach( $custom_fields as $custom_field ) {
141
- $custom_field_input = new WPML_Editor_UI_Single_Line_Field( $custom_field, $this->get_product_custom_field_label( $custom_field ), $this->data, true );
142
- $custom_fields_section->add_field( $custom_field_input );
143
- }
144
  $this->add_field( $custom_fields_section );
145
  }
146
 
@@ -150,6 +149,12 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
150
  if( !empty( $variations ) ){
151
  $variations_data_section = new WPML_Editor_UI_Field_Section( __( 'Variations data', 'woocommerce-multilingual' ) );
152
  foreach( $variations as $variation ){
 
 
 
 
 
 
153
  $var_desc_field_input = new WPML_Editor_UI_Single_Line_Field( 'variation_desc'.$variation['variation_id'], 'Variation description #'.$variation['variation_id'], $this->data, true );
154
  $variations_data_section->add_field( $var_desc_field_input );
155
  }
@@ -209,6 +214,29 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
209
 
210
  }
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  function get_data() {
213
 
214
  $trn_product_id = apply_filters( 'translate_object_id', $this->product->id, 'product', false, $this->get_target_language() );
@@ -268,23 +296,18 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
268
  }
269
  }
270
 
271
- $custom_fields = $this->get_product_custom_fields_to_translate( $this->product->id );
272
- if( $custom_fields ){
273
- foreach( $custom_fields as $custom_field ) {
274
- $element_data[ $custom_field ] = array( 'original' => get_post_meta( $this->product->id, $custom_field, true ) );
275
- $element_data[ $custom_field ][ 'translation' ] = ( isset( $translation->ID ) && $translation->ID ) ? get_post_meta( $translation->ID, $custom_field, true) : '';
276
-
277
- }
278
- }
279
 
280
  if( $this->woocommerce_wpml->products->is_variable_product( $this->product->id ) ){
281
  $variations = $this->product->get_available_variations();
282
 
283
  if( !empty( $variations ) ){
284
  foreach( $variations as $variation ){
285
- $element_data[ 'variation_desc'.$variation['variation_id'] ] = array( 'original' => strip_tags( $variation['variation_description'] ) );
286
- $translated_variation_id = apply_filters( 'translate_object_id', $variation['variation_id'], 'product_variation', false, $this->get_target_language() );
287
- $element_data[ 'variation_desc'.$variation['variation_id'] ][ 'translation' ] = $translated_variation_id ?get_post_meta( $translated_variation_id, '_variation_description', true ) : '';
 
 
288
  }
289
  }
290
  }
@@ -322,7 +345,42 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
322
 
323
  return $element_data;
324
  }
325
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
  public function save_translations( $translations ) {
327
  /** @var TranslationManagement $iclTranslationManagement */
328
  global $iclTranslationManagement;
@@ -523,12 +581,12 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
523
  }
524
 
525
  //get product content labels
526
- public function get_product_custom_field_label( $field )
527
  {
528
  global $sitepress;
529
  $settings = $sitepress->get_settings();
530
  $label = '';
531
- if ( isset( $settings['translation-management']['custom_fields_translation'][ $field ] ) && $settings['translation-management']['custom_fields_translation'][ $field ] === 2 ) {
532
  if ( in_array( $field, $this->not_display_fields_for_variables_product, true ) ) {
533
  return false;
534
  }
@@ -547,6 +605,10 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
547
  $custom_key_label = str_replace('_', ' ', $field);
548
  $label = trim($custom_key_label[0]) ? ucfirst($custom_key_label) : ucfirst(substr($custom_key_label, 1));
549
 
 
 
 
 
550
  }
551
 
552
  return $label;
@@ -583,7 +645,7 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
583
  $contents = array();
584
 
585
  foreach( get_post_custom_keys( $product_id ) as $meta_key ) {
586
- if ( isset( $settings['translation-management']['custom_fields_translation'][ $meta_key ] ) && $settings['translation-management']['custom_fields_translation'][ $meta_key ] === 2 ) {
587
  if( $this->check_custom_field_is_single_value( $product_id, $meta_key ) ){
588
  if ( in_array( $meta_key, apply_filters( 'wcml_not_display_single_fields_to_translate', $this->not_display_fields_for_variables_product ), true ) ) {
589
  continue;
24
  $this->not_display_fields_for_variables_product = array( '_purchase_note', '_regular_price', '_sale_price',
25
  '_price', '_min_variation_price', '_max_variation_price',
26
  '_min_variation_regular_price', '_max_variation_regular_price',
27
+ '_min_variation_sale_price', '_max_variation_sale_price','_downloadable_files' );
28
 
29
  $this->job_details = $job_details;
30
  $this->product = wc_get_product( $job_details[ 'job_id' ] );
137
 
138
  if( $custom_fields ) {
139
  $custom_fields_section = new WPML_Editor_UI_Field_Section( __( 'Custom Fields', 'woocommerce-multilingual' ) );
140
+
141
+ $this->add_custom_fields_ui_section( $custom_fields_section, $custom_fields, false );
142
+
 
143
  $this->add_field( $custom_fields_section );
144
  }
145
 
149
  if( !empty( $variations ) ){
150
  $variations_data_section = new WPML_Editor_UI_Field_Section( __( 'Variations data', 'woocommerce-multilingual' ) );
151
  foreach( $variations as $variation ){
152
+
153
+ $var_custom_fields = $this->get_product_custom_fields_to_translate( $variation[ 'variation_id' ] );
154
+ if( $var_custom_fields ){
155
+ $this->add_custom_fields_ui_section( $variations_data_section, $var_custom_fields, $variation[ 'variation_id' ] );
156
+ }
157
+
158
  $var_desc_field_input = new WPML_Editor_UI_Single_Line_Field( 'variation_desc'.$variation['variation_id'], 'Variation description #'.$variation['variation_id'], $this->data, true );
159
  $variations_data_section->add_field( $var_desc_field_input );
160
  }
214
 
215
  }
216
 
217
+ public function add_custom_fields_ui_section( $custom_fields_section, $custom_fields, $variation_id = false ){
218
+
219
+ foreach( $custom_fields as $custom_field ) {
220
+
221
+ $custom_field_id = $variation_id ? $custom_field.$variation_id : $custom_field;
222
+
223
+ if( key( $this->data[ $custom_field_id ] ) != 'original' ){
224
+ $group = new WPML_Editor_UI_Field_Group( $this->get_product_custom_field_label( $custom_field, $variation_id ), true );
225
+ foreach( $this->data[ $custom_field_id ] as $custom_field_key => $custom_field_array ){
226
+ $custom_field_input = new WPML_Editor_UI_Single_Line_Field( $custom_field_key, '', $this->data[ $custom_field_id ], false );
227
+
228
+ $group->add_field( $custom_field_input );
229
+ }
230
+ $custom_fields_section->add_field( $group );
231
+ }else{
232
+ $custom_field_input = new WPML_Editor_UI_Single_Line_Field( $custom_field_id, $this->get_product_custom_field_label( $custom_field, $variation_id ), $this->data, true );
233
+ $custom_fields_section->add_field( $custom_field_input );
234
+ }
235
+ }
236
+
237
+ }
238
+
239
+
240
  function get_data() {
241
 
242
  $trn_product_id = apply_filters( 'translate_object_id', $this->product->id, 'product', false, $this->get_target_language() );
296
  }
297
  }
298
 
299
+ $element_data = $this->add_custom_field_to_element_data( $element_data, $this->product->id, isset( $translation->ID ) ? $translation->ID : false, false );
 
 
 
 
 
 
 
300
 
301
  if( $this->woocommerce_wpml->products->is_variable_product( $this->product->id ) ){
302
  $variations = $this->product->get_available_variations();
303
 
304
  if( !empty( $variations ) ){
305
  foreach( $variations as $variation ){
306
+ $element_data[ 'variation_desc'.$variation[ 'variation_id' ] ] = array( 'original' => strip_tags( $variation[ 'variation_description' ] ) );
307
+ $translated_variation_id = apply_filters( 'translate_object_id', $variation[ 'variation_id' ], 'product_variation', false, $this->get_target_language() );
308
+ $element_data[ 'variation_desc'.$variation[ 'variation_id' ] ][ 'translation' ] = $translated_variation_id ? get_post_meta( $translated_variation_id, '_variation_description', true ) : '';
309
+
310
+ $element_data = $this->add_custom_field_to_element_data( $element_data, $variation[ 'variation_id' ], $translated_variation_id, true );
311
  }
312
  }
313
  }
345
 
346
  return $element_data;
347
  }
348
+
349
+ public function add_custom_field_to_element_data( $element_data, $element_id, $translation_id, $is_variation = false ){
350
+ $custom_fields = $this->get_product_custom_fields_to_translate( $element_id );
351
+ if( $custom_fields ){
352
+ foreach( $custom_fields as $custom_field ) {
353
+ $orig_custom_field_values = get_post_meta( $element_id, $custom_field );
354
+ $trnsl_custom_field_values = array();
355
+ $trnsl_mid_ids = array();
356
+
357
+ if ( $translation_id ) {
358
+ $trnsl_custom_field_values = get_post_meta( $translation_id, $custom_field );
359
+ $trnsl_mid_ids = $this->woocommerce_wpml->products->get_mid_ids_by_key( $translation_id, $custom_field );
360
+ }
361
+
362
+ if( $is_variation ){
363
+ $custom_field .= $element_id;
364
+ }
365
+
366
+ foreach( $orig_custom_field_values as $val_key => $orig_custom_field_value ){
367
+ if( count( $orig_custom_field_values ) == 1 ){
368
+ $element_data[ $custom_field ] = array( 'original' => $orig_custom_field_value );
369
+ $element_data[ $custom_field ][ 'translation' ] = ( $translation_id && isset( $trnsl_custom_field_values[ $val_key ] ) ) ? $trnsl_custom_field_values[ $val_key ] : '';
370
+ }else{
371
+
372
+ $custom_field_key = $custom_field.':'. ( isset( $trnsl_mid_ids[ $val_key ] ) ? $trnsl_mid_ids[ $val_key ] : 'new_'. $val_key );
373
+
374
+ $element_data[ $custom_field ][ $custom_field_key ] = array( 'original' => $orig_custom_field_value );
375
+ $element_data[ $custom_field ][ $custom_field_key ][ 'translation' ] = ($translation_id && isset( $trnsl_custom_field_values[ $val_key ] ) ) ? $trnsl_custom_field_values[ $val_key ] : '';
376
+ }
377
+ }
378
+ }
379
+ }
380
+
381
+ return $element_data;
382
+ }
383
+
384
  public function save_translations( $translations ) {
385
  /** @var TranslationManagement $iclTranslationManagement */
386
  global $iclTranslationManagement;
581
  }
582
 
583
  //get product content labels
584
+ public function get_product_custom_field_label( $field, $variation_id = false )
585
  {
586
  global $sitepress;
587
  $settings = $sitepress->get_settings();
588
  $label = '';
589
+ if ( isset( $settings['translation-management']['custom_fields_translation'][ $field ] ) && $settings['translation-management']['custom_fields_translation'][ $field ] == WPML_TRANSLATE_CUSTOM_FIELD ) {
590
  if ( in_array( $field, $this->not_display_fields_for_variables_product, true ) ) {
591
  return false;
592
  }
605
  $custom_key_label = str_replace('_', ' ', $field);
606
  $label = trim($custom_key_label[0]) ? ucfirst($custom_key_label) : ucfirst(substr($custom_key_label, 1));
607
 
608
+ if( $variation_id ){
609
+ $label .= ' #'.$variation_id;
610
+ }
611
+
612
  }
613
 
614
  return $label;
645
  $contents = array();
646
 
647
  foreach( get_post_custom_keys( $product_id ) as $meta_key ) {
648
+ if ( isset( $settings['translation-management']['custom_fields_translation'][ $meta_key ] ) && $settings['translation-management']['custom_fields_translation'][ $meta_key ] == WPML_TRANSLATE_CUSTOM_FIELD ) {
649
  if( $this->check_custom_field_is_single_value( $product_id, $meta_key ) ){
650
  if ( in_array( $meta_key, apply_filters( 'wcml_not_display_single_fields_to_translate', $this->not_display_fields_for_variables_product ), true ) ) {
651
  continue;
inc/translation-editor/class-wcml-synchronize-product-data.php CHANGED
@@ -408,28 +408,24 @@ class WCML_Synchronize_Product_Data{
408
 
409
  //duplicate product post meta
410
  public function duplicate_product_post_meta( $original_product_id, $trnsl_product_id, $data = false , $add = false ){
411
- $settings = $this->sitepress->get_settings();
 
412
  $all_meta = get_post_custom( $original_product_id );
 
 
413
  unset( $all_meta[ '_thumbnail_id' ] );
414
 
415
  foreach ( $all_meta as $key => $meta ) {
416
- if (
417
- !isset( $settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] ) ||
418
- $settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] == 0
419
- ) {
420
  continue;
421
  }
422
  foreach ( $meta as $meta_value ) {
423
  if( $key == '_downloadable_files' ){
424
  $this->woocommerce_wpml->downloadable->sync_files_to_translations( $original_product_id, $trnsl_product_id, $data );
425
  }elseif ( $data ) {
426
- if (
427
- isset( $data[ md5( $key ) ] ) &&
428
- isset( $settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] ) &&
429
- $settings[ 'translation-management' ][ 'custom_fields_translation' ][ $key ] == 2 ) {
430
- $meta_value = $data[ md5( $key ) ];
431
- $meta_value = apply_filters( 'wcml_meta_value_before_add', $meta_value, $key );
432
- update_post_meta( $trnsl_product_id, $key, $meta_value );
433
  }
434
  }
435
  }
@@ -438,6 +434,42 @@ class WCML_Synchronize_Product_Data{
438
  do_action( 'wcml_after_duplicate_product_post_meta', $original_product_id, $trnsl_product_id, $data );
439
  }
440
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  public function woocommerce_duplicate_product( $new_id, $post ){
442
  $duplicated_products = array();
443
 
@@ -465,6 +497,14 @@ class WCML_Synchronize_Product_Data{
465
  $this->sitepress->set_element_language_details( $new_id, 'post_' . $post->post_type, $new_trid, $this->sitepress->get_current_language() );
466
  }
467
  }
 
 
 
 
 
 
 
 
468
  $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
469
  $duplicated_products[ 'translations' ] = array();
470
  if( $translations ){
408
 
409
  //duplicate product post meta
410
  public function duplicate_product_post_meta( $original_product_id, $trnsl_product_id, $data = false , $add = false ){
411
+ global $iclTranslationManagement;
412
+ $settings = $iclTranslationManagement->settings[ 'custom_fields_translation' ];
413
  $all_meta = get_post_custom( $original_product_id );
414
+ $post_fields = null;
415
+
416
  unset( $all_meta[ '_thumbnail_id' ] );
417
 
418
  foreach ( $all_meta as $key => $meta ) {
419
+ if ( !isset( $settings[ $key ] ) || $settings[ $key ] == WPML_IGNORE_CUSTOM_FIELD ) {
 
 
 
420
  continue;
421
  }
422
  foreach ( $meta as $meta_value ) {
423
  if( $key == '_downloadable_files' ){
424
  $this->woocommerce_wpml->downloadable->sync_files_to_translations( $original_product_id, $trnsl_product_id, $data );
425
  }elseif ( $data ) {
426
+ if ( isset( $settings[ $key ] ) && $settings[ $key ] == WPML_TRANSLATE_CUSTOM_FIELD ) {
427
+
428
+ $post_fields = $this->sync_custom_field_value( $key, $data, $trnsl_product_id, $post_fields );
 
 
 
 
429
  }
430
  }
431
  }
434
  do_action( 'wcml_after_duplicate_product_post_meta', $original_product_id, $trnsl_product_id, $data );
435
  }
436
 
437
+ public function sync_custom_field_value( $custom_field, $translation_data, $trnsl_product_id, $post_fields, $original_product_id = false, $is_variation = false ){
438
+
439
+ if( is_null( $post_fields ) ){
440
+ $post_fields = array();
441
+ if( isset( $_POST['data'] ) ){
442
+ $post_args = wp_parse_args( $_POST['data'] );
443
+ $post_fields = $post_args[ 'fields' ];
444
+ }
445
+ }
446
+
447
+
448
+ $custom_filed_key = $is_variation && $original_product_id ? $custom_field.$original_product_id : $custom_field;
449
+
450
+ if( isset( $translation_data[ md5( $custom_filed_key ) ] ) ){
451
+ $meta_value = $translation_data[ md5( $custom_filed_key ) ];
452
+ $meta_value = apply_filters( 'wcml_meta_value_before_add', $meta_value, $custom_filed_key );
453
+ update_post_meta( $trnsl_product_id, $custom_field, $meta_value );
454
+ unset( $post_fields[ $custom_filed_key ] );
455
+ }else{
456
+ foreach( $post_fields as $post_field_key => $post_field ){
457
+ $meta_value = $translation_data[ md5( $post_field_key ) ];
458
+ $field_key = explode( ':', $post_field_key );
459
+ if( $field_key[0] == $custom_filed_key ){
460
+ if( substr( $field_key[1], 0, 3 ) == 'new' ){
461
+ add_post_meta( $trnsl_product_id, $custom_field, $meta_value );
462
+ }else{
463
+ update_meta( $field_key[1], $custom_field, $meta_value );
464
+ }
465
+ unset( $post_fields[ $post_field_key ] );
466
+ }
467
+ }
468
+ }
469
+
470
+ return $post_fields;
471
+ }
472
+
473
  public function woocommerce_duplicate_product( $new_id, $post ){
474
  $duplicated_products = array();
475
 
497
  $this->sitepress->set_element_language_details( $new_id, 'post_' . $post->post_type, $new_trid, $this->sitepress->get_current_language() );
498
  }
499
  }
500
+
501
+ // Set language info for variations
502
+ if ( $children_products = get_children( 'post_parent=' . $new_orig_id . '&post_type=product_variation' ) ) {
503
+ foreach ( $children_products as $child ) {
504
+ $this->sitepress->set_element_language_details( $child->ID, 'post_product_variation', false, $orig_lang );
505
+ }
506
+ }
507
+
508
  $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
509
  $duplicated_products[ 'translations' ] = array();
510
  if( $translations ){
inc/translation-editor/class-wcml-synchronize-variations-data.php CHANGED
@@ -82,6 +82,8 @@ class WCML_Synchronize_Variations_Data{
82
  $all_taxs = get_object_taxonomies( 'product_variation' );
83
 
84
  foreach( $get_all_post_variations as $k => $post_data ) {
 
 
85
  // Find if this has already been duplicated
86
  $variation_id = $this->wpdb->get_var(
87
  $this->wpdb->prepare(
@@ -91,9 +93,9 @@ class WCML_Synchronize_Variations_Data{
91
  AND tr.language_code = %s
92
  AND pm.meta_key = '_wcml_duplicate_of_variation'
93
  AND pm.meta_value = %d",
94
- $lang, $post_data->ID )
95
  );
96
- $trid = $this->sitepress->get_element_trid( $post_data->ID, 'post_product_variation' );
97
  if( !empty( $variation_id ) && !is_null( $variation_id ) ) {
98
  // Update variation
99
  wp_update_post( array(
@@ -148,21 +150,21 @@ class WCML_Synchronize_Variations_Data{
148
  'post_mime_type' => $post_data->post_mime_type,
149
  'comment_count' => $post_data->comment_count
150
  ));
151
- add_post_meta( $variation_id, '_wcml_duplicate_of_variation', $post_data->ID );
152
  $this->sitepress->set_element_language_details( $variation_id, 'post_product_variation', $trid, $lang );
153
  }
154
  //sync media
155
- $this->woocommerce_wpml->media->sync_thumbnail_id( $post_data->ID, $variation_id, $lang );
156
  //sync file_paths
157
- $this->woocommerce_wpml->downloadable->sync_files_to_translations( $post_data->ID, $variation_id, $data );
158
  //sync description
159
- if( isset( $data[ md5( 'variation_desc'.$post_data->ID ) ] ) ){
160
- update_post_meta( $variation_id, '_variation_description', $data[ md5( 'variation_desc'.$post_data->ID ) ] );
161
  }
162
  // sync taxonomies
163
  if ( !empty( $all_taxs ) ) {
164
  foreach ( $all_taxs as $tt ) {
165
- $terms = get_the_terms( $post_data->ID, $tt );
166
  if ( !empty( $terms ) ) {
167
  $tax_sync = array();
168
  foreach ( $terms as $term ) {
@@ -190,10 +192,10 @@ class WCML_Synchronize_Variations_Data{
190
  $tr_product_id )
191
  );
192
  // Delete variations that no longer exist
193
- foreach( $get_current_post_variations as $key => $post_data ){
194
- $variation_id = get_post_meta( $post_data->ID, '_wcml_duplicate_of_variation', true );
195
- if( !in_array( $variation_id, $duplicated_post_variation_ids ) ){
196
- wp_delete_post( $post_data->ID, true );
197
  unset( $get_current_post_variations[ $key ] );
198
  }
199
  }
@@ -201,8 +203,8 @@ class WCML_Synchronize_Variations_Data{
201
  $cf = (array)$sitepress_settings[ 'translation-management' ][ 'custom_fields_translation' ];
202
  // synchronize post variations post meta
203
  $current_post_variation_ids = array();
204
- foreach( $get_current_post_variations as $k => $post_data ){
205
- $current_post_variation_ids[] = $post_data->ID;
206
  }
207
  // refresh parent-children transients
208
  delete_transient( 'wc_product_children_' . $tr_product_id );
@@ -231,7 +233,9 @@ class WCML_Synchronize_Variations_Data{
231
  }
232
  }
233
 
 
234
  foreach( $get_all_post_meta as $k => $post_meta ){
 
235
  $meta_key = $post_meta->meta_key;
236
  $meta_value = maybe_unserialize( $post_meta->meta_value );
237
  // update current post variations meta
@@ -297,6 +301,11 @@ class WCML_Synchronize_Variations_Data{
297
  $meta_value = get_post_meta( $duplicated_post_variation_ids[ $dp_key ], $meta_key, true );
298
  update_post_meta( $current_post_variation_ids[ $dp_key ], $meta_key, $meta_value );
299
  }
 
 
 
 
 
300
  }
301
  }
302
  }
82
  $all_taxs = get_object_taxonomies( 'product_variation' );
83
 
84
  foreach( $get_all_post_variations as $k => $post_data ) {
85
+ $original_variation_id = $post_data->ID;
86
+
87
  // Find if this has already been duplicated
88
  $variation_id = $this->wpdb->get_var(
89
  $this->wpdb->prepare(
93
  AND tr.language_code = %s
94
  AND pm.meta_key = '_wcml_duplicate_of_variation'
95
  AND pm.meta_value = %d",
96
+ $lang, $original_variation_id )
97
  );
98
+ $trid = $this->sitepress->get_element_trid( $original_variation_id, 'post_product_variation' );
99
  if( !empty( $variation_id ) && !is_null( $variation_id ) ) {
100
  // Update variation
101
  wp_update_post( array(
150
  'post_mime_type' => $post_data->post_mime_type,
151
  'comment_count' => $post_data->comment_count
152
  ));
153
+ add_post_meta( $variation_id, '_wcml_duplicate_of_variation', $original_variation_id );
154
  $this->sitepress->set_element_language_details( $variation_id, 'post_product_variation', $trid, $lang );
155
  }
156
  //sync media
157
+ $this->woocommerce_wpml->media->sync_thumbnail_id( $original_variation_id, $variation_id, $lang );
158
  //sync file_paths
159
+ $this->woocommerce_wpml->downloadable->sync_files_to_translations( $original_variation_id, $variation_id, $data );
160
  //sync description
161
+ if( isset( $data[ md5( 'variation_desc'.$original_variation_id ) ] ) ){
162
+ update_post_meta( $variation_id, '_variation_description', $data[ md5( 'variation_desc'.$original_variation_id ) ] );
163
  }
164
  // sync taxonomies
165
  if ( !empty( $all_taxs ) ) {
166
  foreach ( $all_taxs as $tt ) {
167
+ $terms = get_the_terms( $original_variation_id, $tt );
168
  if ( !empty( $terms ) ) {
169
  $tax_sync = array();
170
  foreach ( $terms as $term ) {
192
  $tr_product_id )
193
  );
194
  // Delete variations that no longer exist
195
+ foreach( $get_current_post_variations as $key => $current_post_variation ){
196
+ $orig_variation_id = get_post_meta( $current_post_variation->ID, '_wcml_duplicate_of_variation', true );
197
+ if( !in_array( $orig_variation_id, $duplicated_post_variation_ids ) ){
198
+ wp_delete_post( $current_post_variation->ID, true );
199
  unset( $get_current_post_variations[ $key ] );
200
  }
201
  }
203
  $cf = (array)$sitepress_settings[ 'translation-management' ][ 'custom_fields_translation' ];
204
  // synchronize post variations post meta
205
  $current_post_variation_ids = array();
206
+ foreach( $get_current_post_variations as $k => $current_post_variation ){
207
+ $current_post_variation_ids[] = $current_post_variation->ID;
208
  }
209
  // refresh parent-children transients
210
  delete_transient( 'wc_product_children_' . $tr_product_id );
233
  }
234
  }
235
 
236
+ $post_fields = null;
237
  foreach( $get_all_post_meta as $k => $post_meta ){
238
+
239
  $meta_key = $post_meta->meta_key;
240
  $meta_value = maybe_unserialize( $post_meta->meta_value );
241
  // update current post variations meta
301
  $meta_value = get_post_meta( $duplicated_post_variation_ids[ $dp_key ], $meta_key, true );
302
  update_post_meta( $current_post_variation_ids[ $dp_key ], $meta_key, $meta_value );
303
  }
304
+
305
+ if( isset( $cf[ $meta_key ] ) && $cf[ $meta_key ] == WPML_TRANSLATE_CUSTOM_FIELD ){
306
+ //sync custom fields
307
+ $post_fields = $this->woocommerce_wpml->sync_product_data->sync_custom_field_value( $meta_key, $data, $variation_id, $post_fields, $original_variation_id, true );
308
+ }
309
  }
310
  }
311
  }
inc/wcml-core-functions.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @return bool
5
+ *
6
+ * @since 3.8.3
7
+ */
8
+ function wcml_is_multi_currency_on(){
9
+ global $woocommerce_wpml;
10
+
11
+ if( is_null( $woocommerce_wpml ) ){
12
+ return false;
13
+ }
14
+
15
+ return $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT;
16
+ }
locale/woocommerce-multilingual-ar.po DELETED
@@ -1,1214 +0,0 @@
1
- # This file was generated by WPML
2
- # WPML is a WordPress plugin that can turn any WordPress site into a full featured multilingual content management system.
3
- # https://wpml.org
4
- msgid ""
5
- msgstr "Content-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: 8bit\nProject-Id-Version:WPML_EXPORT\nPOT-Creation-Date: \nPO-Revision-Date: \nLast-Translator: \nLanguage-Team: \nLanguage:en\nMIME-Version: 1.0\n"
6
-
7
- msgid "Introduction"
8
- msgstr "مقدمة"
9
-
10
- msgid "Store Pages"
11
- msgstr "صفحات المتجر"
12
-
13
- msgid "Global Attributes"
14
- msgstr "السمات الشاملة"
15
-
16
- msgid "Multiple Currencies"
17
- msgstr "عملات متعددة"
18
-
19
- msgid "Translation Interface"
20
- msgstr "واجهة الترجمة"
21
-
22
- msgid "Ready!"
23
- msgstr "مستعد!"
24
-
25
- msgid "Welcome to %sWooCommerce Multilingual!%s Please take a moment to configure the main settings and then you are ready to start translating your products."
26
- msgstr "مرحبًا بك مع %sWooCommerce متعدد اللغات!%s برجاء تكوين الإعدادات الأساسية، وبعدها ستكون جاهزًا للبدء في ترجمة منتجاتك."
27
-
28
- msgid "Action failed. Please refresh the page and retry."
29
- msgstr "فشل الإجراء. برجاء إعادة تحميل الصفحة وإعادة المحاولة."
30
-
31
- msgid "Cheatin&#8217; huh?"
32
- msgstr "أتغش&#8217; حقًا؟"
33
-
34
- msgid "Run the Setup Wizard"
35
- msgstr "بدء معالج الإعداد"
36
-
37
- msgid "Skip Setup"
38
- msgstr "تخطي الإعداد"
39
-
40
- msgid "WooCommerce Multilingual &rsaquo; Setup Wizard"
41
- msgstr "WooCommerce متعدد اللغات &rsaquo; معالج الإعداد"
42
-
43
- msgid "WooCommerce Multilingual"
44
- msgstr "WooCommerce متعدد اللغات"
45
-
46
- msgid "How to translate products"
47
- msgstr "كيفية ترجمة المنتجات"
48
-
49
- msgid "Quick edit is disabled for product translations. It's recommended to use the %s for editing products translations. %s"
50
- msgstr "التحرير السريع معطل لترجمات المنتج. من الموصى به استخدام %s لتحرير ترجمات المنتجات. %s"
51
-
52
- msgid "WooCommerce Multilingual products editor"
53
- msgstr "محرر منتجات WooCommerce متعدد اللغات"
54
-
55
- msgid "Edit this product translation"
56
- msgstr "تحرير ترجمة المنتج هذه"
57
-
58
- msgid "How to translate attributes"
59
- msgstr "كيفية ترجمة السمات"
60
-
61
- msgid "How to translate product categories"
62
- msgstr "كيفية ترجمة فئات المنتج"
63
-
64
- msgid "The recommended way to translate WooCommerce products is using the\n %sWooCommerce Multilingual products translation%s page.\n Please use this page only for translating elements that are not available in the WooCommerce Multilingual products translation table."
65
- msgstr "الطريقة الموصى بها لترجمة منتجات WooCommerce تكون باستخدم صفحة\n %sترجمة منتجات WooCommerce متعدد اللغات%s.\n برجاء استخدام هذه الصفحة فقط لترجمة العناصر غير المتاحة في جدول ترجمة منتجات WooCommerce متعدد اللغات."
66
-
67
- msgid "In order to edit custom attributes you need to use the <a href=\"%s\">custom product translation editor</a>"
68
- msgstr "كي يمكنك تحرير السمات المخصصة، فأنت في حاجة إلى استخدام <a href=\"%s\">المحرر المخصص لترجمة المنتجات</a>"
69
-
70
- msgid "You are using the same value as for the regular category base. This is known to create conflicts resulting in urls not working properly."
71
- msgstr "أنت تستخدم نفس القيمة التي تستخدمها لقاعدة الفئة العادية. هذا معروف لإنشاء التعارضات الناتجة في المسارات التي لا تعمل كما ينبغي."
72
-
73
- msgid "translations"
74
- msgstr "ترجمات"
75
-
76
- msgid "product"
77
- msgstr "منتج"
78
-
79
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML</a> versions prior %s."
80
- msgstr "WooCommerce Multilingual ممكّن ولكنه غير مفعّل. غير متوافق مع إصدارات <a href=\"%s\">WPML</a> السابقة لـ %s."
81
-
82
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">Woocommerce</a> versions prior %s."
83
- msgstr "WooCommerce متعدد اللغات مُمكّن ولكنه غير فعال. فهو غير متوافق مع إصدارات <a href=\"%s\">Woocommerce</a> التي تسبق %s."
84
-
85
- msgid "You are using WooCommerce Multilingual %s. This version includes an important UI redesign for the configuration screens and it requires <a href=\"%s\">WPML %s</a> or higher. Everything still works on the front end now but, in order to configure options for WooCommerce Multilingual, you need to upgrade WPML."
86
- msgstr "أنت تستخدم WooCommerce متعدد اللغات %s. هذه الإصدار يشتمل على إعادة تصميم هامة لواجهة المستخدم لشاشات التكوين، وهو ما يتطلب الإصدار <a href=\"%s\">WPML %s</a> أو أعلى. كل شيء ما زال يعمل على الواجهة الأمامية الآن، ولكن لتكوين الخيارات لـ WooCommerce متعدد اللغات، فأنت في حاجة إلى ترقية WPML."
87
-
88
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML Translation Management</a> versions prior %s."
89
- msgstr "WooCommerce Multilingual ممكّن ولكنه غير مفعّل. غير متوافق مع إصدارات <a href=\"%s\">إدارة ترجمة WPML</a> السابقة لـ %s."
90
-
91
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML String Translation</a> versions prior %s."
92
- msgstr "WooCommerce Multilingual ممكّن ولكنه غير مفعّل. غير متوافق مع إصدارات <a href=\"%s\">ترجمة متسلسلات WPML</a> السابقة لـ %s."
93
-
94
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML Media</a> versions prior %s."
95
- msgstr "WooCommerce Multilingual ممكّن ولكنه غير مفعّل. غير متوافق مع إصدارات <a href=\"%s\">WPML ميديا</a> السابقة لـ %s."
96
-
97
- msgid "and"
98
- msgstr "و"
99
-
100
- msgid "WooCommerce Multilingual is enabled but not effective. It requires %s in order to work."
101
- msgstr "WooCommerce Multilingual ممكّن ولكن غير فعّال. يحتاج إلى %s ليعمل."
102
-
103
- msgid "Permalink settings"
104
- msgstr "إعدادات الرابط الثابت"
105
-
106
- msgid "Configure products slug translation"
107
- msgstr "تهيئة ترجمة الارتباط الثابت للمنتجات"
108
-
109
- msgid "If you want different slugs for shop pages (%s/%s), you need to disable the shop prefix for products in <a href=\"%s\">WooCommerce Settings</a>"
110
- msgstr "إذا كنت ترغب في روابط لطيفة مختلفة لصفحات السوق (%s/%s)، فأنت في حاجة لتعطيل بادئة السوق للمنتجات في <a href=\"%s\">إعدادات WooCommerce</a>"
111
-
112
- msgid "Finished! You can visit the %sstrings translation%s screen to translate the strings now."
113
- msgstr "تم الإنجاز! يمكنك زيارة شاشة %sترجمة المتسلسلات%s لترجمة المتسلسلات الآن."
114
-
115
- msgid "wpml-config.xml file missing from WooCommerce Multilingual folder."
116
- msgstr "ملف wpml-config.xml مفقود من مجلد WooCommerce متعدد اللغات."
117
-
118
- msgid "Custom field %s configuration from wpml-config.xml file was altered!"
119
- msgstr "تم تغيير تهيئة الحقل المخصص %s من الملف wpml-config.xml!"
120
-
121
- msgid "Custom type %s configuration from wpml-config.xml file was altered!"
122
- msgstr "تم تغيير تهيئة النوع المخصص %s من الملف wpml-config.xml!"
123
-
124
- msgid "Custom taxonomy %s configuration from wpml-config.xml file was altered!"
125
- msgstr "تم تغيير تهيئة التصنيف المخصص %s من الملف wpml-config.xml!"
126
-
127
- msgid "Upgrade WPML"
128
- msgstr "ترقية WPML"
129
-
130
- msgid "Invalid language parameter: %s"
131
- msgstr "معيار لغة غير صالح: %s"
132
-
133
- msgid "Source product id not found: %s"
134
- msgstr "لم يتم العثور على معرف هوية المنتج الأساسي: %s"
135
-
136
- msgid "Product Base"
137
- msgstr "قاعدة المنتج"
138
-
139
- msgid "Product Tag Base"
140
- msgstr "قاعدة علامة المنتج"
141
-
142
- msgid "Product Category Base"
143
- msgstr "قاعدة فئة المنتج"
144
-
145
- msgid "Product Attribute Base"
146
- msgstr "قاعدة سمة المنتج"
147
-
148
- msgid "Endpoint: %s"
149
- msgstr "نقطة النهاية: %s"
150
-
151
- msgid "product-category"
152
- msgstr "product-category"
153
-
154
- msgid "product-tag"
155
- msgstr "product-tag"
156
-
157
- msgid "Original language"
158
- msgstr "اللغة الأصلية"
159
-
160
- msgid "Take this and edit"
161
- msgstr "قبول هذا والتحرير"
162
-
163
- msgid "Add translation"
164
- msgstr "إضافة ترجمة"
165
-
166
- msgid "Update translation"
167
- msgstr "تحديث الترجمة"
168
-
169
- msgid "Finish translating"
170
- msgstr "إنهاء الترجمة"
171
-
172
- msgid "Edit translation"
173
- msgstr "تحرير الترجمة"
174
-
175
- msgid "Edit this item inline"
176
- msgstr "تحرير هذا العنصر بشكلٍ مضمن"
177
-
178
- msgid "Quick Edit"
179
- msgstr "التحرير السريع"
180
-
181
- msgid "Translation in progress"
182
- msgstr "الترجمة قيد التنفيذ"
183
-
184
- msgid "Invalid nonce"
185
- msgstr "nonce غير صالح"
186
-
187
- msgid "Currency - no orders found"
188
- msgstr "العملة - لم يتم العثور على أي طلبات"
189
-
190
- msgid "Currencies order updated"
191
- msgstr "تم تحديث ترتيب العملات"
192
-
193
- msgid "Currency switcher"
194
- msgstr "محوّل العملة"
195
-
196
- msgid "Configure options"
197
- msgstr "تهيئة الخيارات"
198
-
199
- msgid "Settings saved!"
200
- msgstr "تم حفظ الإعدادات!"
201
-
202
- msgid "Add new currency"
203
- msgstr "إضافة عملة جديدة"
204
-
205
- msgid "Update currency"
206
- msgstr "تحديث العملة"
207
-
208
- msgid "Update settings for %s"
209
- msgstr "تحديث الإعدادات لـ %s"
210
-
211
- msgid "The default currency was changed. In order to show accurate prices in all currencies, you need to update the exchange rates under the %sMulti-currency%s configuration."
212
- msgstr "لقد تغيرت العملة الافتراضية. لعرض الأسعار الدقيقة بجميع العملات، فأنت في حاجة إلى تحدث أسعار الصرف في قائمة التكوين %sالعملات المتعددة%s."
213
-
214
- msgid "All the products will be removed from the current order in order to change the currency"
215
- msgstr "ستتم إزالة جميع المنتجات من الطلب الحالي كي يتم تغيير العملة"
216
-
217
- msgid "Show all currencies"
218
- msgstr "عرض جميع العملات"
219
-
220
- msgid "Order currency:"
221
- msgstr "عملة الطلب:"
222
-
223
- msgid "Cart"
224
- msgstr "سلة الشراء"
225
-
226
- msgid "Checkout"
227
- msgstr "المعاينة"
228
-
229
- msgid "Checkout &rarr; Pay"
230
- msgstr "المعاينة &rarr; الدفع"
231
-
232
- msgid "Order Received"
233
- msgstr "تم استلام طلب الشراء"
234
-
235
- msgid "My Account"
236
- msgstr "حسابي"
237
-
238
- msgid "Change Password"
239
- msgstr "تغيير كلمة المرور"
240
-
241
- msgid "Edit My Address"
242
- msgstr "تعديل عنواني"
243
-
244
- msgid "Logout"
245
- msgstr "تسجيل الخروج"
246
-
247
- msgid "Lost Password"
248
- msgstr "كلمة المرور مفقودة"
249
-
250
- msgid "View Order"
251
- msgstr "عرض طلب الشراء"
252
-
253
- msgid "Shop"
254
- msgstr "السوق"
255
-
256
- msgid "All the products will be removed from the current order in order to change the language"
257
- msgstr "ستتم إزالة جميع المنتجات من الطلب الحالي كي يتم تغيير اللغة"
258
-
259
- msgid "Order language:"
260
- msgstr "لغة الطلب:"
261
-
262
- msgid "Choose a file"
263
- msgstr "اختر ملف"
264
-
265
- msgid "At least one of these fields is required: title, content or excerpt"
266
- msgstr "هناك حقل واحد على الأقل مطلوب من هذه الحقول: العنوان، أو المحتوى، أو الاقتباس"
267
-
268
- msgid "This translation job will no longer be assigned to you. Other translators will be able take it and continue the translation."
269
- msgstr "لن يتم تعيين مهمة الترجمة هذه إليك بعد الآن. سيكون بمقدور المترجمين الآخرين التقدم لها ومتابعة الترجمة."
270
-
271
- msgid "This field is locked for editing because WPML will copy its value from the original language."
272
- msgstr "هذا الحقل ممنوع من التحرير لأن WPML سيقوم بنسخ قيمته من اللغة الأصلية."
273
-
274
- msgid "This is a translation of %s. Some of the fields are not editable. It's recommended to use the %s for translating products."
275
- msgstr "هذه ترجمة لـ %s. بعض الحقول غير قابلة للتحرير. من الموصى به استخدام %s لترجمة المنتجات."
276
-
277
- msgid "WooCommerce Multilingual products translator"
278
- msgstr "مترجم منتجات WooCommerce متعدد اللغات"
279
-
280
- msgid "Looks like you are upgrading from a previous version of WooCommerce Multilingual. Would you like to automatically create translated variations and images?"
281
- msgstr "يبدو أنك في مرحلة الترقية من نسخة قديمة لـ WooCommerce متعدد اللغات. هل ترغب في القيام تلقائيًا بإنشاء أنواع وصور مترجمة؟"
282
-
283
- msgid "Yes, go to the troubleshooting page"
284
- msgstr "نعم، اذهب إلى صفحة استكشاف الأخطاء وإصلاحها"
285
-
286
- msgid "No - dismiss"
287
- msgstr "لا - تجاهل"
288
-
289
- msgid "You've successfully installed %sWooCommerce Multilingual%s. Would you like to see a quick overview?"
290
- msgstr "لقد قمت بتثبيت %sWooCommerce متعدد اللغات%s بنجاح. هل ترغب في مشاهدة معاينة سريعة؟"
291
-
292
- msgid "Learn how to turn your e-commerce site multilingual"
293
- msgstr "تعرف على كيفية تحويل موقع التجارة الإلكترونية الخاص بك إلى متعدد اللغات"
294
-
295
- msgid "Dismiss"
296
- msgstr "رفض"
297
-
298
- msgid "To translate %s please use the %s translation%s page, inside the %sWooCommerce Multilingual admin%s."
299
- msgstr "لترجمة %s برجاء استخدام صفحة %s الترجمة%s، داخل %sلوحة مدير WooCommerce متعددة اللغات%s."
300
-
301
- msgid "%s do not require translation."
302
- msgstr "%s لا يحتاج لترجمة."
303
-
304
- msgid "Include to translation"
305
- msgstr "الإدراج للترجمة"
306
-
307
- msgid "%d %s are missing translations."
308
- msgstr "%d %s تفتقر إلى الترجمات."
309
-
310
- msgid "Translate %s"
311
- msgstr "ترجم %s"
312
-
313
- msgid "Exclude from translation"
314
- msgstr "الاستثناء من الترجمة"
315
-
316
- msgid "All %s are translated."
317
- msgstr "جميع %s مترجمة."
318
-
319
- msgid "Currently, there are %s variations that need to be created."
320
- msgstr "حاليًا، هناك %s نوعًا تحتاج للإنشاء."
321
-
322
- msgid "%d products left"
323
- msgstr "%d منتجات باقية"
324
-
325
- msgid "Synchronization complete!"
326
- msgstr "اكتملت المزامنة!"
327
-
328
- msgid "Invalid taxonomy %s"
329
- msgstr "تصنيف غير صالح %s"
330
-
331
- msgid "Some translated %s have different %s assignments."
332
- msgstr "بعض %s المترجمة بها مهام %s مختلفة."
333
-
334
- msgid "Update %s for all translated %s"
335
- msgstr "تحديث %s لجميع %s المترجمة"
336
-
337
- msgid "All %s have the same %s assignments."
338
- msgstr "جميع %s لها نفس مهام %s."
339
-
340
- msgid "Successfully updated %s for all translated %s."
341
- msgstr "تم تحديث %s بنجاح لجميع %s المترجمة."
342
-
343
- msgid "Synchronize attributes and update product variations"
344
- msgstr "مزامنة السمات وتحديث أنواع المنتج"
345
-
346
- msgid "Image"
347
- msgstr "صورة"
348
-
349
- msgid "Product"
350
- msgstr "المنتج"
351
-
352
- msgid "Type"
353
- msgstr "نوع"
354
-
355
- msgid "Date"
356
- msgstr "تاريخ"
357
-
358
- msgid "Categories"
359
- msgstr "فئات"
360
-
361
- msgid "No products found"
362
- msgstr "لم يتم العثور على منتجات"
363
-
364
- msgid "Draft"
365
- msgstr "مسودة"
366
-
367
- msgid "Private"
368
- msgstr "خاص"
369
-
370
- msgid "Pending"
371
- msgstr "معلّق"
372
-
373
- msgid "Scheduled"
374
- msgstr "مجدول"
375
-
376
- msgid "Parent product: %s"
377
- msgstr "المنتج الرئيسي: %s"
378
-
379
- msgid "Edit this item"
380
- msgstr "تحرير هذا العنصر"
381
-
382
- msgid "Edit"
383
- msgstr "تحرير"
384
-
385
- msgid "View \"%s\""
386
- msgstr "عرض \"%s\""
387
-
388
- msgid "View"
389
- msgstr "استعرض"
390
-
391
- msgid "Published"
392
- msgstr "نُشر"
393
-
394
- msgid "Last Modified"
395
- msgstr "آخر تعديل"
396
-
397
- msgid "All languages"
398
- msgstr "جميع اللغات"
399
-
400
- msgid "All categories"
401
- msgstr "كل الفئات"
402
-
403
- msgid "All translation statuses"
404
- msgstr "كل حالات الترجمة"
405
-
406
- msgid "Not translated or needs updating"
407
- msgstr "لم تُترجم أو تحتاج إلى تحديث"
408
-
409
- msgid "Needs updating"
410
- msgstr "يحتاج للتحديث"
411
-
412
- msgid "Translation complete"
413
- msgstr "الترجمة اكتملت"
414
-
415
- msgid "All statuses"
416
- msgstr "جميع الحالات"
417
-
418
- msgid "Filter"
419
- msgstr "تصفية"
420
-
421
- msgid "Reset"
422
- msgstr "إعادة ضبط"
423
-
424
- msgid "Search"
425
- msgstr "بحث"
426
-
427
- msgid "%d items"
428
- msgstr "%d عناصر"
429
-
430
- msgid "Go to the first page"
431
- msgstr "الذهاب إلى الصفحة الأولى"
432
-
433
- msgid "Go to the previous page"
434
- msgstr "الذهاب إلى الصفحة السابقة"
435
-
436
- msgid "Select Page"
437
- msgstr "حدد الصفحة"
438
-
439
- msgid "Current page"
440
- msgstr "الصفحة الحالية"
441
-
442
- msgid "of"
443
- msgstr "من"
444
-
445
- msgid "Go to the next page"
446
- msgstr "الذهاب إلى الصفحة التالية"
447
-
448
- msgid "Go to the last page"
449
- msgstr "الذهاب إلى الصفحة الأخيرة"
450
-
451
- msgid "Translatable?"
452
- msgstr "قابل للترجمة؟"
453
-
454
- msgid "Enable this if you want to translate attribute values with Woocommerce Multilingual"
455
- msgstr "قم بتمكين هذا إذا كنت ترغب في ترجمة قيم السمة باستخدام Woocommerce متعدد اللغات"
456
-
457
- msgid "Existing translations and variations associated will be deleted."
458
- msgstr "سيتم حذف الترجمات والمتغيرات الحالية ذات الصلة."
459
-
460
- msgid "Product Translation Interface"
461
- msgstr "واجهة ترجمة المنتج"
462
-
463
- msgid "The recommended way is using the WPML Translation Editor. It is streamlined for making the translation process much easier while also providing a much better integration with various WooCommerce extensions."
464
- msgstr "الطريقة الموصى بها هي استخدام محرر WPML للترجمة. فهو انسيابي لجعل عملية الترجمة أكثر سهولة، بالإضافة إلى توفير تكامل أفضل بكثير مع امتدادات WooCommerce المتعددة."
465
-
466
- msgid "WPML Translation Editor"
467
- msgstr "محرر WPML للترجمة"
468
-
469
- msgid "Native WooCommerce product editing screen"
470
- msgstr "شاشة تحرير منتج WooCommerce الأصلية"
471
-
472
- msgid "Products synchronization"
473
- msgstr "مزامنة المنتجات"
474
-
475
- msgid "Configure specific product properties that should be synced to translations."
476
- msgstr "تهيئة الخصائص المحددة للمنتج والتي تجب مزامنتها إلى الترجمات."
477
-
478
- msgid "Sync publishing date for translated products."
479
- msgstr "مزامنة تاريخ النشر للمنتجات المترجمة."
480
-
481
- msgid "Sync products and product taxonomies order."
482
- msgstr "مزامنة ترتيب المنتجات وتصانيف المنتج."
483
-
484
- msgid "Products Download Files"
485
- msgstr "ملفات تنزيل المنتجات"
486
-
487
- msgid "If you are using downloadable products, you can choose to have their paths\n synchronized, or seperate for each language."
488
- msgstr "إذا كنت تستخدم منتجات قابلة للتنزيل، يمكنك اختيار مزامنة\n مساراتهم، أو فصلها لكل لغة."
489
-
490
- msgid "Use the same files for translations"
491
- msgstr "استخدم نفس الملفات للترجمات"
492
-
493
- msgid "Add separate download files for translations"
494
- msgstr "إضافة ملفات تنزيل منفصلة للترجمات"
495
-
496
- msgid "Save changes"
497
- msgstr "حفظ التغييرات"
498
-
499
- msgid "Troubleshooting page"
500
- msgstr "صفحة استكشاف الأخطاء وإصلاحها"
501
-
502
- msgid "Update Translation"
503
- msgstr "تحديث الترجمة"
504
-
505
- msgid "Hide This Message"
506
- msgstr "إخفاء هذه الرسالة"
507
-
508
- msgid "<strong>WooCommerce Translation Available</strong> &#8211; Install or update your <code>%s</code> translations to version <code>%s</code>."
509
- msgstr "<strong>ترجمة WooCommerce متاح</strong> &#8211; تثبيت أو تحديث ترجمات <code>%s</code> الخاصة بك إلى الإصدار <code>%s</code>."
510
-
511
- msgid "This will automatically generate variations for translated products corresponding to recently translated attributes."
512
- msgstr "سيقوم هذا تلقائيًا بإنشاء متغيرات للمنتجات المترجمة المتوافقة مع السمات المترجمة مؤخرًا."
513
-
514
- msgid "Synchronize %s assignment in content"
515
- msgstr "مزامنة مهمة %s في المحتوى"
516
-
517
- msgid "This action lets you automatically apply the %s taxonomy to your content in different languages. It will scan the original content and apply the same taxonomy to translated content."
518
- msgstr "يسمح لك هذا الإجراء بتطبيق تصنيف %s تلقائيًا إلى محتوياتك في لغاتك المختلفة. سيقوم بعمل استكشاف للمحتوى الأصلي وتطبيق نفس التصنيف إلى المحتوى المترجم."
519
-
520
- msgid "You have untranslated terms!"
521
- msgstr "لديك مصطلحات غير مترجمة!"
522
-
523
- msgid "Select currency"
524
- msgstr "حدد العملة"
525
-
526
- msgid "Exchange Rate"
527
- msgstr "أسعار صرف العملات"
528
-
529
- msgid "Only numeric"
530
- msgstr "رقمي فقط"
531
-
532
- msgid "Set on %s"
533
- msgstr "ضبط على %s"
534
-
535
- msgid "Currency Preview"
536
- msgstr "معاينة العملة"
537
-
538
- msgid "Currency Position"
539
- msgstr "وضع العملة"
540
-
541
- msgid "Left"
542
- msgstr "يسار"
543
-
544
- msgid "Right"
545
- msgstr "يمين"
546
-
547
- msgid "Left with space"
548
- msgstr "يسار مع مسافة"
549
-
550
- msgid "Right with space"
551
- msgstr "يمين مع مسافة"
552
-
553
- msgid "Thousand Separator"
554
- msgstr "فاصل الآلاف"
555
-
556
- msgid "Decimal Separator"
557
- msgstr "فاصل الكسور العشرية"
558
-
559
- msgid "Number of Decimals"
560
- msgstr "عدد الكسور العشرية"
561
-
562
- msgid "Rounding to the nearest integer"
563
- msgstr "التقريب حتى أقرب عدد صحيح"
564
-
565
- msgid "Disabled"
566
- msgstr "معطل"
567
-
568
- msgid "Up"
569
- msgstr "أعلى"
570
-
571
- msgid "Down"
572
- msgstr "أسفل"
573
-
574
- msgid "Nearest"
575
- msgstr "الأقرب"
576
-
577
- msgid "Increment for nearest integer"
578
- msgstr "الإضافة حتى أقرب عدد صحيح"
579
-
580
- msgid "Autosubtract amount"
581
- msgstr "قيمة الطرح التلقائي"
582
-
583
- msgid "Cancel"
584
- msgstr "الغ"
585
-
586
- msgid "Save"
587
- msgstr "حفظ"
588
-
589
- msgid "Products"
590
- msgstr "المنتجات"
591
-
592
- msgid "Tags"
593
- msgstr "روابط ذكية"
594
-
595
- msgid "Attributes"
596
- msgstr "السمات"
597
-
598
- msgid "Shipping Classes"
599
- msgstr "أصناف الشحن"
600
-
601
- msgid "Settings"
602
- msgstr "إعدادات"
603
-
604
- msgid "Multi-currency"
605
- msgstr "العملات المتعددة"
606
-
607
- msgid "Store URLs"
608
- msgstr "مسارات المتجر"
609
-
610
- msgid "Status"
611
- msgstr "الحالة"
612
-
613
- msgid "Troubleshooting"
614
- msgstr "حل المشكلات"
615
-
616
- msgid "Thank you for using %sWooCommerce Multilingual%s! You can express your love and\n support by %s rating our plugin and saying that %sit works%s for you."
617
- msgstr "شكرًا لاستخدامك %sملحق WooCommerce متعدد اللغات %s! يمكنك التعبير عن حبك\n ودعمك عن طريق %sتقييم ملحقاتنا والتعبير عن %sعملها%s معك."
618
-
619
- msgid "Hide"
620
- msgstr "إخفاء"
621
-
622
- msgid "Loading ..."
623
- msgstr "قيد التحميل..."
624
-
625
- msgid "Regular Price"
626
- msgstr "السعر العادي"
627
-
628
- msgid "Sale Price"
629
- msgstr "سعر البيع"
630
-
631
- msgid "Multi-currency is enabled but no secondary currencies have been set. %sAdd secondary currencies%s."
632
- msgstr "العملات المتعددة مُمكّنة، ولكن لم يتم تعيين عملات ثانوية. %sإضافة العملات الثانوية%s."
633
-
634
- msgid "Calculate prices in other currencies automatically"
635
- msgstr "حساب الأسعار بالعملات الأخرى تلقائيًا"
636
-
637
- msgid "Click to see the prices in the other currencies as they are currently shown on the front end."
638
- msgstr "انقر لاستعراض الأسعار بالعملات الأخرى كما هي معروضة حاليًا على الواجهة الأمامية."
639
-
640
- msgid "Show"
641
- msgstr "عرض"
642
-
643
- msgid "Set prices in other currencies manually"
644
- msgstr "ضبط الأسعار بالعملات الأخرى يدويًا"
645
-
646
- msgid "Enter prices in other currencies"
647
- msgstr "إدخال الأسعار بالعملات الأخرى"
648
-
649
- msgid "Hide prices in other currencies"
650
- msgstr "إخفاء الأسعار بالعملات الأخرى"
651
-
652
- msgid "Determined automatically based on exchange rate"
653
- msgstr "تحديد تلقائي وفقًا لأسعار الصرف"
654
-
655
- msgid "Schedule"
656
- msgstr "جدول الأعمال"
657
-
658
- msgid "Same as default currency"
659
- msgstr "مثل العملة الافتراضية"
660
-
661
- msgid "Set dates"
662
- msgstr "ضبط التواريخ"
663
-
664
- msgid "Collapse"
665
- msgstr "طي"
666
-
667
- msgid "From&hellip;"
668
- msgstr "من&hellip;"
669
-
670
- msgid "To&hellip;"
671
- msgstr "إلى&hellip;"
672
-
673
- msgid "Please enter in a value less than the regular price"
674
- msgstr "برجاء إدخال قيمة أقل من السعر المعتاد"
675
-
676
- msgid "Required plugins"
677
- msgstr "الملحقات المطلوبة"
678
-
679
- msgid "Plugins Status"
680
- msgstr "حالة الملحقات"
681
-
682
- msgid "WooCommerce Multilingual depends on several plugins to work. If any required plugin is missing, you should install and activate it."
683
- msgstr "يعتمد WooCommerce متعدد اللغات على العديد من الملحقات لكي يعمل. إذا كان أحد هذه الملحقات غير موجود، فيجب عليك تثبيته وتفعيله."
684
-
685
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML</a> versions prior 2.0.5."
686
- msgstr "WooCommerce Multilingual ممكّن ولكن غير فعّال. غير متوافق مع نسخ <a href=\"%s\">WPML</a> الأقدم من 2.0.5."
687
-
688
- msgid "Update WPML"
689
- msgstr "تحديث WPML"
690
-
691
- msgid "Get WPML"
692
- msgstr "احصل على WPML"
693
-
694
- msgid "Get WPML Media"
695
- msgstr "احصل على WPML Media"
696
-
697
- msgid "Get WPML Translation Management"
698
- msgstr "احصل على إدارة ترجمة WPML"
699
-
700
- msgid "Get WPML String Translation"
701
- msgstr "احصل على WPML String Translation"
702
-
703
- msgid "%s is installed and active."
704
- msgstr "%s مثبت ونشط."
705
-
706
- msgid "%s is set up."
707
- msgstr "%s تم إعداده."
708
-
709
- msgid "%s is not set up."
710
- msgstr "%s لم يتم إعداده."
711
-
712
- msgid "%s is either not installed or not active."
713
- msgstr "%s إما أنه غير مثبت أو غير نشط."
714
-
715
- msgid "%1$s is installed, but with incorrect version. You need %1$s %2$s or higher. "
716
- msgstr "%1$s مثبت، ولكن بنسخة خاطئة. تحتاج إلى نسخة %1$s %2$s أو أعلى."
717
-
718
- msgid "Download WooCommerce"
719
- msgstr "تحميل WooCommerce"
720
-
721
- msgid "The WordPress Multilingual Plugin"
722
- msgstr "ملحق WordPress متعدد اللغات"
723
-
724
- msgid "This page allows you to translate all strings that are being used by WooCommerce in building different type of urls. Translating them enables you to have fully localized urls that match the language of the pages."
725
- msgstr "تسمح لك هذه الصفحة بترجمة جميع النصوص التي تستخدم بواسطة WooCommerce في بناء الأنواع المختلفة من المسارات. ترجمتهم ستجعلك تمتلك مسارات مترجمة بالكامل تتوافق مع لغة الصفحات."
726
-
727
- msgid "You can enter or edit your default values on the %sPermalinks settings%s page or, for the endpoints, on the WooCommerce %sAccount settings%s page."
728
- msgstr "يمكنك إدخال أو تحرير قيمك الافتراضية في صفحة %sإعدادات الروابط الثابتة%s، أو بالنسبة لنقاط النهاية في صفحة %sإعدادات حساب%s WooCommerce."
729
-
730
- msgid "permalinks settings"
731
- msgstr "إعدادات الارتباطات الثابتة"
732
-
733
- msgid "Account settings"
734
- msgstr "إعدادات الحساب"
735
-
736
- msgid "Slug type"
737
- msgstr "نوع الارتباط الثابت"
738
-
739
- msgid "Original Slug"
740
- msgstr "الارتباط الثابت الأصلي"
741
-
742
- msgid "Shop page"
743
- msgstr "صفحة المتجر"
744
-
745
- msgid "Product base"
746
- msgstr "قاعدة المنتج"
747
-
748
- msgid "Product category base"
749
- msgstr "قاعدة فئة المنتج"
750
-
751
- msgid "Product tag base"
752
- msgstr "قاعدة علامة المنتج"
753
-
754
- msgid "Product attribute base"
755
- msgstr "قاعدة سمة المنتج"
756
-
757
- msgid "Original"
758
- msgstr "الأصل"
759
-
760
- msgid "Translation to"
761
- msgstr "الترجمة إلى"
762
-
763
- msgid "Product Shop Base"
764
- msgstr "قاعدة متجر المنتج"
765
-
766
- msgid "Welcome to WooCommerce Multilingual!"
767
- msgstr "مرحبًا بك مع WooCommerce متعدد اللغات!"
768
-
769
- msgid "Configure the multilingual support for your e-commerce site in just a couple of minutes."
770
- msgstr "قم بتكوين الدعم متعدد اللغات لموقع التجارة الإلكترونية الخاص بك في عدة دقائق فقط."
771
-
772
- msgid "By default, the products are translatable just like product categories, product tags and attributes. So you can start translating these right away."
773
- msgstr "بشكلٍ افتراضي، المنتجات قابلة للترجمة مثل فئات المنتج، وعلامات المنتج، والسمات. بحيث يمكنك البدء في ترجمتها على الفور."
774
-
775
- msgid "You can configure, however, which attributes you want to translate, install the translated shop pages or enable the multi-currency mode."
776
- msgstr "مع ذلك، يمكنك تكوين السمات التي ترغب في ترجمتها، أو تثبيت صفحات المتجر المترجمة، تمكين وضع العملات المتعددة."
777
-
778
- msgid "Start"
779
- msgstr "بداية"
780
-
781
- msgid "No, thanks. I'll do it later."
782
- msgstr "لا، شكرًا. سأفعل ذلك لاحقًا."
783
-
784
- msgid "Select translatable attributes"
785
- msgstr "حدد السمات القابلة للترجمة"
786
-
787
- msgid "There are no attributes defined"
788
- msgstr "لم يتم تعيين سمات"
789
-
790
- msgid "Continue"
791
- msgstr "استمر"
792
-
793
- msgid "Later"
794
- msgstr "لاحقًا"
795
-
796
- msgid "One or more WooCommerce pages have not been created"
797
- msgstr "لم يتم إنشاء صفحة أو عدة صفحات من WooCommerce"
798
-
799
- msgid "Install missing WooCommerce pages and create translations."
800
- msgstr "تثبيت صفحات WooCommerce المفقودة وإنشاء الترجمات."
801
-
802
- msgid "Translate Store Pages"
803
- msgstr "ترجمة صفحات المتجر"
804
-
805
- msgid "All store pages must be translated in the languages configured on the site."
806
- msgstr "ينبغي ترجمة جميع صفحات المتجر باللغات التي تم تكوينها على الموقع."
807
-
808
- msgid "Select the translation interface"
809
- msgstr "حدد واجهة الترجمة"
810
-
811
- msgid "Enable multiple currencies"
812
- msgstr "تمكين العملات المتعددة"
813
-
814
- msgid "This will allow you to set prices for products in different currencies. The prices can be determined based on a given exchange rate or set explicitly for specific products."
815
- msgstr "سيسمح لك ذلك بتعيين الأسعار للمنتجات بعملات مختلفة. يمكن تحديد الأسعار بحسب سعر الصرف المدخل أو المحدد بوضوح لمنتجات بعينها."
816
-
817
- msgid "Enable the multi-currency mode"
818
- msgstr "تمكين وضع العملات المتعددة"
819
-
820
- msgid "Further actions that are necessary for making your existing content multilingual, are listed below."
821
- msgstr "ستجد الإجراءات الأخرى اللازمة لجعل محتواك الحالي متعدد اللغات مدرجة أدناه."
822
-
823
- msgid "Start translating products"
824
- msgstr "بدء ترجمة المنتجات"
825
-
826
- msgid "Add secondary currencies on the %smulti-currency configuration%s page"
827
- msgstr "أضف العملات الثانوية في صفحة %sتكوين العملات المتعددة%s"
828
-
829
- msgid "Translate existing terms for these %sproduct attributes%s: %s"
830
- msgstr "ترجم المصطلحات الحالية %sلسمات المنتج%s هذه: %s"
831
-
832
- msgid "Translate existing %sproduct categories%s"
833
- msgstr "ترجمة %sفئات المنتج%s الحالية"
834
-
835
- msgid "Translate existing %sproduct tags%s"
836
- msgstr "ترجمة %sعلامات المنتج%s الحالية"
837
-
838
- msgid "%sAdd missing translations%s for shipping classes"
839
- msgstr "%sإضافة الترجمات المفقودة%s لفئات الشحن"
840
-
841
- msgid "Translate %sURL slugs%s to create multilingual store and product urls"
842
- msgstr "ترجمة %sالارتباطات الثابتة للمسارات%s لإنشاء متجر متعدد اللغات ومسارات للمنتج"
843
-
844
- msgid "Use custom settings for translations download files"
845
- msgstr "استخدام الإعدادات المخصصة لملفات تنزيل الترجمات"
846
-
847
- msgid "WooCommerce Store Pages"
848
- msgstr "صفحات متجر WooCommerce"
849
-
850
- msgid "To run a multilingual e-commerce site, you need to have the WooCommerce shop pages translated to all the site's languages. Once all the pages are installed you can add the translations for them from this menu."
851
- msgstr "لتشغيل موقع تجارة إلكترونية متعدد اللغات، فأنت في حاجة إلى ترجمة صفحات متجر WooCommerce إلى جميع لغات الموقع. ما أن يتم تثبيت جميع الصفحات، يمكنك إضافة الترجمات لهم من هذه القائمة."
852
-
853
- msgid "One or more WooCommerce pages have not been created."
854
- msgstr "لم يتم إنشاء صفحة WooCommerce أو أكثر."
855
-
856
- msgid "Install WooCommerce Pages"
857
- msgstr "تثبيت صفحات WooCommerce"
858
-
859
- msgid "WooCommerce store pages do not exist for these languages:"
860
- msgstr "صفحات متجر WooCommerce غير موجودة لهذه اللغات:"
861
-
862
- msgid "Create missing translations"
863
- msgstr "إنشاء الترجمات المفقودة"
864
-
865
- msgid "These pages are currently being translated by translators via WPML: "
866
- msgstr "هذه الصفحات يتم ترجمتها حاليًا بواسطة مترجمين عبر WPML:"
867
-
868
- msgid "WooCommerce store pages are translated to all the site's languages."
869
- msgstr "صفحات متجر WooCommerce مترجمة لجميع لغات الموقع."
870
-
871
- msgid "Configuration warnings"
872
- msgstr "تحذيرات التهيئة"
873
-
874
- msgid "Reporting miscelaneous configuration issues that can make WooCommerce Multilingual not run normally"
875
- msgstr "الإبلاغ عن مسائل التهيئة المتنوعة التي قد تجعل WooCommerce Multilingual يعمل بشكلٍ غير طبيعي"
876
-
877
- msgid "Your product permalink base is not translated to:"
878
- msgstr "قاعدة الارتباط الثابت لمنتجك غير مترجمة إلى:"
879
-
880
- msgid "Translate URLs"
881
- msgstr "ترجمة المسارات"
882
-
883
- msgid "Your site's default language is not English and the strings language is also not English."
884
- msgstr "اللغة الافتراضية لموقعك ليست اللغة الإنجليزية، ولغة النصوص أيضًا ليست اللغة الإنجليزية."
885
-
886
- msgid "Running WooCommerce multilingual with default language other than English."
887
- msgstr "جارٍ تشغيل WooCommerce متعدد اللغات بلغة افتراضية غير اللغة الإنجليزية."
888
-
889
- msgid "This may cause problems with URLs in different languages."
890
- msgstr "قد يتسبب هذا في مشاكل مع المسارات بلغات مختلفة."
891
-
892
- msgid "Change default language"
893
- msgstr "تغيير اللغة الافتراضية"
894
-
895
- msgid "Your site's default language is not English."
896
- msgstr "اللغة الافتراضية لموقعك ليست اللغة الإنجليزية."
897
-
898
- msgid "There are some settings that require careful attention."
899
- msgstr "هناك بعض الإعدادات التي تحتاج إلى انتباه تام."
900
-
901
- msgid "Some settings from the WooCommerce Multilingual wpml-config.xml file have been overwritten."
902
- msgstr "تم استبدال بعض الإعدادات من ملف wpml-config.xml الخاص بـ WooCommerce متعدد اللغات."
903
-
904
- msgid "You should check WPML configuration files added by other plugins or manual settings on the %s section."
905
- msgstr "ينبغي عليك التحقق من ملفات تكوين WPML المضافة بواسطة الملحقات الأخرى أو الإعدادات اليدوية في قسم %s."
906
-
907
- msgid "Multilingual Content Setup"
908
- msgstr "إعداد محتوى متعدد اللغات"
909
-
910
- msgid "Taxonomies missing translations"
911
- msgstr "تصانيف الترجمات المفقودة"
912
-
913
- msgid "To run a fully translated site, you should translate all taxonomy terms. Some store elements, such as variations, depend on taxonomy translation."
914
- msgstr "لتشغيل موقع مترجم بالكامل، يجب عليك ترجمة جميع مصطلحات التصنيف. تعتمد بعض عناصر المتجر مثل أنواع المنتج على ترجمة التصنيف."
915
-
916
- msgid "This taxonomy requires translation."
917
- msgstr "هذا التصنيف يحتاج لترجمة."
918
-
919
- msgid "Include in translation"
920
- msgstr "التضمين في الترجمة"
921
-
922
- msgid "This taxonomy does not require translation."
923
- msgstr "هذا التصنيف لا يحتاج لترجمة."
924
-
925
- msgid "Right now, there are no taxonomy terms needing translation."
926
- msgstr "حاليًا، لا توجد مصطلحات تصنيف في حاجة للترجمة."
927
-
928
- msgid "There are no translatable product attributes defined"
929
- msgstr "لا توجد سمات منتج قابلة للترجمة تم تحديدها"
930
-
931
- msgid "Select the attribute to translate: "
932
- msgstr "حدد السمة المراد ترجمتها:"
933
-
934
- msgid "Please make a backup of your database before you start the synchronization"
935
- msgstr "برجاء عمل نسخة احتياطية من قاعدة البيانات الخاصة بك قبل بدء المزامنة"
936
-
937
- msgid "Sync variables products"
938
- msgstr "مزامنة منتجات المتغيرات"
939
-
940
- msgid "Update products count:"
941
- msgstr "تحديث عدد المنتجات:"
942
-
943
- msgid "products with variations"
944
- msgstr "منتجات ذات أنواع"
945
-
946
- msgid "Sync products variations:"
947
- msgstr "مزامنة أنواع المنتجات:"
948
-
949
- msgid "left"
950
- msgstr "باقٍ"
951
-
952
- msgid "Sync products \"gallery images\":"
953
- msgstr "مزامنة \"صور معرض\" المنتجات:"
954
-
955
- msgid "Sync products categories (display type, thumbnail):"
956
- msgstr "مزامنة فئات المنتج (عرض النوع، صورة مصغرة):"
957
-
958
- msgid "Duplicate terms ( please select attribute ):"
959
- msgstr "تكرار المصطلحات (برجاء تحديد سمة):"
960
-
961
- msgid "none"
962
- msgstr "لا"
963
-
964
- msgid "Enable/disable"
965
- msgstr "تمكين/تعطيل"
966
-
967
- msgid "Currencies"
968
- msgstr "العملات"
969
-
970
- msgid "Add currency"
971
- msgstr "إضافة عملة"
972
-
973
- msgid "Currency"
974
- msgstr "العملة"
975
-
976
- msgid "Rate"
977
- msgstr "السعر"
978
-
979
- msgid "default"
980
- msgstr "افتراضي"
981
-
982
- msgid "Default currency"
983
- msgstr "العملة الافتراضية"
984
-
985
- msgid "Switch to this currency when switching language in the front-end"
986
- msgstr "حوّل إلى هذه العملة عند تغيير اللغة في الواجهة الأمامية"
987
-
988
- msgid "Keep"
989
- msgstr "ثبات القيمة"
990
-
991
- msgid "Delete"
992
- msgstr "حذف"
993
-
994
- msgid " (%s)"
995
- msgstr "(%s)"
996
-
997
- msgid "The multi-currency mode cannot be enabled as a specific currency was not set. Go to the %sWooCommerce settings%s page and select the default currency for your store."
998
- msgstr "لا يمكن تمكين وضع العملات المتعددة حيث أنه لم يتم تعيين عملة معينة. اذهب إلى صفحة %sإعدادات WooCommerce%s وحدد العملة الافتراضية لمتجرك."
999
-
1000
- msgid "Learn more"
1001
- msgstr "تعلم المزيد"
1002
-
1003
- msgid "Show only products with custom prices in secondary currencies"
1004
- msgstr "عرض المنتجات المصحوبة بأسعار مخصصة فقط في العملات الفرعية"
1005
-
1006
- msgid "When this option is on, when you switch to a secondary currency on the front end, only the products with custom prices in that currency are being displayed. Products with prices determined based on the exchange rate are hidden."
1007
- msgstr "عند تفعيل هذا الخيار، فعند تحويلك إلى عملة فرعية على الواجهة الأمامية، فلن يتم عرض سوى المنتجات المصحوبة بأسعار مخصصة في تلك العملة. يتم إخفاء المنتجات المصحوبة بأسعار محددة وفقًا لسعر الصرف."
1008
-
1009
- msgid "The changes you made will be lost if you navigate away from this page."
1010
- msgstr "ستفقد التغييرات التي أجريتها إذا غادرت هذه الصفحة."
1011
-
1012
- msgid "At least one currency must be enabled for this language!"
1013
- msgstr "ينبغي تمكين عملة واحدة على الأقل لهذه اللغة!"
1014
-
1015
- msgid "Currency switcher options"
1016
- msgstr "خيارات محوّل العملة"
1017
-
1018
- msgid "Currency switcher style"
1019
- msgstr "نمط محوّل العملة"
1020
-
1021
- msgid "Currency order"
1022
- msgstr "ترتيب العملات"
1023
-
1024
- msgid "Available parameters"
1025
- msgstr "المعايير المتاحة"
1026
-
1027
- msgid "Template for currency switcher"
1028
- msgstr "نموذج لمحوّل العملة"
1029
-
1030
- msgid "Visibility"
1031
- msgstr "الظهور"
1032
-
1033
- msgid "Currency switcher preview"
1034
- msgstr "استعراض محوّل العملة"
1035
-
1036
- msgid "Drop-down menu"
1037
- msgstr "قائمة منزلقة"
1038
-
1039
- msgid "List of currencies"
1040
- msgstr "قائمة العملات"
1041
-
1042
- msgid "Vertical"
1043
- msgstr "رأسي"
1044
-
1045
- msgid "Horizontal"
1046
- msgstr "أفقي"
1047
-
1048
- msgid "Drag the currencies to change their order"
1049
- msgstr "قم بسحب العملات وتركها لتغيير ترتيبها"
1050
-
1051
- msgid "%name%, %symbol%, %code%"
1052
- msgstr "%name%, %symbol%, %code%"
1053
-
1054
- msgid "Default: %name% (%symbol%) - %code%"
1055
- msgstr "الافتراضي: %name% (%symbol%) - %code%"
1056
-
1057
- msgid "Show a currency selector on the product page template"
1058
- msgstr "عرض محدد العملة على قالب صفحة المنتج"
1059
-
1060
- msgid "To configure how the %sWooCommerce products%s are translated, visit the WooCommerce Multiligual %ssettings%s page."
1061
- msgstr "لتكوين طريقة ترجمة %sمنتجات WooCommerce%s، قم بزيارة صفحة %sإعدادات%s WooCommerce متعدد اللغات."
1062
-
1063
- msgid "Title"
1064
- msgstr "عنوان"
1065
-
1066
- msgid "Slug"
1067
- msgstr "الرابط اللطيف"
1068
-
1069
- msgid "Content / Description"
1070
- msgstr "المحتوى/الوصف"
1071
-
1072
- msgid "Excerpt"
1073
- msgstr "اقتباس"
1074
-
1075
- msgid "Purchase note"
1076
- msgstr "ملاحظة الشراء"
1077
-
1078
- msgid "Images"
1079
- msgstr "الصور"
1080
-
1081
- msgid "Custom Product attributes"
1082
- msgstr "سمات المنتج المخصصة"
1083
-
1084
- msgid "Name"
1085
- msgstr "الاسم"
1086
-
1087
- msgid "Value(s)"
1088
- msgstr "القيمة (القيم)"
1089
-
1090
- msgid "Custom Fields"
1091
- msgstr "الحقول المخصصة"
1092
-
1093
- msgid "Variations data"
1094
- msgstr "بيانات المتغيرات"
1095
-
1096
- msgid "Download Files for Variation #%s"
1097
- msgstr "ملفات التنزيل للمتغير #%s"
1098
-
1099
- msgid "Download Files"
1100
- msgstr "ملفات التنزيل"
1101
-
1102
- msgid "File URL"
1103
- msgstr "مسار الملف"
1104
-
1105
- msgid "Content, title, and excerpt are empty."
1106
- msgstr "المحتوى والعنوان والاقتباس فارغون."
1107
-
1108
- msgid "Search %s"
1109
- msgstr "البحث عن %s"
1110
-
1111
- msgid "All %s"
1112
- msgstr "جميع %s"
1113
-
1114
- msgid "Parent %s"
1115
- msgstr "%s الرئيسي"
1116
-
1117
- msgid "Parent %s:"
1118
- msgstr "%s الرئيسي:"
1119
-
1120
- msgid "Edit %s"
1121
- msgstr "تحرير %s"
1122
-
1123
- msgid "Update %s"
1124
- msgstr "تحديث %s"
1125
-
1126
- msgid "Add New %s"
1127
- msgstr "إضافة %s جديد"
1128
-
1129
- msgid "New %s"
1130
- msgstr "%s جديد"
1131
-
1132
- msgid "To translate Add-ons strings please save Add-ons and go to the <b><a href=\"%s\">String Translation interface</a></b>"
1133
- msgstr "لترجمة متسلسلات الملحقات، برجاء حفظ الملحقات والذهاب إلى <b><a href=\"%s\">واجهة ترجمة المتسلسلات</a></b>"
1134
-
1135
- msgid "Product Add-ons Group \"%s\""
1136
- msgstr "مجموعة ملحقات المنتج \"%s\""
1137
-
1138
- msgid "Description"
1139
- msgstr "وصف"
1140
-
1141
- msgid "Options"
1142
- msgstr "خيارات"
1143
-
1144
- msgid "Label"
1145
- msgstr "علامة"
1146
-
1147
- msgid "To translate Extra Options strings please save %s and go to the <b><a href=\"%s\">String Translation interface</a></b>"
1148
- msgstr "لترجمة متسلسلات الخيارات الإضافية، برجاء حفظ %s والذهاب إلى <b><a href=\"%s\">واجهة ترجمة المتسلسلات</a></b>"
1149
-
1150
- msgid "Language"
1151
- msgstr "لغة"
1152
-
1153
- msgid "Translation of"
1154
- msgstr "ترجمة"
1155
-
1156
- msgid "Subscription Price"
1157
- msgstr "سعر الاشتراك"
1158
-
1159
- msgid "Sign-up Fee"
1160
- msgstr "رسم التسجيل"
1161
-
1162
- msgid "Calculate costs in other currencies automatically"
1163
- msgstr "احتساب التكاليف بعملات أخرى تلقائيًا"
1164
-
1165
- msgid "Set costs in other currencies manually"
1166
- msgstr "تعيين التكاليف بعملات أخرى يدويًا"
1167
-
1168
- msgid "This is the cost per block booked. All other costs (for resources and persons) are added to this."
1169
- msgstr "هذه هي التكلفة لكل كتلة محجوزة. تتم إضافة جميع التكاليف الأخرى (للموارد والأشخاص) إلى هذه."
1170
-
1171
- msgid "Product tabs"
1172
- msgstr "علامات تبويب المنتج"
1173
-
1174
- msgid "Heading"
1175
- msgstr "رأس الصفحة"
1176
-
1177
- msgid "Tour Data"
1178
- msgstr "بيانات الجولة"
1179
-
1180
- msgid "Content"
1181
- msgstr "المحتوى"
1182
-
1183
- msgid "Composite Products"
1184
- msgstr "المنتجات المركبة"
1185
-
1186
- msgid "Product Bundles"
1187
- msgstr "حزم المنتج"
1188
-
1189
- msgid "One-off cost for the booking as a whole."
1190
- msgstr "تكلفة إجمالية تدفعها لمرة واحدة مقابل الحجز بأكمله."
1191
-
1192
- msgid "The cost is displayed to the user on the frontend. Leave blank to have it calculated for you. If a booking has varying costs, this will be prefixed with the word \"from:\"."
1193
- msgstr "يتم عرض التكلفة للمستخدم على الواجهة الأمامية. اترك الحقل فارغًا كي يتم احتسابها لك. إذا كان هناك حجز له تكاليف مختلفة، فسيتم وضع كلمة \"بدءًا من:\" أمامه."
1194
-
1195
- msgid "Bookings"
1196
- msgstr "الحجوزات"
1197
-
1198
- msgid "Resources Label"
1199
- msgstr "علامة الموارد"
1200
-
1201
- msgid "Resources"
1202
- msgstr "الموارد"
1203
-
1204
- msgid "Person Types"
1205
- msgstr "أنواع الشخص"
1206
-
1207
- msgid "Person Type Name"
1208
- msgstr "اسم نوع الشخص"
1209
-
1210
- msgid "Resources label"
1211
- msgstr "ملصق الموارد"
1212
-
1213
- msgid "Booking currency"
1214
- msgstr "عملة الحجز"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
locale/woocommerce-multilingual-de_DE.po DELETED
@@ -1,1214 +0,0 @@
1
- # This file was generated by WPML
2
- # WPML is a WordPress plugin that can turn any WordPress site into a full featured multilingual content management system.
3
- # https://wpml.org
4
- msgid ""
5
- msgstr "Content-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: 8bit\nProject-Id-Version:WPML_EXPORT\nPOT-Creation-Date: \nPO-Revision-Date: \nLast-Translator: \nLanguage-Team: \nLanguage:en\nMIME-Version: 1.0\n"
6
-
7
- msgid "Introduction"
8
- msgstr "Einleitung"
9
-
10
- msgid "Store Pages"
11
- msgstr "Store-Seiten"
12
-
13
- msgid "Global Attributes"
14
- msgstr "Globale Attribute"
15
-
16
- msgid "Multiple Currencies"
17
- msgstr "Mehrere Währungen"
18
-
19
- msgid "Translation Interface"
20
- msgstr "Übersetzungsoberfläche"
21
-
22
- msgid "Ready!"
23
- msgstr "Fertig!"
24
-
25
- msgid "Welcome to %sWooCommerce Multilingual!%s Please take a moment to configure the main settings and then you are ready to start translating your products."
26
- msgstr ""
27
-
28
- msgid "Action failed. Please refresh the page and retry."
29
- msgstr "Aktion fehlgeschlagen. Bitte aktualisieren Sie die Seite und versuchen Sie es erneut."
30
-
31
- msgid "Cheatin&#8217; huh?"
32
- msgstr "Wollen Sie etwa schummeln?"
33
-
34
- msgid "Run the Setup Wizard"
35
- msgstr "Einrichtungsassistent starten"
36
-
37
- msgid "Skip Setup"
38
- msgstr "Einrichtung überspringen"
39
-
40
- msgid "WooCommerce Multilingual &rsaquo; Setup Wizard"
41
- msgstr "WooCommerce Multilingual &rsaquo; Einrichtungsassistent"
42
-
43
- msgid "WooCommerce Multilingual"
44
- msgstr "WooCommerce Multilingual"
45
-
46
- msgid "How to translate products"
47
- msgstr "So übersetzen Sie Produkte"
48
-
49
- msgid "Quick edit is disabled for product translations. It's recommended to use the %s for editing products translations. %s"
50
- msgstr "Schnellbearbeitung ist für Produktübersetzungen deaktiviert. Wir empfehlen, für die Bearbeitung von Produktübersetzungen %s zu verwenden. %s"
51
-
52
- msgid "WooCommerce Multilingual products editor"
53
- msgstr "WooCommerce Multilingual-Produkteditor"
54
-
55
- msgid "Edit this product translation"
56
- msgstr "Diese Produktübersetzung bearbeiten"
57
-
58
- msgid "How to translate attributes"
59
- msgstr "So übersetzen Sie Attribute"
60
-
61
- msgid "How to translate product categories"
62
- msgstr "Sie übersetzen Sie Produktkategorien"
63
-
64
- msgid "The recommended way to translate WooCommerce products is using the\n %sWooCommerce Multilingual products translation%s page.\n Please use this page only for translating elements that are not available in the WooCommerce Multilingual products translation table."
65
- msgstr ""
66
-
67
- msgid "In order to edit custom attributes you need to use the <a href=\"%s\">custom product translation editor</a>"
68
- msgstr "Um benutzerdefinierte Attribute zu bearbeiten, müssen Sie den <a href=\"%s\">Übersetzungseditor für benutzerdefinierte</a> Produkte verwenden."
69
-
70
- msgid "You are using the same value as for the regular category base. This is known to create conflicts resulting in urls not working properly."
71
- msgstr "Sie benutzen denselben Wert wie für die reguläre Kategoriebasis. Dabei können Konflikte entstehen, die zu Funktionsfehlern in URLs führen."
72
-
73
- msgid "translations"
74
- msgstr "Übersetzungen"
75
-
76
- msgid "product"
77
- msgstr "Produkt"
78
-
79
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML</a> versions prior %s."
80
- msgstr "WooCommerce Multilingual ist effektiv, funktioniert aber nicht. Es ist nicht kompatibel mit früheren <a href=\"%s\">WPML</a>-Versionen als %s."
81
-
82
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">Woocommerce</a> versions prior %s."
83
- msgstr "WooCommerce Multilingual ist aktiviert, funktioniert aber nicht. Es ist nicht mit <a href=\"%s\">Woocommerce</a>-Versionen vor %s kompatibel."
84
-
85
- msgid "You are using WooCommerce Multilingual %s. This version includes an important UI redesign for the configuration screens and it requires <a href=\"%s\">WPML %s</a> or higher. Everything still works on the front end now but, in order to configure options for WooCommerce Multilingual, you need to upgrade WPML."
86
- msgstr "Sie verwenden WooCommerce Multilingual %s. Diese Version enthält eine wichtige Umgestaltung der Benutzeroberfläche für die Konfigurationsbildschirme und erfordert <a href=\"%s\">WPML %s</a> oder höher. Im Front-End funktioniert noch immer alles, aber um Optionen für WooCommerce Multilingual zu konfigurieren, müssen Sie WPML upgraden."
87
-
88
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML Translation Management</a> versions prior %s."
89
- msgstr "WooCommerce Multilingual ist aktiviert, funktioniert aber nicht. Es ist nicht kompatibel mit früheren Version von <a href=\"%s\">WPML Übersetzungsmanagement</a> als %s."
90
-
91
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML String Translation</a> versions prior %s."
92
- msgstr "WooCommerce Multilingual ist aktiviert, funktioniert aber nicht. Es ist nicht kompatibel mit früheren Versionen von <a href=\"%s\">WPML String Translation</a> als %s."
93
-
94
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML Media</a> versions prior %s."
95
- msgstr "WooCommerce Multilingual ist aktiviert, funktioniert aber nicht. Es ist nicht kompatibel mit früheren Version von <a href=\"%s\">WPML Media</a> als %s."
96
-
97
- msgid "and"
98
- msgstr "und"
99
-
100
- msgid "WooCommerce Multilingual is enabled but not effective. It requires %s in order to work."
101
- msgstr "WooCommerce Multilingual ist aktiviert, aber nicht aktiv. Es benötigt %s, um zu funktionieren."
102
-
103
- msgid "Permalink settings"
104
- msgstr "Permalink-Einstellungen"
105
-
106
- msgid "Configure products slug translation"
107
- msgstr "Produkt-Slug-Übersetzung konfigurieren"
108
-
109
- msgid "If you want different slugs for shop pages (%s/%s), you need to disable the shop prefix for products in <a href=\"%s\">WooCommerce Settings</a>"
110
- msgstr "Wenn Sie andere Slugs für Shop-Seiten haben wollen, (%s/%s), müssen Sie den Shop-Präfix für Produkte in den <a href=\"%s\">WooCommerce-Einstellungen</a> deaktivieren."
111
-
112
- msgid "Finished! You can visit the %sstrings translation%s screen to translate the strings now."
113
- msgstr "Fertig! Sie können jetzt den Bildschirm %sString-Übersetzung%s aufrufen, um die Strings zu übersetzen."
114
-
115
- msgid "wpml-config.xml file missing from WooCommerce Multilingual folder."
116
- msgstr "Die Datei wpml-config.xml fehlt im Ordner WooCommerce Multilingual."
117
-
118
- msgid "Custom field %s configuration from wpml-config.xml file was altered!"
119
- msgstr "Konfiguration des benutzerdefinierten Felds %s aus der Datei wpml-config.xml wurde geändert!"
120
-
121
- msgid "Custom type %s configuration from wpml-config.xml file was altered!"
122
- msgstr "Konfiguration des benutzerdefinierten Typs %s aus der Datei wpml-config.xml wurde geändert!"
123
-
124
- msgid "Custom taxonomy %s configuration from wpml-config.xml file was altered!"
125
- msgstr "Konfiguration der benutzerdefinierten Taxonomie %s aus der Datei wpml-config.xml wurde geändert!"
126
-
127
- msgid "Upgrade WPML"
128
- msgstr "WPML upgraden"
129
-
130
- msgid "Invalid language parameter: %s"
131
- msgstr "Ungültiger Sprachparameter: %s"
132
-
133
- msgid "Source product id not found: %s"
134
- msgstr "Quellprodukt-ID nicht gefunden: %s"
135
-
136
- msgid "Product Base"
137
- msgstr "Produktbasis"
138
-
139
- msgid "Product Tag Base"
140
- msgstr "Produkt-Tag-Basis"
141
-
142
- msgid "Product Category Base"
143
- msgstr "Produktkategoriebasis"
144
-
145
- msgid "Product Attribute Base"
146
- msgstr "Produktattributbasis"
147
-
148
- msgid "Endpoint: %s"
149
- msgstr "Endpunkt: %s"
150
-
151
- msgid "product-category"
152
- msgstr "Produktkategorie"
153
-
154
- msgid "product-tag"
155
- msgstr "Produkt-Tag"
156
-
157
- msgid "Original language"
158
- msgstr "Ausgangssprache"
159
-
160
- msgid "Take this and edit"
161
- msgstr "Annehmen und bearbeiten"
162
-
163
- msgid "Add translation"
164
- msgstr "Übersetzung hinzufügen"
165
-
166
- msgid "Update translation"
167
- msgstr "Übersetzung aktualisieren"
168
-
169
- msgid "Finish translating"
170
- msgstr "Übersetzung beenden"
171
-
172
- msgid "Edit translation"
173
- msgstr "Übersetzung bearbeiten"
174
-
175
- msgid "Edit this item inline"
176
- msgstr "Dieses Objekt inline bearbeiten"
177
-
178
- msgid "Quick Edit"
179
- msgstr "Schnellbearbeitung"
180
-
181
- msgid "Translation in progress"
182
- msgstr "Übersetzung wird ausgeführt"
183
-
184
- msgid "Invalid nonce"
185
- msgstr "Nonce ungültig"
186
-
187
- msgid "Currency - no orders found"
188
- msgstr "Währung - keine Reihenfolgen gefunden"
189
-
190
- msgid "Currencies order updated"
191
- msgstr "Währungsreihenfolge wurde aktualisiert"
192
-
193
- msgid "Currency switcher"
194
- msgstr "Währungsumschalter"
195
-
196
- msgid "Configure options"
197
- msgstr "Optionen konfigurieren"
198
-
199
- msgid "Settings saved!"
200
- msgstr "Einstellungen gespeichert!"
201
-
202
- msgid "Add new currency"
203
- msgstr "Neue Währung hinzufügen"
204
-
205
- msgid "Update currency"
206
- msgstr "Währung aktualisieren"
207
-
208
- msgid "Update settings for %s"
209
- msgstr "Einstellungen für %s aktualisieren"
210
-
211
- msgid "The default currency was changed. In order to show accurate prices in all currencies, you need to update the exchange rates under the %sMulti-currency%s configuration."
212
- msgstr "Die Standardwährung wurde geändert. Um in allen Währungen präzise Preise anzuzeigen, müssen Sie die Wechselkurse unter der Konfiguration %sMehrere Währungen%s aktualisieren."
213
-
214
- msgid "All the products will be removed from the current order in order to change the currency"
215
- msgstr "Alle Produkte werden aus dem aktuellen Ordner gelöscht, um die Währung zu ändern."
216
-
217
- msgid "Show all currencies"
218
- msgstr "Alle Währungen anzeigen"
219
-
220
- msgid "Order currency:"
221
- msgstr "Währungsreihenfolge:"
222
-
223
- msgid "Cart"
224
- msgstr "Einkaufswagen"
225
-
226
- msgid "Checkout"
227
- msgstr "Zur Kasse"
228
-
229
- msgid "Checkout &rarr; Pay"
230
- msgstr "Zur Kasse &rarr; zahlen"
231
-
232
- msgid "Order Received"
233
- msgstr "Auftrag erhalten"
234
-
235
- msgid "My Account"
236
- msgstr "Mein Account"
237
-
238
- msgid "Change Password"
239
- msgstr "Passwort ändern"
240
-
241
- msgid "Edit My Address"
242
- msgstr "Meine Adresse bearbeiten"
243
-
244
- msgid "Logout"
245
- msgstr "Ausloggen"
246
-
247
- msgid "Lost Password"
248
- msgstr "Passwort vergessen"
249
-
250
- msgid "View Order"
251
- msgstr "Auftrag anzeigen"
252
-
253
- msgid "Shop"
254
- msgstr "Shop"
255
-
256
- msgid "All the products will be removed from the current order in order to change the language"
257
- msgstr "Alle Produkte werden aus dem aktuellen Ordner entfernt, um die Sprache zu ändern"
258
-
259
- msgid "Order language:"
260
- msgstr "Sprachreihenfolge:"
261
-
262
- msgid "Choose a file"
263
- msgstr "Datei wählen"
264
-
265
- msgid "At least one of these fields is required: title, content or excerpt"
266
- msgstr "Mindestens eines dieser Felder muss ausgefüllt werden: Titel, Inhalt oder Auszug"
267
-
268
- msgid "This translation job will no longer be assigned to you. Other translators will be able take it and continue the translation."
269
- msgstr "Dieser Übersetzungsauftrag wird Ihnen nicht mehr zugeteilt. Andere Übersetzer werden ihn annehmen und die Übersetzung fortführen können."
270
-
271
- msgid "This field is locked for editing because WPML will copy its value from the original language."
272
- msgstr "Dieses Feld ist für die Bearbeitung gesperrt, da WPML seinen Wert aus der Originalsprache kopieren wird."
273
-
274
- msgid "This is a translation of %s. Some of the fields are not editable. It's recommended to use the %s for translating products."
275
- msgstr "Dies ist eine Übersetzung von %s. Einige der Felder sind nicht bearbeitbar. Wir empfehlen, für die Übersetzung der Produkte %s zu verwenden."
276
-
277
- msgid "WooCommerce Multilingual products translator"
278
- msgstr "WooCommerce Multilingual-Produktübersetzer"
279
-
280
- msgid "Looks like you are upgrading from a previous version of WooCommerce Multilingual. Would you like to automatically create translated variations and images?"
281
- msgstr "Scheinbar upgraden Sie von einer früheren Version von WooCommerce Multilingual. Möchten Sie automatisch übersetzte Variationen und Bilder erstellen?"
282
-
283
- msgid "Yes, go to the troubleshooting page"
284
- msgstr "Ja, zur Fehlerbehebungs-Seite gehen"
285
-
286
- msgid "No - dismiss"
287
- msgstr "Nein - verwerfen"
288
-
289
- msgid "You've successfully installed %sWooCommerce Multilingual%s. Would you like to see a quick overview?"
290
- msgstr "Sie haben erfolgreich %sWooCommerce Multilingual%s. installiert. Möchten Sie eine kurze Übersicht sehen?"
291
-
292
- msgid "Learn how to turn your e-commerce site multilingual"
293
- msgstr "Lernen Sie, wie Sie Ihre E-Commerce-Seite mehrsprachig machen"
294
-
295
- msgid "Dismiss"
296
- msgstr "Ausblenden"
297
-
298
- msgid "To translate %s please use the %s translation%s page, inside the %sWooCommerce Multilingual admin%s."
299
- msgstr "Um %s zu übersetzen, benutzen Sie bitte die %sÜbersetzungs-%s-Seite im %sWooCommerce Multilingual-Adminbereich%s."
300
-
301
- msgid "%s do not require translation."
302
- msgstr "%s erfordern keine Übersetzung."
303
-
304
- msgid "Include to translation"
305
- msgstr "In die Übersetzung einbeziehen"
306
-
307
- msgid "%d %s are missing translations."
308
- msgstr "In %d %s fehlen Übersetzungen."
309
-
310
- msgid "Translate %s"
311
- msgstr "%s übersetzen"
312
-
313
- msgid "Exclude from translation"
314
- msgstr "Aus der Übersetzung ausschließen"
315
-
316
- msgid "All %s are translated."
317
- msgstr "Alle %s sind übersetzt."
318
-
319
- msgid "Currently, there are %s variations that need to be created."
320
- msgstr "Aktuell müssen %s-Variationen erstellt werden."
321
-
322
- msgid "%d products left"
323
- msgstr "noch %d Produkte"
324
-
325
- msgid "Synchronization complete!"
326
- msgstr "Synchronisierung abgeschlossen!"
327
-
328
- msgid "Invalid taxonomy %s"
329
- msgstr "Ungültige Taxonomie %s"
330
-
331
- msgid "Some translated %s have different %s assignments."
332
- msgstr "Einige übersetzte %s haben verschiedene %s-Zuteilungen."
333
-
334
- msgid "Update %s for all translated %s"
335
- msgstr "%s für alle übersetzten %s aktualisieren"
336
-
337
- msgid "All %s have the same %s assignments."
338
- msgstr "%s haben die gleichen %s-Zuteilungen."
339
-
340
- msgid "Successfully updated %s for all translated %s."
341
- msgstr "%s für alle übersetzten %s erfolgreich aktualisiert."
342
-
343
- msgid "Synchronize attributes and update product variations"
344
- msgstr "Attribute synchronisieren und Produkt-Variationen aktualisieren"
345
-
346
- msgid "Image"
347
- msgstr "Bild"
348
-
349
- msgid "Product"
350
- msgstr "Produkt"
351
-
352
- msgid "Type"
353
- msgstr "Typ"
354
-
355
- msgid "Date"
356
- msgstr "Datum"
357
-
358
- msgid "Categories"
359
- msgstr "Kategorien"
360
-
361
- msgid "No products found"
362
- msgstr "Keine Produkte gefunden"
363
-
364
- msgid "Draft"
365
- msgstr "Entwurf"
366
-
367
- msgid "Private"
368
- msgstr "Privat"
369
-
370
- msgid "Pending"
371
- msgstr ""
372
-
373
- msgid "Scheduled"
374
- msgstr "Geplant"
375
-
376
- msgid "Parent product: %s"
377
- msgstr "Übergeordnetes Produkt: %s"
378
-
379
- msgid "Edit this item"
380
- msgstr "Dieses Objekt bearbeiten"
381
-
382
- msgid "Edit"
383
- msgstr "Bearbeiten"
384
-
385
- msgid "View \"%s\""
386
- msgstr "\"%s\" anzeigen"
387
-
388
- msgid "View"
389
- msgstr "Anzeigen"
390
-
391
- msgid "Published"
392
- msgstr "Veröffentlicht"
393
-
394
- msgid "Last Modified"
395
- msgstr "Datum der letzten Änderung"
396
-
397
- msgid "All languages"
398
- msgstr "Alle Sprachen"
399
-
400
- msgid "All categories"
401
- msgstr "Alle Kategorien"
402
-
403
- msgid "All translation statuses"
404
- msgstr "Alle Übersetzungsstatus"
405
-
406
- msgid "Not translated or needs updating"
407
- msgstr "Nicht übersetzt oder bedarf eines Updates"
408
-
409
- msgid "Needs updating"
410
- msgstr "Aktualisierung erforderlich"
411
-
412
- msgid "Translation complete"
413
- msgstr "Übersetzung abgeschlossen"
414
-
415
- msgid "All statuses"
416
- msgstr "Alle Statusanzeigen"
417
-
418
- msgid "Filter"
419
- msgstr "Filter"
420
-
421
- msgid "Reset"
422
- msgstr "Zurücksetzen"
423
-
424
- msgid "Search"
425
- msgstr "Suche"
426
-
427
- msgid "%d items"
428
- msgstr "%d Objekte"
429
-
430
- msgid "Go to the first page"
431
- msgstr "Zur ersten Seite gehen"
432
-
433
- msgid "Go to the previous page"
434
- msgstr "Zur vorherigen Seite gehen"
435
-
436
- msgid "Select Page"
437
- msgstr "Seite auswählen"
438
-
439
- msgid "Current page"
440
- msgstr "Aktuelle Seite"
441
-
442
- msgid "of"
443
- msgstr "von"
444
-
445
- msgid "Go to the next page"
446
- msgstr "Zur nächsten Seite gehen"
447
-
448
- msgid "Go to the last page"
449
- msgstr "Zur letzten Seite gehen"
450
-
451
- msgid "Translatable?"
452
- msgstr "Übersetzbar?"
453
-
454
- msgid "Enable this if you want to translate attribute values with Woocommerce Multilingual"
455
- msgstr "Aktivieren Sie dies, wenn Sie Attributwerte mit WooCommerce Multilingual übersetzen möchten."
456
-
457
- msgid "Existing translations and variations associated will be deleted."
458
- msgstr "Vorhandene Übersetzungen und damit verbundene Variationen werden gelöscht."
459
-
460
- msgid "Product Translation Interface"
461
- msgstr "Produkt-Übersetzungsoberfläche"
462
-
463
- msgid "The recommended way is using the WPML Translation Editor. It is streamlined for making the translation process much easier while also providing a much better integration with various WooCommerce extensions."
464
- msgstr "Die empfohlene Methode ist der Einsatz des WPML Translation Editor. Dieser ist so optimiert, dass er den Übersetzungsvoggang vereinfacht und zugleich bessere Integration in mehrere WooCommerce-Erweiterungen bietet."
465
-
466
- msgid "WPML Translation Editor"
467
- msgstr "WPML Translation Editor"
468
-
469
- msgid "Native WooCommerce product editing screen"
470
- msgstr "Nativer WooCommerce-Produktbearbeitungsbildschirm"
471
-
472
- msgid "Products synchronization"
473
- msgstr "Produkte-Synchronisierung"
474
-
475
- msgid "Configure specific product properties that should be synced to translations."
476
- msgstr "Konfigurieren Sie bestimmte Produktattribute, die in den Übersetzungen nicht synchronisiert werden sollen."
477
-
478
- msgid "Sync publishing date for translated products."
479
- msgstr "Veröffentlichungsdatum für übersetzte Produkte synchronisieren."
480
-
481
- msgid "Sync products and product taxonomies order."
482
- msgstr "Produkte und Produkt-Taxonomie-Reihenfolge synchronisieren."
483
-
484
- msgid "Products Download Files"
485
- msgstr "Produkte-Download-Dateien"
486
-
487
- msgid "If you are using downloadable products, you can choose to have their paths\n synchronized, or seperate for each language."
488
- msgstr "Wenn Sie heruntergeladene Produkte benutzen, können Sie die Pfade\n wahlweise synchronisieren oder für jede Sprache trennen."
489
-
490
- msgid "Use the same files for translations"
491
- msgstr "Dieselben Dateien für Übersetzungen benutzen"
492
-
493
- msgid "Add separate download files for translations"
494
- msgstr "Separate Download-Dateien für Übersetzungen hinzufügen"
495
-
496
- msgid "Save changes"
497
- msgstr "Änderungen speichern"
498
-
499
- msgid "Troubleshooting page"
500
- msgstr "Fehlerbehebungsseite"
501
-
502
- msgid "Update Translation"
503
- msgstr "Übersetzung aktualisieren"
504
-
505
- msgid "Hide This Message"
506
- msgstr "Diese Meldung ausblenden"
507
-
508
- msgid "<strong>WooCommerce Translation Available</strong> &#8211; Install or update your <code>%s</code> translations to version <code>%s</code>."
509
- msgstr "<strong>WooCommerce-Übersetzung verfügbar</strong> &#8211; Installieren oder aktualisieren Sie Ihre <code>%s</code> Übersetzungen auf die Version <code>%s</code>."
510
-
511
- msgid "This will automatically generate variations for translated products corresponding to recently translated attributes."
512
- msgstr "Dies wird automatisch Variationen für übersetzte Produkte erstellen, die den vor Kurzem übersetzten Attributen entsprechen."
513
-
514
- msgid "Synchronize %s assignment in content"
515
- msgstr "%s-Zuteilung im Inhalt synchronisieren"
516
-
517
- msgid "This action lets you automatically apply the %s taxonomy to your content in different languages. It will scan the original content and apply the same taxonomy to translated content."
518
- msgstr "Mit dieser Aktion können Sie die %s-Taxonomie automatisch auf Ihren Inhalt in verschiedenen Sprachen anwenden. Sie wird den Originalinhalt durchsuchen und die gleiche Taxonomie auf den übersetzten Inhalt anwenden."
519
-
520
- msgid "You have untranslated terms!"
521
- msgstr "Sie haben unübersetzte Begriffe!"
522
-
523
- msgid "Select currency"
524
- msgstr "Währung auswählen"
525
-
526
- msgid "Exchange Rate"
527
- msgstr "Wechselkurs"
528
-
529
- msgid "Only numeric"
530
- msgstr "Nur numerisch"
531
-
532
- msgid "Set on %s"
533
- msgstr "Einstellen auf %s"
534
-
535
- msgid "Currency Preview"
536
- msgstr "Währungsvorschau"
537
-
538
- msgid "Currency Position"
539
- msgstr "Währungsposition"
540
-
541
- msgid "Left"
542
- msgstr "Links"
543
-
544
- msgid "Right"
545
- msgstr "Rechts"
546
-
547
- msgid "Left with space"
548
- msgstr "Links mit Abstand "
549
-
550
- msgid "Right with space"
551
- msgstr "Rechts mit Abstand"
552
-
553
- msgid "Thousand Separator"
554
- msgstr "Tausenderpunkt"
555
-
556
- msgid "Decimal Separator"
557
- msgstr "Dezimaltrenner"
558
-
559
- msgid "Number of Decimals"
560
- msgstr "Anzahl der Dezimalstellen"
561
-
562
- msgid "Rounding to the nearest integer"
563
- msgstr "Rundung auf die nächste ganze Zahl"
564
-
565
- msgid "Disabled"
566
- msgstr "Deaktiviert"
567
-
568
- msgid "Up"
569
- msgstr "Hoch"
570
-
571
- msgid "Down"
572
- msgstr "Runter"
573
-
574
- msgid "Nearest"
575
- msgstr "Nächste"
576
-
577
- msgid "Increment for nearest integer"
578
- msgstr "Schrittweite bis zur nächsten ganzen Zahl"
579
-
580
- msgid "Autosubtract amount"
581
- msgstr "Betrag automatisch abziehen"
582
-
583
- msgid "Cancel"
584
- msgstr "Abbrechen"
585
-
586
- msgid "Save"
587
- msgstr "Speichern"
588
-
589
- msgid "Products"
590
- msgstr "Produkte"
591
-
592
- msgid "Tags"
593
- msgstr "Tags"
594
-
595
- msgid "Attributes"
596
- msgstr "Attribute"
597
-
598
- msgid "Shipping Classes"
599
- msgstr "Versandklassen"
600
-
601
- msgid "Settings"
602
- msgstr "Einstellungen"
603
-
604
- msgid "Multi-currency"
605
- msgstr "Mehrere Währungen"
606
-
607
- msgid "Store URLs"
608
- msgstr "Shop-URLs"
609
-
610
- msgid "Status"
611
- msgstr "Status"
612
-
613
- msgid "Troubleshooting"
614
- msgstr "Fehlerbehebung"
615
-
616
- msgid "Thank you for using %sWooCommerce Multilingual%s! You can express your love and\n support by %s rating our plugin and saying that %sit works%s for you."
617
- msgstr "Danke, dass Sie %sWooCommerce Multilingual%s benutzen! Ihre Begeisterung und Unterstützung können\n Sie immer ausdrücken,%s indem Sie unser Plugin bewerten und erzählen, dass %ses bei Ihnen funktioniert.%s"
618
-
619
- msgid "Hide"
620
- msgstr "Ausblenden"
621
-
622
- msgid "Loading ..."
623
- msgstr "Ladevorgang ..."
624
-
625
- msgid "Regular Price"
626
- msgstr "Regulärer Preis"
627
-
628
- msgid "Sale Price"
629
- msgstr "Verkaufspreis"
630
-
631
- msgid "Multi-currency is enabled but no secondary currencies have been set. %sAdd secondary currencies%s."
632
- msgstr ""
633
-
634
- msgid "Calculate prices in other currencies automatically"
635
- msgstr "Berechnet Preise in anderen Währungen automatisch"
636
-
637
- msgid "Click to see the prices in the other currencies as they are currently shown on the front end."
638
- msgstr "Klicken Sie, um die Preise in den anderen Währungen zu sehen, wie sie aktuell im Frontend angezeigt werden."
639
-
640
- msgid "Show"
641
- msgstr "Anzeigen"
642
-
643
- msgid "Set prices in other currencies manually"
644
- msgstr "Preise in anderen Währungen manuell festlegen"
645
-
646
- msgid "Enter prices in other currencies"
647
- msgstr "Geben Sie Preise in anderen Währungen ein"
648
-
649
- msgid "Hide prices in other currencies"
650
- msgstr "Preise in anderen Währungen ausblenden"
651
-
652
- msgid "Determined automatically based on exchange rate"
653
- msgstr "Wird auf Basis des Wechselkurses automatisch bestimmt"
654
-
655
- msgid "Schedule"
656
- msgstr "Zeitplan"
657
-
658
- msgid "Same as default currency"
659
- msgstr "Gleich wie die Standardwährung"
660
-
661
- msgid "Set dates"
662
- msgstr "Termine festlegen"
663
-
664
- msgid "Collapse"
665
- msgstr "Einklappen"
666
-
667
- msgid "From&hellip;"
668
- msgstr "Von&hellip;"
669
-
670
- msgid "To&hellip;"
671
- msgstr "An&hellip;"
672
-
673
- msgid "Please enter in a value less than the regular price"
674
- msgstr "Bitte geben Sie einen Wert ein, der geringer als der normale Preis ist"
675
-
676
- msgid "Required plugins"
677
- msgstr "Erforderliche Plugins"
678
-
679
- msgid "Plugins Status"
680
- msgstr "Plugins-Status"
681
-
682
- msgid "WooCommerce Multilingual depends on several plugins to work. If any required plugin is missing, you should install and activate it."
683
- msgstr "WooCommerce Multilingual benötigt mehrere Plugins, um zu funktionieren. Wenn ein erforderliches Plugin fehlt, sollten Sie es installieren und aktivieren."
684
-
685
- msgid "WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href=\"%s\">WPML</a> versions prior 2.0.5."
686
- msgstr "WooCommerce Multilingual ist aktiviert, funktioniert aber nicht. Es ist nicht mit <a href=\"%s\">WPML</a>-Versionen vor 2.0.5 kompatibel."
687
-
688
- msgid "Update WPML"
689
- msgstr "WPML aktualisieren"
690
-
691
- msgid "Get WPML"
692
- msgstr "WPML herunterladen"
693
-
694
- msgid "Get WPML Media"
695
- msgstr "WPML Media herunterladen"
696
-
697
- msgid "Get WPML Translation Management"
698
- msgstr "WPML Übersetzungsmanagement herunterladen"
699
-
700
- msgid "Get WPML String Translation"
701
- msgstr "WPML String Translation herunterladen"
702
-
703
- msgid "%s is installed and active."
704
- msgstr "%s ist installiert und aktiv."
705
-
706
- msgid "%s is set up."
707
- msgstr "%s ist eingerichtet."
708
-
709
- msgid "%s is not set up."
710
- msgstr "%s ist nicht eingerichtet."
711
-
712
- msgid "%s is either not installed or not active."
713
- msgstr "%s ist entweder nicht installiert oder nicht aktiv."
714
-
715
- msgid "%1$s is installed, but with incorrect version. You need %1$s %2$s or higher. "
716
- msgstr "%1$s ist installiert, aber in der falschen Version. Sie brauchen %1$s %2$s oder höher."
717
-
718
- msgid "Download WooCommerce"
719
- msgstr "WooCommerce herunterladen"
720
-
721
- msgid "The WordPress Multilingual Plugin"
722
- msgstr "Das WordPress Multilingual-Plugin"
723
-
724
- msgid "This page allows you to translate all strings that are being used by WooCommerce in building different type of urls. Translating them enables you to have fully localized urls that match the language of the pages."
725
- msgstr "Diese Seite ermöglicht es Ihnen, alle Strings zu übersetzen, die von WooCommerce zur Erstellung verschiedener URL-Typen verwendet werden. Wenn Sie diese übersetzen, haben Sie komplett lokalisierte URLs, die zur Sprache der Seiten passen."
726
-
727
- msgid "You can enter or edit your default values on the %sPermalinks settings%s page or, for the endpoints, on the WooCommerce %sAccount settings%s page."
728
- msgstr "Sie können Ihre Standardwerte auf der %sPermalinks-Einstellungen%s-Seite eingeben oder bearbeiten, oder im Falle der Endpunkte auf der WooCommerce %sAccount-Einstellungs%s-Seite."
729
-
730
- msgid "permalinks settings"
731
- msgstr "Permalinks-Einstellungen"
732
-
733
- msgid "Account settings"
734
- msgstr "Account-Einstellungen"
735
-
736
- msgid "Slug type"
737
- msgstr "Slug-Typ"
738
-
739
- msgid "Original Slug"
740
- msgstr "Original-Slug"
741
-
742
- msgid "Shop page"
743
- msgstr "Shop-Seite"
744
-
745
- msgid "Product base"
746
- msgstr "Produktbasis"
747
-
748
- msgid "Product category base"
749
- msgstr "Produktkategoriebasis"
750
-
751
- msgid "Product tag base"
752
- msgstr "Produkt-Tag-Basis"
753
-
754
- msgid "Product attribute base"
755
- msgstr "Produktattributbasis"
756
-
757
- msgid "Original"
758
- msgstr "Original"
759
-
760
- msgid "Translation to"
761
- msgstr "Übersetzung auf"
762
-
763
- msgid "Product Shop Base"
764
- msgstr "Produkt-Shop-Basis"
765
-
766
- msgid "Welcome to WooCommerce Multilingual!"
767
- msgstr "Willkommen bei WooCommerce Multilingual!"
768
-
769
- msgid "Configure the multilingual support for your e-commerce site in just a couple of minutes."
770
- msgstr ""
771
-
772
- msgid "By default, the products are translatable just like product categories, product tags and attributes. So you can start translating these right away."
773
- msgstr "Standardmäßig sind die Produkte genau wie Produktkategorien, Produkt-Tags und Attribute übersetzbar. So können Sie sofort mit ihrer Übersetzung beginnen."
774
-
775
- msgid "You can configure, however, which attributes you want to translate, install the translated shop pages or enable the multi-currency mode."
776
- msgstr "Sie können jedoch konfigurieren, welche Attribute Sie übersetzen wollen, die übersetzten Shop-Seiten installieren oder den Modus für mehrere Währungen aktivieren."
777
-
778
- msgid "Start"
779
- msgstr "Start"
780
-
781
- msgid "No, thanks. I'll do it later."
782
- msgstr "Nein, danke. Das mache ich später."
783
-
784
- msgid "Select translatable attributes"
785
- msgstr "Übersetzbare Attribute auswählen"
786
-
787
- msgid "There are no attributes defined"
788
- msgstr "Es wurden keine Attribute definiert"
789
-
790
- msgid "Continue"
791
- msgstr "Weiter"
792
-
793
- msgid "Later"
794
- msgstr "Später"
795
-
796
- msgid "One or more WooCommerce pages have not been created"
797
- msgstr "Eine oder mehrere WooCommerce-Seiten wurden nicht erstellt"
798
-
799
- msgid "Install missing WooCommerce pages and create translations."
800
- msgstr "Installieren Sie fehlende WooCommerce-Seiten und erstellen Sie Übersetzungen."
801
-
802
- msgid "Translate Store Pages"
803
- msgstr "Store-Seiten übersetzen"
804
-
805
- msgid "All store pages must be translated in the languages configured on the site."
806
- msgstr "Alle Store-Seiten müssen in die auf der Seite konfigurierten Sprachen übersetzt werden."
807
-
808
- msgid "Select the translation interface"
809
- msgstr "Wählen Sie die Übersetzungsoberfläche aus."
810
-
811
- msgid "Enable multiple currencies"
812
- msgstr "Mehrere Währungen aktivieren"
813
-
814
- msgid "This will allow you to set prices for products in different currencies. The prices can be determined based on a given exchange rate or set explicitly for specific products."
815
- msgstr "Hiermit können Sie Preise für Produkte in verschiedenen Kategorien festlegen. Die Preise können auf Basis eines angegebenen Wechselkurses ermittelt oder gezielt für bestimmte Produkte eingestellt werden."
816
-
817
- msgid "Enable the multi-currency mode"
818
- msgstr "Modus für mehrere Währungen aktivieren"
819
-
820
- msgid "Further actions that are necessary for making your existing content multilingual, are listed below."
821
- msgstr "Weitere Aktionen, die nötig sind, um Ihren vorhandenen Inhalt mehrsprachig zu machen, sind unten aufgeführt."
822
-
823
- msgid "Start translating products"
824
- msgstr "Beginnen Sie, Produkte zu übersetzen"
825
-
826
- msgid "Add secondary currencies on the %smulti-currency configuration%s page"
827
- msgstr "Fügen Sie auf der Seite %sKonfiguration für mehrere Währungen%s weitere Währungen hinzu"
828
-
829
- msgid "Translate existing terms for these %sproduct attributes%s: %s"
830
- msgstr "Übersetzen Sie vorhandene Begriffe für diese %sProduktattribute%s: %s"
831
-
832
- msgid "Translate existing %sproduct categories%s"
833
- msgstr "Übersetzen Sie vorhandene %sProduktkategorien%s"
834
-
835
- msgid "Translate existing %sproduct tags%s"
836
- msgstr "Übersetzen Sie vorhandene %sProdukt-Tags%s"
837
-
838
- msgid "%sAdd missing translations%s for shipping classes"
839
- msgstr "%sFügen Sie fehlende Übersetzungen hinzu%s für Versandklassen"
840
-
841
- msgid "Translate %sURL slugs%s to create multilingual store and product urls"
842
- msgstr "Übersetzen Sie %sURL-Slugs%s, um mehrsprachige Store- und Produkt-URLs zu generieren"
843
-
844
- msgid "Use custom settings for translations download files"
845
- msgstr ""
846
-
847
- msgid "WooCommerce Store Pages"
848
- msgstr "WooCommerce Store-Seiten"
849
-
850
- msgid "To run a multilingual e-commerce site, you need to have the WooCommerce shop pages translated to all the site's languages. Once all the pages are installed you can add the translations for them from this menu."
851
- msgstr "Um eine mehrsprachige E-Commerce-Seite zu betreiben, müssen Sie die WooCommerce-Shop-Seiten in alle Sprachen der Seite übersetzen lassen. Sobald alle Seiten installiert sind, können Sie die Übersetzungen für diese aus dem Menü hinzufügen."
852
-
853
- msgid "One or more WooCommerce pages have not been created."
854
- msgstr "Eine oder mehrere WooCommerce-Seite wurden nicht erstellt."
855
-
856
- msgid "Install WooCommerce Pages"
857
- msgstr "WooCommerce-Seiten installieren"
858
-
859
- msgid "WooCommerce store pages do not exist for these languages:"
860
- msgstr "Für diese Sprachen gibt es keine WooCommerce-Shop-Seiten:"
861
-
862
- msgid "Create missing translations"
863
- msgstr "Fehlende Übersetzungen erstellen"
864
-
865
- msgid "These pages are currently being translated by translators via WPML: "
866
- msgstr "Diese Seiten werden aktuell von Übersetzern über WPML übersetzt:"
867
-
868
- msgid "WooCommerce store pages are translated to all the site's languages."
869
- msgstr "WooCommerce Store-Seiten werden in alle Sprachen der Seite übersetzt."
870
-
871
- msgid "Configuration warnings"
872
- msgstr "Konfigurationswarnungen"
873
-
874
- msgid "Reporting miscelaneous configuration issues that can make WooCommerce Multilingual not run normally"
875
- msgstr "Es wurden verschiedene Konfigurationsprobleme gemeldet, die dazu führen können, dass WooCommerce Multilingual nicht richtig funktioniert"
876
-
877
- msgid "Your product permalink base is not translated to:"
878
- msgstr "Ihre Produkt-Permalink-Basis ist nicht übersetzt auf:"
879
-
880
- msgid "Translate URLs"
881
- msgstr "URLs übersetzen"
882
-
883
- msgid "Your site's default language is not English and the strings language is also not English."
884
- msgstr "Die Standardsprache Ihrer Seite ist nicht Englisch und die Sprache der Strings ist ebenfalls nicht Englisch."
885
-
886
- msgid "Running WooCommerce multilingual with default language other than English."
887
- msgstr "Betrieb von WooCommerce Multilingual mit einer anderen Standardsprache als Englisch."
888
-
889
- msgid "This may cause problems with URLs in different languages."
890
- msgstr "Dies kann Probleme mit URLs in unterschiedlichen Sprachen hervorrufen."
891
-
892
- msgid "Change default language"
893
- msgstr "Standardsprache ändern"
894
-
895
- msgid "Your site's default language is not English."
896
- msgstr "Die Standardsprache Ihrer Seite ist nicht Englisch."
897
-
898
- msgid "There are some settings that require careful attention."
899
- msgstr "Einige der Einstellungen müssen sorgfältig ausgewählt werden."
900
-
901
- msgid "Some settings from the WooCommerce Multilingual wpml-config.xml file have been overwritten."
902
- msgstr "Einige Einstellungen aus der wpml-config.xml-Datei in WooCommerce Multilingual wurden überschrieben."
903
-
904
- msgid "You should check WPML configuration files added by other plugins or manual settings on the %s section."
905
- msgstr "Sie sollten die WPML-Konfigurationsdateien prüfen, die von anderen Plugins hinzugefügt wurden oder die manuellen Einstellungen im Abschnitt %s."
906
-
907
- msgid "Multilingual Content Setup"
908
- msgstr "Einrichtung des mehrsprachigen Inhalts"
909
-
910
- msgid "Taxonomies missing translations"
911
- msgstr "Übersetzungen in Taxonomien fehlen"
912
-
913
- msgid "To run a fully translated site, you should translate all taxonomy terms. Some store elements, such as variations, depend on taxonomy translation."
914
- msgstr "Um eine vollständig übersetzte Seite zu betreiben, sollten Sie alle Taxonomie-Begriffe übersetzen. Einige Store-Elemente wie Variationen hängen von der Taxonomie-Übersetzung ab."
915
-
916
- msgid "This taxonomy requires translation."
917
- msgstr "Diese Taxonomie erfordert eine Übersetzung."
918
-
919
- msgid "Include in translation"
920
- msgstr "In die Übersetzung einbeziehen"
921
-
922
- msgid "This taxonomy does not require translation."
923
- msgstr "Diese Taxonomie erfordert keine Übersetzung."
924
-
925
- msgid "Right now, there are no taxonomy terms needing translation."
926
- msgstr "Aktuell benötigen keine Taxonomie-Begriffe eine Übersetzung."
927
-
928
- msgid "There are no translatable product attributes defined"
929
- msgstr "Es wurden keine übersetzbaren Produktattribute definiert"
930
-
931
- msgid "Select the attribute to translate: "
932
- msgstr "Wählen Sie das zu übersetzende Attribut:"
933
-
934
- msgid "Please make a backup of your database before you start the synchronization"
935
- msgstr "Bitte erstellen Sie ein Backup Ihrer Datenbank, bevor Sie die Synchronisierung starten."
936
-
937
- msgid "Sync variables products"
938
- msgstr "Variable Produkte synchronisieren"
939
-
940
- msgid "Update products count:"
941
- msgstr "Produktzähler aktualisieren:"
942
-
943
- msgid "products with variations"
944
- msgstr "Produkte mit Variationen"
945
-
946
- msgid "Sync products variations:"
947
- msgstr "Produkt-Variationen synchronisieren:"
948
-
949
- msgid "left"
950
- msgstr "übrig"
951
-
952
- msgid "Sync products \"gallery images\":"
953
- msgstr "Produkt-\"Galeriebilder\" synchr.:"
954
-
955
- msgid "Sync products categories (display type, thumbnail):"
956
- msgstr "Produktkategorien synchronisieren (Anzeigetyp, Miniaturbild):"
957
-
958
- msgid "Duplicate terms ( please select attribute ):"
959
- msgstr "Begriffe duplizieren (bitte Attribut auswählen):"
960
-
961
- msgid "none"
962
- msgstr "keine"
963
-
964
- msgid "Enable/disable"
965
- msgstr "Aktivieren/deaktivieren"
966
-
967
- msgid "Currencies"
968
- msgstr "Währungen"
969
-
970
- msgid "Add currency"
971
- msgstr "Währung hinzufügen"
972
-
973
- msgid "Currency"
974
- msgstr "Währung"
975
-
976
- msgid "Rate"
977
- msgstr "Kurs"
978
-
979
- msgid "default"
980
- msgstr "Voreinstellung"
981
-
982
- msgid "Default currency"
983
- msgstr "Standardwährung"
984
-
985
- msgid "Switch to this currency when switching language in the front-end"
986
- msgstr "Beim Umschalten der Sprache im Front-End auf diese Währung umschalten"
987
-
988
- msgid "Keep"
989
- msgstr "Beibehalten"
990
-
991
- msgid "Delete"
992
- msgstr "Löschen"
993
-
994
- msgid " (%s)"
995
- msgstr "(%s)"
996
-
997
- msgid "The multi-currency mode cannot be enabled as a specific currency was not set. Go to the %sWooCommerce settings%s page and select the default currency for your store."
998
- msgstr "Der Modus für mehrere Währungen kann nicht aktiviert werden, da keine bestimmte Währung eingestellt wurde. Gehen Sie auf die Seite %sWooCommerce-Einstellungen%s und wählen Sie die Standardwährung für Ihren Shop aus."
999
-
1000
- msgid "Learn more"
1001
- msgstr "Mehr erfahren"
1002
-
1003
- msgid "Show only products with custom prices in secondary currencies"
1004
- msgstr "Nur Produkte mit benutzerdefinierten Preisen in Zweitwährungen anzeigen"
1005
-
1006
- msgid "When this option is on, when you switch to a secondary currency on the front end, only the products with custom prices in that currency are being displayed. Products with prices determined based on the exchange rate are hidden."
1007
- msgstr "Wenn diese Option eingeschaltet ist und Sie im Frontend auf eine Zweitwährung wechseln, werden in dieser Währung nur Produkte mit benutzerdefinierten Preisen angezeigt. Produkte mit Preisen, die basierend auf dem Wechselkurs bestimmt werden, werden ausgeblendet."
1008
-
1009
- msgid "The changes you made will be lost if you navigate away from this page."
1010
- msgstr "Die von Ihnen durchgeführten Änderungen gehen verloren, wenn Sie von dieser Seite weg navigieren."
1011
-
1012
- msgid "At least one currency must be enabled for this language!"
1013
- msgstr "Mindestens eine Währung muss für diese Sprache aktiviert sein!"
1014
-
1015
- msgid "Currency switcher options"
1016
- msgstr "Währungsumschalter-Optionen"
1017
-
1018
- msgid "Currency switcher style"
1019
- msgstr "Währungsumschalter-Stil"
1020
-
1021
- msgid "Currency order"
1022
- msgstr "Währungsreihenfolge"
1023
-
1024
- msgid "Available parameters"
1025
- msgstr "Verfügbare Parameter"
1026
-
1027
- msgid "Template for currency switcher"
1028
- msgstr "Template für Währungsumschalter"
1029
-
1030
- msgid "Visibility"
1031
- msgstr "Sichtbarkeit"
1032
-
1033
- msgid "Currency switcher preview"
1034
- msgstr "Wäh