GravityView  2.5
The best, easiest way to display Gravity Forms entries on your website.
class-gv-plugin.php
Go to the documentation of this file.
1 <?php
2 namespace GV;
3 
4 /** If this file is called directly, abort. */
5 if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
6  die();
7 }
8 
9 /**
10  * The GravityView WordPress plugin class.
11  *
12  * Contains functionality related to GravityView being
13  * a WordPress plugin and doing WordPress pluginy things.
14  *
15  * Accessible via gravityview()->plugin
16  */
17 final class Plugin {
18  /**
19  * @var string The plugin version.
20  *
21  * @api
22  * @since 2.0
23  */
24  public static $version = GV_PLUGIN_VERSION;
25 
26  /**
27  * @var string Minimum WordPress version.
28  *
29  * GravityView requires at least this version of WordPress to function properly.
30  */
31  private static $min_wp_version = GV_MIN_WP_VERSION;
32 
33  /**
34  * @var string Minimum Gravity Forms version.
35  *
36  * GravityView requires at least this version of Gravity Forms to function properly.
37  */
38  public static $min_gf_version = GV_MIN_GF_VERSION;
39 
40  /**
41  * @var string Minimum PHP version.
42  *
43  * GravityView requires at least this version of PHP to function properly.
44  */
45  private static $min_php_version = GV_MIN_PHP_VERSION;
46 
47  /**
48  * @var string|bool Minimum future PHP version.
49  *
50  * GravityView will require this version of PHP soon. False if no future PHP version changes are planned.
51  */
52  private static $future_min_php_version = GV_FUTURE_MIN_PHP_VERSION;
53 
54  /**
55  * @var string|bool Minimum future Gravity Forms version.
56  *
57  * GravityView will require this version of Gravity Forms soon. False if no future Gravity Forms version changes are planned.
58  */
59  private static $future_min_gf_version = GV_FUTURE_MIN_GF_VERSION;
60 
61  /**
62  * @var \GV\Plugin The \GV\Plugin static instance.
63  */
64  private static $__instance = null;
65 
66  /**
67  * @var \GV\Addon_Settings The plugin "addon" settings.
68  *
69  * @api
70  * @since 2.0
71  */
72  public $settings;
73 
74  /**
75  * @var string The GFQuery functionality identifier.
76  */
77  const FEATURE_GFQUERY = 'gfquery';
78 
79  /**
80  * @var string The joins functionality identifier.
81  */
82  const FEATURE_JOINS = 'joins';
83 
84  /**
85  * @var string The unions functionality identifier.
86  */
87  const FEATURE_UNIONS = 'unions';
88 
89  /**
90  * @var string The REST API functionality identifier.
91  */
92  const FEATURE_REST = 'rest_api';
93 
94  /**
95  * Get the global instance of \GV\Plugin.
96  *
97  * @return \GV\Plugin The global instance of GravityView Plugin.
98  */
99  public static function get() {
100  if ( ! self::$__instance instanceof self ) {
101  self::$__instance = new self;
102  }
103  return self::$__instance;
104  }
105 
106 
107  private function __construct() {
108  /**
109  * Load translations.
110  */
111  add_action( 'init', array( $this, 'load_textdomain' ) );
112 
113  /**
114  * Load some frontend-related legacy files.
115  */
116  add_action( 'gravityview/loaded', array( $this, 'include_legacy_frontend' ) );
117 
118  /**
119  * GFAddOn-backed settings, licensing.
120  */
121  add_action( 'plugins_loaded', array( $this, 'load_license_settings' ) );
122  }
123 
124  public function load_license_settings() {
125  require_once $this->dir( 'future/includes/class-gv-license-handler.php' );
126  require_once $this->dir( 'future/includes/class-gv-settings-addon.php' );
127  if ( class_exists( '\GV\Addon_Settings' ) ) {
128  $this->settings = new Addon_Settings();
129  include_once $this->dir( 'includes/class-gravityview-settings.php' );
130  } else {
131  gravityview()->log->notice( '\GV\Addon_Settings not loaded. Missing \GFAddOn.' );
132  }
133  }
134 
135  /**
136  * Check whether GravityView is network activated.
137  *
138  * @return bool Whether it's network activated or not.
139  */
140  public static function is_network_activated() {
141 
142  $plugin_basename = plugin_basename( GRAVITYVIEW_FILE );
143 
144  return is_multisite() && ( function_exists( 'is_plugin_active_for_network' ) && is_plugin_active_for_network( $plugin_basename ) );
145  }
146 
147  /**
148  * Include more legacy stuff.
149  *
150  * @param boolean $force Whether to force the includes.
151  *
152  * @return void
153  */
154  public function include_legacy_frontend( $force = false ) {
155 
156  if ( gravityview()->request->is_admin() && ! $force ) {
157  return;
158  }
159 
160  include_once $this->dir( 'includes/class-gravityview-image.php' );
161  include_once $this->dir( 'includes/class-template.php' );
162  include_once $this->dir( 'includes/class-api.php' );
163  include_once $this->dir( 'includes/class-frontend-views.php' );
164  include_once $this->dir( 'includes/class-gravityview-change-entry-creator.php' );
165 
166  /**
167  * @action `gravityview_include_frontend_actions` Triggered after all GravityView frontend files are loaded
168  *
169  * @deprecated Use `gravityview/loaded` along with \GV\Request::is_admin(), etc.
170  *
171  * Nice place to insert extensions' frontend stuff
172  */
173  do_action( 'gravityview_include_frontend_actions' );
174  }
175 
176  /**
177  * Load more legacy core files.
178  *
179  * @return void
180  */
181  public function include_legacy_core() {
182 
183  if ( ! class_exists( '\GravityView_Extension' ) ) {
184  include_once $this->dir( 'includes/class-gravityview-extension.php' );
185  }
186 
187  // Load fields
188  include_once $this->dir( 'includes/fields/class-gravityview-fields.php' );
189  include_once $this->dir( 'includes/fields/class-gravityview-field.php' );
190 
191  // Load all field files automatically
192  foreach ( glob( $this->dir( 'includes/fields/class-gravityview-field*.php' ) ) as $gv_field_filename ) {
193  include_once $gv_field_filename;
194  }
195 
196  include_once $this->dir( 'includes/class-gravityview-entry-approval-status.php' );
197  include_once $this->dir( 'includes/class-gravityview-entry-approval.php' );
198 
199  include_once $this->dir( 'includes/class-gravityview-entry-notes.php' );
200  include_once $this->dir( 'includes/load-plugin-and-theme-hooks.php' );
201 
202  // Load Extensions
203  // @todo: Convert to a scan of the directory or a method where this all lives
204  include_once $this->dir( 'includes/extensions/edit-entry/class-edit-entry.php' );
205  include_once $this->dir( 'includes/extensions/delete-entry/class-delete-entry.php' );
206  include_once $this->dir( 'includes/extensions/duplicate-entry/class-duplicate-entry.php' );
207  include_once $this->dir( 'includes/extensions/entry-notes/class-gravityview-field-notes.php' );
208 
209  // Load WordPress Widgets
210  include_once $this->dir( 'includes/wordpress-widgets/register-wordpress-widgets.php' );
211 
212  // Load GravityView Widgets
213  include_once $this->dir( 'includes/widgets/register-gravityview-widgets.php' );
214 
215  // Add oEmbed
216  include_once $this->dir( 'includes/class-api.php' );
217  include_once $this->dir( 'includes/class-oembed.php' );
218 
219  // Add logging
220  include_once $this->dir( 'includes/class-gravityview-logging.php' );
221 
222  include_once $this->dir( 'includes/class-ajax.php' );
223  include_once $this->dir( 'includes/class-gravityview-html-elements.php' );
224  include_once $this->dir( 'includes/class-frontend-views.php' );
225  include_once $this->dir( 'includes/class-gravityview-admin-bar.php' );
226  include_once $this->dir( 'includes/class-gravityview-entry-list.php' );
227  include_once $this->dir( 'includes/class-gravityview-merge-tags.php'); /** @since 1.8.4 */
228  include_once $this->dir( 'includes/class-data.php' );
229  include_once $this->dir( 'includes/class-gravityview-shortcode.php' );
230  include_once $this->dir( 'includes/class-gravityview-entry-link-shortcode.php' );
231  include_once $this->dir( 'includes/class-gvlogic-shortcode.php' );
232  include_once $this->dir( 'includes/presets/register-default-templates.php' );
233 
234  if ( class_exists( '\GFFormsModel' ) ) {
235  include_once $this->dir( 'includes/class-gravityview-gfformsmodel.php' );
236  }
237  }
238 
239  /**
240  * Load the translations.
241  *
242  * Order of look-ups:
243  *
244  * 1. /wp-content/languages/plugins/gravityview-{locale}.mo (loaded by WordPress Core)
245  * 2. /wp-content/mu-plugins/gravityview-{locale}.mo
246  * 3. /wp-content/mu-plugins/languages/gravityview-{locale}.mo
247  * 4. /wp-content/plugins/gravityview/languages/gravityview-{locale}.mo
248  *
249  * @return void
250  */
251  public function load_textdomain() {
252 
253  $domain = 'gravityview';
254 
255  // 1. /wp-content/languages/plugins/gravityview-{locale}.mo (loaded by WordPress Core)
256  if ( is_textdomain_loaded( $domain ) ) {
257  return;
258  }
259 
260  // 2. /wp-content/languages/plugins/gravityview-{locale}.mo
261  // 3. /wp-content/mu-plugins/plugins/languages/gravityview-{locale}.mo
262  $loaded = load_muplugin_textdomain( $domain, '/languages/' );
263 
264  if ( $loaded ) {
265  return;
266  }
267 
268  // 4. /wp-content/plugins/gravityview/languages/gravityview-{locale}.mo
269  $loaded = load_plugin_textdomain( $domain, false, $this->relpath( '/languages/' ) );
270 
271  if ( $loaded ) {
272  return;
273  }
274 
275  // Pre-4.6 loading
276  // TODO: Remove when GV minimum version is WordPress 4.6.0
277  $locale = apply_filters( 'plugin_locale', ( ( function_exists('get_user_locale') && is_admin() ) ? get_user_locale() : get_locale() ), 'gravityview' );
278 
279  $loaded = load_textdomain( 'gravityview', sprintf( '%s/%s-%s.mo', $this->dir('languages'), $domain, $locale ) );
280 
281  if( $loaded ) {
282  return;
283  }
284 
285  gravityview()->log->error( sprintf( 'Unable to load textdomain for %s locale.', $locale ) );
286  }
287 
288  /**
289  * Register hooks that are fired when the plugin is activated and deactivated.
290  *
291  * @return void
292  */
293  public function register_activation_hooks() {
294  register_activation_hook( $this->dir( 'gravityview.php' ), array( $this, 'activate' ) );
295  register_deactivation_hook( $this->dir( 'gravityview.php' ), array( $this, 'deactivate' ) );
296  }
297 
298  /**
299  * Plugin activation function.
300  *
301  * @internal
302  * @return void
303  */
304  public function activate() {
305  gravityview();
306 
307  if ( ! $this->is_compatible() ) {
308  return;
309  }
310 
311  /** Register the gravityview post type upon WordPress core init. */
312  require_once $this->dir( 'future/includes/class-gv-view.php' );
313  View::register_post_type();
314 
315  /** Add the entry rewrite endpoint. */
316  require_once $this->dir( 'future/includes/class-gv-entry.php' );
317  Entry::add_rewrite_endpoint();
318 
319  /** Flush all URL rewrites. */
320  flush_rewrite_rules();
321 
322  update_option( 'gv_version', self::$version );
323 
324  /** Add the transient to redirect to configuration page. */
325  set_transient( '_gv_activation_redirect', true, 60 );
326 
327  /** Clear settings transient. */
328  delete_transient( 'gravityview_edd-activate_valid' );
329 
331  }
332 
333  /**
334  * Plugin deactivation function.
335  *
336  * @internal
337  * @return void
338  */
339  public function deactivate() {
340  flush_rewrite_rules();
341  }
342 
343  /**
344  * Retrieve an absolute path within the GravityView plugin directory.
345  *
346  * @api
347  * @since 2.0
348  *
349  * @param string $path Optional. Append this extra path component.
350  * @return string The absolute path to the plugin directory.
351  */
352  public function dir( $path = '' ) {
353  return wp_normalize_path( GRAVITYVIEW_DIR . ltrim( $path, '/' ) );
354  }
355 
356  /**
357  * Retrieve a relative path to the GravityView plugin directory from the WordPress plugin directory
358  *
359  * @api
360  * @since 2.2.3
361  *
362  * @param string $path Optional. Append this extra path component.
363  * @return string The relative path to the plugin directory from the plugin directory.
364  */
365  public function relpath( $path = '' ) {
366 
367  $dirname = trailingslashit( dirname( plugin_basename( GRAVITYVIEW_FILE ) ) );
368 
369  return wp_normalize_path( $dirname . ltrim( $path, '/' ) );
370  }
371 
372  /**
373  * Retrieve a URL within the GravityView plugin directory.
374  *
375  * @api
376  * @since 2.0
377  *
378  * @param string $path Optional. Extra path appended to the URL.
379  * @return string The URL to this plugin, with trailing slash.
380  */
381  public function url( $path = '/' ) {
382  return plugins_url( $path, $this->dir( 'gravityview.php' ) );
383  }
384 
385  /**
386  * Is everything compatible with this version of GravityView?
387  *
388  * @api
389  * @since 2.0
390  *
391  * @return bool
392  */
393  public function is_compatible() {
394  return
395  $this->is_compatible_php()
396  && $this->is_compatible_wordpress()
397  && $this->is_compatible_gravityforms();
398  }
399 
400  /**
401  * Is this version of GravityView compatible with the current version of PHP?
402  *
403  * @api
404  * @since 2.0
405  *
406  * @return bool true if compatible, false otherwise.
407  */
408  public function is_compatible_php() {
409  return version_compare( $this->get_php_version(), self::$min_php_version, '>=' );
410  }
411 
412  /**
413  * Is this version of GravityView compatible with the future required version of PHP?
414  *
415  * @api
416  * @since 2.0
417  *
418  * @return bool true if compatible, false otherwise.
419  */
420  public function is_compatible_future_php() {
421  return version_compare( $this->get_php_version(), self::$future_min_php_version, '>=' );
422  }
423 
424  /**
425  * Is this version of GravityView compatible with the current version of WordPress?
426  *
427  * @api
428  * @since 2.0
429  *
430  * @param string $version Version to check against; otherwise uses GV_MIN_WP_VERSION
431  *
432  * @return bool true if compatible, false otherwise.
433  */
434  public function is_compatible_wordpress( $version = null ) {
435 
436  if( ! $version ) {
437  $version = self::$min_wp_version;
438  }
439 
440  return version_compare( $this->get_wordpress_version(), $version, '>=' );
441  }
442 
443  /**
444  * Is this version of GravityView compatible with the current version of Gravity Forms?
445  *
446  * @api
447  * @since 2.0
448  *
449  * @return bool true if compatible, false otherwise (or not active/installed).
450  */
451  public function is_compatible_gravityforms() {
452  $version = $this->get_gravityforms_version();
453  return $version ? version_compare( $version, self::$min_gf_version, '>=' ) : false;
454  }
455 
456  /**
457  * Is this version of GravityView compatible with the future version of Gravity Forms?
458  *
459  * @api
460  * @since 2.0
461  *
462  * @return bool true if compatible, false otherwise (or not active/installed).
463  */
465  $version = $this->get_gravityforms_version();
466  return $version ? version_compare( $version, self::$future_min_gf_version, '>=' ) : false;
467  }
468 
469  /**
470  * Retrieve the current PHP version.
471  *
472  * Overridable with GRAVITYVIEW_TESTS_PHP_VERSION_OVERRIDE during testing.
473  *
474  * @return string The version of PHP.
475  */
476  private function get_php_version() {
477  return ! empty( $GLOBALS['GRAVITYVIEW_TESTS_PHP_VERSION_OVERRIDE'] ) ?
478  $GLOBALS['GRAVITYVIEW_TESTS_PHP_VERSION_OVERRIDE'] : phpversion();
479  }
480 
481  /**
482  * Retrieve the current WordPress version.
483  *
484  * Overridable with GRAVITYVIEW_TESTS_WP_VERSION_OVERRIDE during testing.
485  *
486  * @return string The version of WordPress.
487  */
488  private function get_wordpress_version() {
489  return ! empty( $GLOBALS['GRAVITYVIEW_TESTS_WP_VERSION_OVERRIDE'] ) ?
490  $GLOBALS['GRAVITYVIEW_TESTS_WP_VERSION_OVERRIDE'] : $GLOBALS['wp_version'];
491  }
492 
493  /**
494  * Retrieve the current Gravity Forms version.
495  *
496  * Overridable with GRAVITYVIEW_TESTS_GF_VERSION_OVERRIDE during testing.
497  *
498  * @return string|null The version of Gravity Forms or null if inactive.
499  */
500  private function get_gravityforms_version() {
501  if ( ! class_exists( '\GFCommon' ) || ! empty( $GLOBALS['GRAVITYVIEW_TESTS_GF_INACTIVE_OVERRIDE'] ) ) {
502  gravityview()->log->error( 'Gravity Forms is inactive or not installed.' );
503  return null;
504  }
505 
506  return ! empty( $GLOBALS['GRAVITYVIEW_TESTS_GF_VERSION_OVERRIDE'] ) ?
507  $GLOBALS['GRAVITYVIEW_TESTS_GF_VERSION_OVERRIDE'] : \GFCommon::$version;
508  }
509 
510  /**
511  * Feature support detection.
512  *
513  * @param string $feature Feature name. Check FEATURE_* class constants.
514  *
515  * @return boolean
516  */
517  public function supports( $feature ) {
518  if ( ! is_null( $supports = apply_filters( "gravityview/plugin/feature/$feature", null ) ) ) {
519  return $supports;
520  }
521 
522  switch ( $feature ):
523  case self::FEATURE_GFQUERY:
524  return class_exists( '\GF_Query' );
525  case self::FEATURE_JOINS:
526  case self::FEATURE_UNIONS:
527  return apply_filters( 'gravityview/query/class', false ) === '\GF_Patched_Query';
528  case self::FEATURE_REST:
529  return class_exists( '\WP_REST_Controller' );
530  default:
531  return false;
532  endswitch;
533  }
534 
535  /**
536  * Delete GravityView Views, settings, roles, caps, etc.
537  *
538  * @return void
539  */
540  public function uninstall() {
541  global $wpdb;
542 
543  $suppress = $wpdb->suppress_errors();
544 
545  /**
546  * Posts.
547  */
548  $items = get_posts( array(
549  'post_type' => 'gravityview',
550  'post_status' => 'any',
551  'numberposts' => -1,
552  'fields' => 'ids'
553  ) );
554 
555  foreach ( $items as $item ) {
556  wp_delete_post( $item, true );
557  }
558 
559  /**
560  * Meta.
561  */
562  $tables = array();
563 
564  if ( version_compare( \GravityView_GFFormsModel::get_database_version(), '2.3-dev-1', '>=' ) ) {
565  $tables []= \GFFormsModel::get_entry_meta_table_name();
566  }
567  $tables []= \GFFormsModel::get_lead_meta_table_name();
568 
569  foreach ( $tables as $meta_table ) {
570  $sql = "
571  DELETE FROM $meta_table
572  WHERE (
573  `meta_key` = 'is_approved'
574  );
575  ";
576  $wpdb->query( $sql );
577  }
578 
579  /**
580  * Notes.
581  */
582  $tables = array();
583 
584  if ( version_compare( \GravityView_GFFormsModel::get_database_version(), '2.3-dev-1', '>=' ) && method_exists( 'GFFormsModel', 'get_entry_notes_table_name' ) ) {
585  $tables[] = \GFFormsModel::get_entry_notes_table_name();
586  }
587 
588  $tables[] = \GFFormsModel::get_lead_notes_table_name();
589 
590  $disapproved = __('Disapproved the Entry for GravityView', 'gravityview');
591  $approved = __('Approved the Entry for GravityView', 'gravityview');
592 
593  $suppress = $wpdb->suppress_errors();
594  foreach ( $tables as $notes_table ) {
595  $sql = $wpdb->prepare( "
596  DELETE FROM $notes_table
597  WHERE (
598  `note_type` = 'gravityview' OR
599  `value` = %s OR
600  `value` = %s
601  );
602  ", $approved, $disapproved );
603  $wpdb->query( $sql );
604  }
605 
606  $wpdb->suppress_errors( $suppress );
607 
608  /**
609  * Capabilities.
610  */
612 
613  /**
614  * Options.
615  */
616  delete_option( 'gravityview_cache_blacklist' );
617  delete_option( 'gv_version_upgraded_from' );
618  delete_transient( 'gravityview_edd-activate_valid' );
619  delete_transient( 'gravityview_edd-deactivate_valid' );
620  delete_transient( 'gravityview_dismissed_notices' );
621  delete_site_transient( 'gravityview_related_plugins' );
622  }
623 
624  private function __clone() { }
625 
626  private function __wakeup() { }
627 }
const GRAVITYVIEW_DIR
"GRAVITYVIEW_DIR" "./" The absolute path to the plugin directory, with trailing slash ...
Definition: gravityview.php:40
deactivate()
Plugin deactivation function.
If this file is called directly, abort.
get_php_version()
Retrieve the current PHP version.
uninstall()
Delete GravityView Views, settings, roles, caps, etc.
is_compatible_future_gravityforms()
Is this version of GravityView compatible with the future version of Gravity Forms?
get_wordpress_version()
Retrieve the current WordPress version.
static is_network_activated()
Check whether GravityView is network activated.
is_compatible_wordpress( $version=null)
Is this version of GravityView compatible with the current version of WordPress?
is_compatible_gravityforms()
Is this version of GravityView compatible with the current version of Gravity Forms?
is_compatible_future_php()
Is this version of GravityView compatible with the future required version of PHP?
gravityview()
Definition: _stubs.php:26
get_gravityforms_version()
Retrieve the current Gravity Forms version.
include_legacy_core()
Load more legacy core files.
dir( $path='')
Retrieve an absolute path within the GravityView plugin directory.
const GV_PLUGIN_VERSION(! defined( 'ABSPATH'))
Plugin Name: GravityView Plugin URI: https://gravityview.co Description: The best, easiest way to display Gravity Forms entries on your website.
Definition: gravityview.php:25
relpath( $path='')
Retrieve a relative path to the GravityView plugin directory from the WordPress plugin directory...
const GV_FUTURE_MIN_PHP_VERSION
Definition: gravityview.php:64
If this file is called directly, abort.
const GRAVITYVIEW_FILE
Full path to the GravityView file "GRAVITYVIEW_FILE" "./gravityview.php".
Definition: gravityview.php:31
const GV_FUTURE_MIN_GF_VERSION
GravityView will soon require at least this version of Gravity Forms to function properly.
Definition: gravityview.php:70
supports( $feature)
Feature support detection.
register_activation_hooks()
Register hooks that are fired when the plugin is activated and deactivated.
is_compatible()
Is everything compatible with this version of GravityView?
include_legacy_frontend( $force=false)
Include more legacy stuff.
is_compatible_php()
Is this version of GravityView compatible with the current version of PHP?
static get_database_version()
Make sure the method exists, regardless of GF version.
activate()
Plugin activation function.
url( $path='/')
Retrieve a URL within the GravityView plugin directory.
load_textdomain()
Load the translations.
const GV_MIN_GF_VERSION
GravityView requires at least this version of Gravity Forms to function properly. ...
Definition: gravityview.php:45
const GV_MIN_PHP_VERSION
GravityView requires at least this version of PHP to function properly.
Definition: gravityview.php:57
const GV_MIN_WP_VERSION
GravityView requires at least this version of WordPress to function properly.
Definition: gravityview.php:51