GravityView  2.17
The best, easiest way to display Gravity Forms entries on your website.
EDD.php
Go to the documentation of this file.
1 <?php
2 /**
3  * @license GPL-2.0-or-later
4  *
5  * Modified by gravityview on 13-January-2023 using Strauss.
6  * @see https://github.com/BrianHenryIE/strauss
7  */
8 
10 
13 use Exception;
14 
15 class EDD {
16  /**
17  * @since 1.0.0
18  *
19  * @var EDD Class instance.
20  */
21  private static $_instance;
22 
23  /**
24  * Returns class instance.
25  *
26  * @since 1.0.0
27  *
28  * @return EDD
29  */
30  public static function get_instance() {
31  if ( is_null( self::$_instance ) ) {
32  self::$_instance = new self();
33  }
34 
35  return self::$_instance;
36  }
37 
38  /**
39  * Initializes the class.
40  *
41  * @since 1.0.0
42  *
43  * @return void
44  */
45  public function init() {
46  add_filter( 'pre_set_site_transient_update_plugins', [ $this, 'check_for_product_updates' ] );
47  add_filter( 'plugins_api', [ $this, 'display_product_information' ], 10, 3 );
48  add_filter( 'admin_init', [ $this, 'disable_legacy_edd_updater' ], 999 );
49  }
50 
51  /**
52  * Disables EDD updater that's included with GravityKit products.
53  *
54  * @since 1.0.0
55  *
56  * @return void
57  */
58  public function disable_legacy_edd_updater() {
59  global $wp_filter;
60 
61  $filters_to_remove = [ 'pre_set_site_transient_update_plugins', 'plugins_api', 'after_plugin_row', 'admin_init' ];
62 
63  $legacy_edd_check = function () {
64  return isset( $this->api_url ) && preg_match( '/gravity(view|kit)\.com?/', $this->api_url );
65  };
66 
67  $remove_filter = function ( $filter ) use ( $wp_filter, $legacy_edd_check ) {
68  if ( empty( $wp_filter[ $filter ]->callbacks ) ) {
69  return;
70  }
71 
72  foreach ( $wp_filter[ $filter ]->callbacks as &$callback ) {
73  foreach ( $callback as $key => &$hook ) {
74  if ( ! is_array( $hook['function'] ) || ! is_object( $hook['function'][0] ) ) {
75  continue;
76  }
77 
78  // EDD_SL_Plugin_Updater->api_url is a private property, so we need a way to access it.
79  $is_legacy_edd = $legacy_edd_check->bindTo( $hook['function'][0], get_class( $hook['function'][0] ) );
80 
81  if ( ! $is_legacy_edd() ) {
82  continue;
83  }
84 
85  unset( $callback[ $key ] );
86  }
87  }
88  };
89 
90  foreach ( array_keys( $wp_filter ) as $filter ) {
91  foreach ( $filters_to_remove as $filter_to_remove ) {
92  // Older EDD_SL_Plugin_Updater class uses 'after_plugin_row_{plugin_file}' filter, so we can't just check for 'after_plugin_row'.
93  if ( strpos( $filter, $filter_to_remove ) !== false ) {
94  $remove_filter( $filter );
95  }
96  }
97  }
98  }
99 
100  /**
101  * Checks for product updates and modifies the 'update_plugins' transient.
102  *
103  * @since 1.0.0
104  *
105  * @param object $transient_data
106  * @param bool $skip_cache (optional) Whether to skip cache when getting products data. Default: false.
107  *
108  * @return object
109  */
110  public function check_for_product_updates( $transient_data, $skip_cache = false ) {
111  static $checked;
112 
113  if ( ! is_object( $transient_data ) ) {
114  $transient_data = new \stdClass();
115  }
116 
117  if ( ! $checked && ! $skip_cache && Arr::get( $_GET, 'force-check', false ) ) {
118  $skip_cache = true;
119  }
120 
121  try {
122  $products_data = ProductManager::get_instance()->get_products_data( [ 'skip_cache' => $skip_cache ] );
123  } catch ( Exception $e ) {
124  LoggerFramework::get_instance()->error( "Can't get products data when checking for updated versions: " . $e->getMessage() );
125 
126  return $transient_data;
127  }
128 
129  foreach ( $products_data as $path => $product ) {
130  if ( ! Arr::get( $product, 'installed' ) ) {
131  continue;
132  }
133 
134  $wp_product_data = $this->format_product_data( $product );
135 
136  if ( $product['update_available'] ) {
137  $transient_data->response[ $path ] = $wp_product_data;
138  } else {
139  $transient_data->no_update[ $path ] = $wp_product_data;
140  }
141 
142  $transient_data->checked[ $path ] = Arr::get( $product, 'installed_version' );
143  }
144 
145  $transient_data->last_checked = time();
146 
147  $checked = true;
148 
149  return $transient_data;
150  }
151 
152  /**
153  * Returns a product object formatted according to what WP expects in order to display changelog/store plugin update data.
154  *
155  * @since 1.0.0
156  *
157  * @see ProductManager::get_products_data()
158  * @see plugins_api()
159  *
160  * @param array $product Product data.
161  *
162  * @return object
163  */
164  public function format_product_data( $product ) {
165  $licenses_data = LicenseManager::get_instance()->get_licenses_data();
166 
167  $license = Arr::get( $product, 'licenses.0' );
168 
169  $download_link = Arr::get( $licenses_data, "{$license}.products.{$product['id']}.download" );
170 
171  $formatted_data = [
172  'plugin' => Arr::get( $product, 'path' ),
173  'name' => Arr::get( $product, 'title' ),
174  'id' => Arr::get( $product, 'id' ),
175  'slug' => Arr::get( $product, 'slug' ),
176  'version' => Arr::get( $product, 'server_version' ),
177  'new_version' => Arr::get( $product, 'server_version' ),
178  'url' => Arr::get( $product, 'link' ),
179  'homepage' => Arr::get( $product, 'link' ),
180  'icons' => [
181  '1x' => Arr::get( $product, 'icons.1x' ),
182  '2x' => Arr::get( $product, 'icons.2x' ),
183  ],
184  'banners' => [
185  'low' => Arr::get( $product, 'banners.low' ),
186  'high' => Arr::get( $product, 'banners.high' ),
187  ],
188  'sections' => [
189  'description' => Arr::get( $product, 'sections.description' ),
190  'changelog' => Arr::get( $product, 'sections.changelog' ),
191  ],
192  'requires' => Arr::get( $product, 'system_requirements.wp.version' ),
193  'tested' => Arr::get( $product, 'system_requirements.wp.tested' ),
194  'requires_php' => Arr::get( $product, 'system_requirements.php.version' ),
195  ];
196 
197  if ( $download_link ) {
198  $formatted_data['package'] = $download_link;
199  $formatted_data['download_link'] = $download_link;
200  }
201 
202  return (object) $formatted_data;
203  }
204 
205 
206  /**
207  * Returns product information for display on the Plugins page.
208  * This short-circuits the WordPress.org API request by returning product information from the EDD API that we store in the database.
209  *
210  * @since 1.0.0
211  *
212  * @param false|object|array $result Product information.
213  * @param string $action Plugin Installation API action.
214  * @param object $args Request arguments.
215  *
216  * @return false|object|array
217  */
218  public function display_product_information( $result, $action, $args ) {
219  try {
220  $products_data = ProductManager::get_instance()->get_products_data( [ 'key_by' => 'slug' ] );
221  } catch ( Exception $e ) {
222  LoggerFramework::get_instance()->error( "Can't get products data when displaying the changelog: " . $e->getMessage() );
223 
224  return $result;
225  }
226 
227  if ( 'plugin_information' !== $action ) {
228  return $result;
229  }
230 
231  $product = Arr::get( $products_data, $args->slug );
232 
233  if ( ! $product ) {
234  return $result;
235  }
236 
237  return $this->format_product_data( $product );
238  }
239 }
format_product_data( $product)
Returns a product object formatted according to what WP expects in order to display changelog/store p...
Definition: EDD.php:164
static get( $array, $key, $default=null)
{}
Definition: Arr.php:99
init()
Initializes the class.
Definition: EDD.php:45
check_for_product_updates( $transient_data, $skip_cache=false)
Checks for product updates and modifies the &#39;update_plugins&#39; transient.
Definition: EDD.php:110
disable_legacy_edd_updater()
Disables EDD updater that&#39;s included with GravityKit products.
Definition: EDD.php:58
static get_instance()
Returns class instance.
Definition: EDD.php:30
display_product_information( $result, $action, $args)
Returns product information for display on the Plugins page.
Definition: EDD.php:218