Total Upkeep – WordPress Backup Plugin plus Restore & Migrate by BoldGrid - Version 1.7.2

Version Description

Release date: Jan 15th, 2019

  • Update: Improved journey for downloading the premium plugin.
  • Update: Reduced the number of FTP connections made on the settings page.
  • Update: Overhauled this readme file, added more info on features and added screenshots.
  • Update: New system that asks user for bug fixes / new features, or requests plugin rating.
Download this release

Release Info

Developer boldgrid
Plugin Icon 128x128 Total Upkeep – WordPress Backup Plugin plus Restore & Migrate by BoldGrid
Version 1.7.2
Comparing to
See all releases

Code changes from version 1.7.1 to 1.7.2

Files changed (37) hide show
  1. admin/class-boldgrid-backup-admin-archive-details.php +10 -4
  2. admin/class-boldgrid-backup-admin-core.php +43 -0
  3. admin/class-boldgrid-backup-admin-go-pro.php +13 -3
  4. admin/class-boldgrid-backup-admin-support.php +49 -38
  5. admin/class-boldgrid-backup-admin-utility.php +1 -1
  6. admin/partials/boldgrid-backup-admin-archive-details.php +10 -8
  7. admin/remote/class-boldgrid-backup-admin-ftp-hooks.php +13 -1
  8. admin/remote/class-boldgrid-backup-admin-ftp.php +32 -15
  9. admin/remote/class-boldgrid-backup-admin-remote-settings.php +189 -0
  10. boldgrid-backup.php +6 -1
  11. build/clipboard.min.js +2 -2
  12. includes/class-boldgrid-backup.php +4 -0
  13. includes/config/config.plugin.php +11 -0
  14. includes/config/config.rating-prompt.php +133 -0
  15. readme.txt +45 -36
  16. vendor/autoload.php +1 -1
  17. vendor/boldgrid/library/README.md +22 -0
  18. vendor/boldgrid/library/src/Library/Activity.php +208 -0
  19. vendor/boldgrid/library/src/Library/Asset.php +29 -0
  20. vendor/boldgrid/library/src/Library/Plugin/Plugin.php +57 -0
  21. vendor/boldgrid/library/src/Library/RatingPrompt.php +525 -0
  22. vendor/boldgrid/library/src/Library/Views/Connect/AutoUpdates.php +3 -3
  23. vendor/boldgrid/library/src/Library/Views/KeyPrompt.php +19 -17
  24. vendor/boldgrid/library/src/assets/css/admin-icon.css +113 -0
  25. vendor/boldgrid/library/src/assets/css/admin.css +0 -116
  26. vendor/boldgrid/library/src/assets/css/api-notice.css +10 -4
  27. vendor/boldgrid/library/src/assets/css/rating-prompt.css +3 -0
  28. vendor/boldgrid/library/src/assets/js/api-notice.js +7 -1
  29. vendor/boldgrid/library/src/assets/js/rating-prompt.js +80 -0
  30. vendor/boldgrid/library/tests/Library/Library/test-activity.php +180 -0
  31. vendor/boldgrid/library/tests/Library/Library/test-rating-prompt.php +553 -0
  32. vendor/boldgrid/library/tests/Library/Plugin/test-plugin.php +62 -0
  33. vendor/boldgrid/library/tests/bootstrap.php +23 -19
  34. vendor/boldgrid/library/yarn.lock +84 -76
  35. vendor/composer/autoload_real.php +7 -7
  36. vendor/composer/autoload_static.php +4 -4
  37. vendor/composer/installed.json +6 -6
admin/class-boldgrid-backup-admin-archive-details.php CHANGED
@@ -190,18 +190,24 @@ class Boldgrid_Backup_Admin_Archive_Details {
190
  wp_send_json_error( __( 'Permission denied.', 'boldgrid-backup' ) );
191
  }
192
 
193
- $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : false; // phpcs:ignore WordPress.CSRF.NonceVerification
194
- $filepath = $this->core->backup_dir->get_path_to( $filename );
 
195
  if ( empty( $filename ) || ! $this->core->wp_filesystem->exists( $filepath ) ) {
196
  wp_send_json_error( __( 'Invalid archive filepath.', 'boldgrid-backup' ) );
197
  }
198
 
199
  $this->core->archive->init( $filepath );
200
 
201
- if ( ! empty( $_POST['attributes'] ) ) { // phpcs:ignore WordPress.CSRF.NonceVerification
202
- foreach ( $_POST['attributes'] as $key => $value ) { // phpcs:ignore WordPress.CSRF.NonceVerification
203
  $this->core->archive->set_attribute( $key, stripslashes( $value ) );
204
  }
 
 
 
 
 
205
  }
206
 
207
  wp_send_json_success();
190
  wp_send_json_error( __( 'Permission denied.', 'boldgrid-backup' ) );
191
  }
192
 
193
+ $attributes = ! empty( $_POST['attributes'] ) ? $_POST['attributes'] : array(); // phpcs:ignore WordPress.CSRF.NonceVerification
194
+ $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : false; // phpcs:ignore WordPress.CSRF.NonceVerification
195
+ $filepath = $this->core->backup_dir->get_path_to( $filename );
196
  if ( empty( $filename ) || ! $this->core->wp_filesystem->exists( $filepath ) ) {
197
  wp_send_json_error( __( 'Invalid archive filepath.', 'boldgrid-backup' ) );
198
  }
199
 
200
  $this->core->archive->init( $filepath );
201
 
202
+ if ( ! empty( $attributes ) ) {
203
+ foreach ( $attributes as $key => $value ) {
204
  $this->core->archive->set_attribute( $key, stripslashes( $value ) );
205
  }
206
+
207
+ // Take action if we've updated either the backup's title or description.
208
+ if ( ! empty( $attributes['title'] ) || ! empty( $attributes['description'] ) ) {
209
+ $this->core->activity->add( 'update_title_description', 1, $this->core->rating_prompt_config );
210
+ }
211
  }
212
 
213
  wp_send_json_success();
admin/class-boldgrid-backup-admin-core.php CHANGED
@@ -481,6 +481,15 @@ class Boldgrid_Backup_Admin_Core {
481
  */
482
  public $local;
483
 
 
 
 
 
 
 
 
 
 
484
  /**
485
  * The Restore Helper class.
486
  *
@@ -508,6 +517,15 @@ class Boldgrid_Backup_Admin_Core {
508
  */
509
  public $download;
510
 
 
 
 
 
 
 
 
 
 
511
  /**
512
  * Constructor.
513
  *
@@ -632,6 +650,15 @@ class Boldgrid_Backup_Admin_Core {
632
  if ( class_exists( '\Boldgrid\Library\Library\Ui' ) ) {
633
  $ui = new \Boldgrid\Library\Library\Ui();
634
  }
 
 
 
 
 
 
 
 
 
635
  }
636
 
637
  /**
@@ -683,6 +710,19 @@ class Boldgrid_Backup_Admin_Core {
683
  return $backup_identifier;
684
  }
685
 
 
 
 
 
 
 
 
 
 
 
 
 
 
686
  /**
687
  * Initialize the premium version of the plugin.
688
  *
@@ -1829,6 +1869,8 @@ class Boldgrid_Backup_Admin_Core {
1829
  )
1830
  );
1831
 
 
 
1832
  // Return the array of archive information.
1833
  return $info;
1834
  }
@@ -2526,6 +2568,7 @@ class Boldgrid_Backup_Admin_Core {
2526
  $filesize = $archives[ $download_key ]['filesize'];
2527
 
2528
  // Send the file and die nicely.
 
2529
  Boldgrid_Backup_File::send_file( $filepath, $filesize );
2530
  }
2531
 
481
  */
482
  public $local;
483
 
484
+ /**
485
+ * Path to our config.rating-prompt.php file.
486
+ *
487
+ * @since 1.7.2
488
+ * @access public
489
+ * @var string
490
+ */
491
+ public $rating_prompt_config;
492
+
493
  /**
494
  * The Restore Helper class.
495
  *
517
  */
518
  public $download;
519
 
520
+ /**
521
+ * An instance of the Boldgrid\Library\Library\Activity class.
522
+ *
523
+ * @since 1.7.2
524
+ * @access public
525
+ * @var Boldgrid\Library\Library\Activity
526
+ */
527
+ public $activity;
528
+
529
  /**
530
  * Constructor.
531
  *
650
  if ( class_exists( '\Boldgrid\Library\Library\Ui' ) ) {
651
  $ui = new \Boldgrid\Library\Library\Ui();
652
  }
653
+
654
+ // Setup library's Activity and RatingPrompt classes; init RatingPrompt to add necessary filters.
655
+ $this->rating_prompt_config = BOLDGRID_BACKUP_PATH . '/includes/config/config.rating-prompt.php';
656
+ if ( class_exists( '\Boldgrid\Library\Library\RatingPrompt' ) ) {
657
+ new \Boldgrid\Library\Library\RatingPrompt();
658
+ }
659
+ if ( class_exists( '\Boldgrid\Library\Library\Activity' ) ) {
660
+ $this->activity = new \Boldgrid\Library\Library\Activity( BOLDGRID_BACKUP_KEY );
661
+ }
662
  }
663
 
664
  /**
710
  return $backup_identifier;
711
  }
712
 
713
+ /**
714
+ * Get core.
715
+ *
716
+ * Callable via the boldgrid_backup_get_core filter.
717
+ *
718
+ * @since 1.7.2
719
+ *
720
+ * @return Boldgrid_Backup_Admin_Core object.
721
+ */
722
+ public function get_core() {
723
+ return $this;
724
+ }
725
+
726
  /**
727
  * Initialize the premium version of the plugin.
728
  *
1869
  )
1870
  );
1871
 
1872
+ $this->activity->add( 'any_backup_created', 1, $this->rating_prompt_config );
1873
+
1874
  // Return the array of archive information.
1875
  return $info;
1876
  }
2568
  $filesize = $archives[ $download_key ]['filesize'];
2569
 
2570
  // Send the file and die nicely.
2571
+ $this->activity->add( 'download_to_local_machine', 1, $this->rating_prompt_config );
2572
  Boldgrid_Backup_File::send_file( $filepath, $filesize );
2573
  }
2574
 
admin/class-boldgrid-backup-admin-go-pro.php CHANGED
@@ -70,8 +70,17 @@ class Boldgrid_Backup_Admin_Go_Pro {
70
  return;
71
  }
72
 
 
 
 
 
 
 
 
73
  $is_premium = $this->core->config->get_is_premium();
74
 
 
 
75
  $notices = array(
76
  array(
77
  'id' => 'boldgrid_backup_activate_premium',
@@ -99,12 +108,13 @@ class Boldgrid_Backup_Admin_Go_Pro {
99
  'id' => 'boldgrid_backup_download_premium',
100
  'show' => $is_premium && ! $this->core->config->is_premium_installed,
101
  'message' => '<p>' . sprintf(
102
- // translators: 1: URL address for BoldGrid Central.
103
  __(
104
- 'Hello there! We see that you have a <strong>Premium BoldGrid Connect Key</strong> and you have the <strong>BoldGrid Backup Plugin</strong> activated! Be sure to download the <strong>BoldGrid Backup Premium Extension</strong> from <a href="%1$s">BoldGrid Central</a> to gain access to more features!',
105
  'boldgrid-backup'
106
  ),
107
- 'https://www.boldgrid.com/central'
 
108
  ) . '</p>',
109
  ),
110
  );
70
  return;
71
  }
72
 
73
+ // Avoid a fatal error.
74
+ if ( ! class_exists( '\Boldgrid\Library\Library\Plugin\Plugin' ) ) {
75
+ $message = __( 'Class "Boldgrid\Library\Library\Plugin\Plugin" not found. Please ensure you are running the lastest version of the BoldGrid Library.', 'boldgrid-backup' );
76
+ $this->core->notice->boldgrid_backup_notice( $message );
77
+ return;
78
+ }
79
+
80
  $is_premium = $this->core->config->get_is_premium();
81
 
82
+ $premium_plugin = new \Boldgrid\Library\Library\Plugin\Plugin( 'boldgrid-backup-premium' );
83
+
84
  $notices = array(
85
  array(
86
  'id' => 'boldgrid_backup_activate_premium',
108
  'id' => 'boldgrid_backup_download_premium',
109
  'show' => $is_premium && ! $this->core->config->is_premium_installed,
110
  'message' => '<p>' . sprintf(
111
+ // translators: 1: URL address to download the BoldGrid Backup Premium plugin 2: URL to plugin-installer.php
112
  __(
113
+ 'Hello there! We see that you have a <strong>Premium BoldGrid Connect Key</strong> and you have the <strong>BoldGrid Backup Plugin</strong> activated! <a href="%1$s">Click here</a> to download the <strong>BoldGrid Backup Premium Extension</strong> and gain access to more features! After the download completes, go to <a href="%2$s">Plugins &raquo; Add New</a> and click the <em>Upload Plugin</em> button at the top of the page to upload your new plugin.',
114
  'boldgrid-backup'
115
  ),
116
+ $premium_plugin->getDownloadUrl(),
117
+ admin_url( 'plugin-install.php' )
118
  ) . '</p>',
119
  ),
120
  );
admin/class-boldgrid-backup-admin-support.php CHANGED
@@ -35,32 +35,37 @@ class Boldgrid_Backup_Admin_Support {
35
  * @param string $error Error message.
36
  */
37
  public function deactivate( $error ) {
38
- add_action( 'admin_notices', function () use ( $error ) {
39
- $allowed_html = array(
40
- 'p' => array(),
41
- 'strong' => array(),
42
- 'br' => array(),
43
- 'em' => array(),
44
- );
45
-
46
- $error = '<p>' . sprintf(
47
- /* translators: 1 and 2 are opening and closing string tags. */
48
- __( '%1$sBoldGrid Backup%2$s has been deactivated due to the following error:', 'boldgrid-backup' ),
49
- '<strong>',
50
- '</strong>' ) . '<br /><br />' . $error . '</p>';
51
-
52
- // Echo our admin notice. Hide the "plugin activated" notice.
53
- echo '
 
 
54
  <div class="notice notice-error is-dismissible">' . wp_kses( $error, $allowed_html ) . '</div>
55
  <style type="text/css">
56
  .updated.notice { display: none; }
57
  </style>
58
  ';
59
- } );
60
-
61
- add_action( 'admin_init', function() {
62
- deactivate_plugins( 'boldgrid-backup/boldgrid-backup.php', true );
63
- } );
 
 
 
64
  }
65
 
66
  /**
@@ -113,33 +118,39 @@ class Boldgrid_Backup_Admin_Support {
113
  */
114
  public function run_tests() {
115
  if ( ! $this->has_compatible_php() ) {
116
- $this->deactivate( sprintf(
117
- // Translators: 1: Current PHP version, 2: Minimum supported PHP version.
118
- __(
119
- 'Your PHP version (%1$s) is not supported. Please upgrade PHP to %2$s or higher, or contact your host for further assistance.',
120
- 'boldgrid-backup'
121
- ),
122
- PHP_VERSION,
123
- self::PHP_MIN_VER
124
- ) );
 
 
125
 
126
  return false;
127
  }
128
 
129
  if ( ! $this->has_composer_installed() ) {
130
- $this->deactivate( __(
131
- 'The vendor folder is missing. Please run "composer install", or contact your host for further assistance.',
132
- 'boldgrid-backup'
133
- ) );
 
 
134
 
135
  return false;
136
  }
137
 
138
  if ( ! $this->has_been_built() ) {
139
- $this->deactivate( __(
140
- 'The "build" folder is missing. Please run "yarn install" and "gulp", or contact your host for further assistance.',
141
- 'boldgrid-backup'
142
- ) );
 
 
143
 
144
  return false;
145
  }
35
  * @param string $error Error message.
36
  */
37
  public function deactivate( $error ) {
38
+ add_action(
39
+ 'admin_notices', function () use ( $error ) {
40
+ $allowed_html = array(
41
+ 'p' => array(),
42
+ 'strong' => array(),
43
+ 'br' => array(),
44
+ 'em' => array(),
45
+ );
46
+
47
+ $error = '<p>' . sprintf(
48
+ /* translators: 1 and 2 are opening and closing string tags. */
49
+ __( '%1$sBoldGrid Backup%2$s has been deactivated due to the following error:', 'boldgrid-backup' ),
50
+ '<strong>',
51
+ '</strong>'
52
+ ) . '<br /><br />' . $error . '</p>';
53
+
54
+ // Echo our admin notice. Hide the "plugin activated" notice.
55
+ echo '
56
  <div class="notice notice-error is-dismissible">' . wp_kses( $error, $allowed_html ) . '</div>
57
  <style type="text/css">
58
  .updated.notice { display: none; }
59
  </style>
60
  ';
61
+ }
62
+ );
63
+
64
+ add_action(
65
+ 'admin_init', function() {
66
+ deactivate_plugins( 'boldgrid-backup/boldgrid-backup.php', true );
67
+ }
68
+ );
69
  }
70
 
71
  /**
118
  */
119
  public function run_tests() {
120
  if ( ! $this->has_compatible_php() ) {
121
+ $this->deactivate(
122
+ sprintf(
123
+ // Translators: 1: Current PHP version, 2: Minimum supported PHP version.
124
+ __(
125
+ 'Your PHP version (%1$s) is not supported. Please upgrade PHP to %2$s or higher, or contact your host for further assistance.',
126
+ 'boldgrid-backup'
127
+ ),
128
+ PHP_VERSION,
129
+ self::PHP_MIN_VER
130
+ )
131
+ );
132
 
133
  return false;
134
  }
135
 
136
  if ( ! $this->has_composer_installed() ) {
137
+ $this->deactivate(
138
+ __(
139
+ 'The vendor folder is missing. Please run "composer install", or contact your host for further assistance.',
140
+ 'boldgrid-backup'
141
+ )
142
+ );
143
 
144
  return false;
145
  }
146
 
147
  if ( ! $this->has_been_built() ) {
148
+ $this->deactivate(
149
+ __(
150
+ 'The "build" folder is missing. Please run "yarn install" and "gulp", or contact your host for further assistance.',
151
+ 'boldgrid-backup'
152
+ )
153
+ );
154
 
155
  return false;
156
  }
admin/class-boldgrid-backup-admin-utility.php CHANGED
@@ -503,7 +503,7 @@ class Boldgrid_Backup_Admin_Utility {
503
  *
504
  * @global string $pagenow
505
  *
506
- * @param string $page The page to check for in $_GET.
507
  * @return boolean
508
  */
509
  public static function is_admin_page( $page ) {
503
  *
504
  * @global string $pagenow
505
  *
506
+ * @param string $page The page to check for in $_GET.
507
  * @return boolean
508
  */
509
  public static function is_admin_page( $page ) {
admin/partials/boldgrid-backup-admin-archive-details.php CHANGED
@@ -107,14 +107,16 @@ if ( ! $archive_found ) {
107
  <p>
108
  <em>
109
  ' .
110
- wp_kses( sprintf(
111
- // translators: 1: HTML anchor open tags, 2: HTML close tag, 3: HTML anchor open tags, 4: HTML close tag.
112
- __( 'Protect this backup from being deleted due to %1$sretention settings%2$s. Applies only to backups stored on your %3$sWeb Server%4$s.', 'boldgrid-backup' ),
113
- '<a href="' . get_admin_url( null, 'admin.php?page=boldgrid-backup-settings&section=section_storage' ) . '">',
114
- '</a>',
115
- '<a href="' . get_admin_url( null, 'admin.php?page=boldgrid-backup-tools&section=section_locations' ) . '">',
116
- '</a>'
117
- ), $allowed_html ) . '
 
 
118
  </em>
119
  </p>
120
  <select name="backup_protect">
107
  <p>
108
  <em>
109
  ' .
110
+ wp_kses(
111
+ sprintf(
112
+ // translators: 1: HTML anchor open tags, 2: HTML close tag, 3: HTML anchor open tags, 4: HTML close tag.
113
+ __( 'Protect this backup from being deleted due to %1$sretention settings%2$s. Applies only to backups stored on your %3$sWeb Server%4$s.', 'boldgrid-backup' ),
114
+ '<a href="' . get_admin_url( null, 'admin.php?page=boldgrid-backup-settings&section=section_storage' ) . '">',
115
+ '</a>',
116
+ '<a href="' . get_admin_url( null, 'admin.php?page=boldgrid-backup-tools&section=section_locations' ) . '">',
117
+ '</a>'
118
+ ), $allowed_html
119
+ ) . '
120
  </em>
121
  </p>
122
  <select name="backup_protect">
admin/remote/class-boldgrid-backup-admin-ftp-hooks.php CHANGED
@@ -165,7 +165,7 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
165
  * @param array $storage_locations Storage locations.
166
  */
167
  public function register_storage_location( $storage_locations ) {
168
- $storage_locations[] = $this->core->ftp->get_details();
169
 
170
  return $storage_locations;
171
  }
@@ -191,6 +191,18 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
191
  );
192
  }
193
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  /**
195
  * Upload a file (triggered by jobs queue).
196
  *
165
  * @param array $storage_locations Storage locations.
166
  */
167
  public function register_storage_location( $storage_locations ) {
168
+ $storage_locations[] = $this->core->ftp->get_details( true );
169
 
170
  return $storage_locations;
171
  }
191
  );
192
  }
193
 
194
+ /**
195
+ * Hook into WordPress' shutdown action and close any open FTP connections.
196
+ *
197
+ * Closing the connections now, rather than when we're done with a specific ftp action, will
198
+ * eliminate numerous ftp connections being opened on a single admin page.
199
+ *
200
+ * @since 1.7.2
201
+ */
202
+ public function shutdown() {
203
+ $this->core->ftp->disconnect();
204
+ }
205
+
206
  /**
207
  * Upload a file (triggered by jobs queue).
208
  *
admin/remote/class-boldgrid-backup-admin-ftp.php CHANGED
@@ -142,6 +142,15 @@ class Boldgrid_Backup_Admin_Ftp {
142
  */
143
  public $retention_count = 5;
144
 
 
 
 
 
 
 
 
 
 
145
  /**
146
  * Default timeout.
147
  *
@@ -209,9 +218,10 @@ class Boldgrid_Backup_Admin_Ftp {
209
  public function __construct( $core ) {
210
  include_once BOLDGRID_BACKUP_PATH . '/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php';
211
 
212
- $this->core = $core;
213
- $this->hooks = new Boldgrid_Backup_Admin_Ftp_Hooks( $core );
214
- $this->page = new Boldgrid_Backup_Admin_Ftp_Page( $core );
 
215
  }
216
 
217
  /**
@@ -611,9 +621,12 @@ class Boldgrid_Backup_Admin_Ftp {
611
  * Get settings.
612
  *
613
  * @since 1.6.0
 
 
 
614
  */
615
- public function get_details() {
616
- $is_setup = $this->is_setup();
617
 
618
  $settings = $this->core->settings->get_settings();
619
 
@@ -691,16 +704,24 @@ class Boldgrid_Backup_Admin_Ftp {
691
  *
692
  * @since 1.6.0
693
  *
 
 
 
 
694
  * @return bool
695
  */
696
- public function is_setup() {
 
 
 
 
 
 
697
  $this->connect();
698
  $this->log_in();
699
 
700
  $logged_in = $this->logged_in;
701
 
702
- $this->disconnect();
703
-
704
  return $logged_in;
705
  }
706
 
@@ -823,11 +844,10 @@ class Boldgrid_Backup_Admin_Ftp {
823
  break;
824
  }
825
 
826
- // If we tried to login and it failed, disconnect.
827
- if ( ! $this->logged_in ) {
828
- $this->disconnect();
829
- } else {
830
  $this->maybe_passive();
 
 
831
  }
832
  }
833
 
@@ -939,7 +959,6 @@ class Boldgrid_Backup_Admin_Ftp {
939
  if ( ! $uploaded ) {
940
  $last_error = error_get_last();
941
 
942
- $this->disconnect();
943
  $this->errors[] = __( 'Unable to upload file.', 'boldgrid-backup' );
944
 
945
  /*
@@ -956,8 +975,6 @@ class Boldgrid_Backup_Admin_Ftp {
956
 
957
  $this->enforce_retention();
958
 
959
- $this->disconnect();
960
-
961
  return true;
962
  }
963
  }
142
  */
143
  public $retention_count = 5;
144
 
145
+ /**
146
+ * Settings class.
147
+ *
148
+ * @since 1.7.2
149
+ * @access public
150
+ * @var Boldgrid_Backup_Admin_Remote_Settings
151
+ */
152
+ public $settings;
153
+
154
  /**
155
  * Default timeout.
156
  *
218
  public function __construct( $core ) {
219
  include_once BOLDGRID_BACKUP_PATH . '/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php';
220
 
221
+ $this->core = $core;
222
+ $this->hooks = new Boldgrid_Backup_Admin_Ftp_Hooks( $core );
223
+ $this->page = new Boldgrid_Backup_Admin_Ftp_Page( $core );
224
+ $this->settings = new Boldgrid_Backup_Admin_Remote_Settings( $this->key );
225
  }
226
 
227
  /**
621
  * Get settings.
622
  *
623
  * @since 1.6.0
624
+ *
625
+ * @param bool $try_cache Whether or not to use last_login to validate the ftp account. Please
626
+ * see param definition in $this->is_setup().
627
  */
628
+ public function get_details( $try_cache = false ) {
629
+ $is_setup = $this->is_setup( $try_cache );
630
 
631
  $settings = $this->core->settings->get_settings();
632
 
704
  *
705
  * @since 1.6.0
706
  *
707
+ * @param bool $try_cache Whether or not to use the last_login value to determine if we are
708
+ * setup. For example, if $try_cache and we logged in an hour ago, no
709
+ * need to try to connect and log in again, we logged in an hour ago so
710
+ * assume all is still good.
711
  * @return bool
712
  */
713
+ public function is_setup( $try_cache = false ) {
714
+
715
+ // If successfully logged in within last 24 hours, return true.
716
+ if ( $try_cache && $this->settings->is_last_login_valid() ) {
717
+ return true;
718
+ }
719
+
720
  $this->connect();
721
  $this->log_in();
722
 
723
  $logged_in = $this->logged_in;
724
 
 
 
725
  return $logged_in;
726
  }
727
 
844
  break;
845
  }
846
 
847
+ if ( $this->logged_in ) {
 
 
 
848
  $this->maybe_passive();
849
+
850
+ $this->settings->set_last_login();
851
  }
852
  }
853
 
959
  if ( ! $uploaded ) {
960
  $last_error = error_get_last();
961
 
 
962
  $this->errors[] = __( 'Unable to upload file.', 'boldgrid-backup' );
963
 
964
  /*
975
 
976
  $this->enforce_retention();
977
 
 
 
978
  return true;
979
  }
980
  }
admin/remote/class-boldgrid-backup-admin-remote-settings.php ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-remote-settings.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.7.2
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/remote
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Remote_Settings
17
+ *
18
+ * The purpose of this class is to handle remote settings stored in the database. This class was
19
+ * introduced as of 1.7.2, however prior code working with settings has not been refactored to use
20
+ * this class.
21
+ *
22
+ * The remote settings are stored in the boldgrid_backup_settings option, such as:
23
+ * boldgrid_backup_settings['remote']['ftp']['host']
24
+ *
25
+ * @since 1.7.2
26
+ */
27
+ class Boldgrid_Backup_Admin_Remote_Settings {
28
+ /**
29
+ * Our remote_id.
30
+ *
31
+ * For example, the 'ftp' in boldgrid_backup_settings['remote']['ftp'].
32
+ *
33
+ * @since 1.7.2
34
+ * @access private
35
+ * @var string
36
+ */
37
+ private $remote_id;
38
+
39
+ /**
40
+ * The settings key that stores the last successful login.
41
+ *
42
+ * For example, the last_login in boldgrid_backup_settings['remote']['ftp']['last_login'].
43
+ *
44
+ * @since 1.7.2
45
+ * @access private
46
+ * @var string
47
+ */
48
+ private $last_login_key = 'last_login';
49
+
50
+ /**
51
+ * The WordPress option that stores boldgrid backup settings.
52
+ *
53
+ * @since 1.7.2
54
+ * @access private
55
+ * @var string
56
+ */
57
+ private $option_name = 'boldgrid_backup_settings';
58
+
59
+ /**
60
+ * The key within our settings option that contains all remote settings.
61
+ *
62
+ * For example, the 'remote' in boldgrid_backup_settings['remote']['ftp'].
63
+ *
64
+ * @since 1.7.2
65
+ * @access private
66
+ * @var string
67
+ */
68
+ private $remote_key = 'remote';
69
+
70
+ /**
71
+ * Constructor.
72
+ *
73
+ * @since 1.7.2
74
+ *
75
+ * @param string $remote_id The remote id, such as 'ftp' or 'amazon_s3'.
76
+ */
77
+ public function __construct( $remote_id ) {
78
+ $this->remote_id = $remote_id;
79
+ }
80
+
81
+ /**
82
+ * Get the time we last logged in successfully.
83
+ *
84
+ * @since 1.7.2
85
+ *
86
+ * @return int
87
+ */
88
+ public function get_last_login() {
89
+ return $this->get_setting( $this->last_login_key, 0 );
90
+ }
91
+
92
+ /**
93
+ * Get our boldgrid_backup_settings option.
94
+ *
95
+ * @since 1.7.2
96
+ *
97
+ * @return array
98
+ */
99
+ public function get_option() {
100
+ return get_option( $this->option_name, array() );
101
+ }
102
+
103
+ /**
104
+ * Get one setting.
105
+ *
106
+ * @since 1.7.2
107
+ *
108
+ * @param string $key The key of the setting.
109
+ * @param mixed $default The default value if one does not exist.
110
+ * @return mixed
111
+ */
112
+ public function get_setting( $key, $default = false ) {
113
+ $settings = $this->get_settings();
114
+
115
+ return isset( $settings[ $key ] ) ? $settings[ $key ] : $default;
116
+ }
117
+
118
+ /**
119
+ * Get our remote_id's settings.
120
+ *
121
+ * For example, if our remote_id is 'ftp', return all of our ftp settings.
122
+ *
123
+ * @since 1.7.2
124
+ *
125
+ * @return array
126
+ */
127
+ public function get_settings() {
128
+ $option = $this->get_option();
129
+
130
+ $settings = ! empty( $option[ $this->remote_key ][ $this->remote_id ] ) ? $option[ $this->remote_key ][ $this->remote_id ] : array();
131
+
132
+ return $settings;
133
+ }
134
+
135
+ /**
136
+ * Determine whether or not our last login is within the last_login_lifetime range.
137
+ *
138
+ * Please see comments for last_login_lifetime within the plugin's config file.
139
+ *
140
+ * @since 1.7.2
141
+ *
142
+ * @return bool
143
+ */
144
+ public function is_last_login_valid() {
145
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
146
+
147
+ return $this->get_last_login() + $core->configs['last_login_lifetime'] >= time();
148
+ }
149
+
150
+ /**
151
+ * Set and save a setting.
152
+ *
153
+ * @since 1.7.2
154
+ *
155
+ * @param string $key
156
+ * @param mixed $value
157
+ */
158
+ public function save_setting( $key, $value ) {
159
+ $settings = $this->get_settings();
160
+
161
+ $settings[ $key ] = $value;
162
+
163
+ $this->save_settings( $settings );
164
+ }
165
+
166
+ /**
167
+ * Save our remote_id's settings.
168
+ *
169
+ * @since 1.7.2
170
+ *
171
+ * @param array $settings An array containing our remote_id's settings.
172
+ */
173
+ public function save_settings( $settings ) {
174
+ $option = $this->get_option();
175
+
176
+ $option[ $this->remote_key ][ $this->remote_id ] = $settings;
177
+
178
+ update_option( $this->option_name, $option );
179
+ }
180
+
181
+ /**
182
+ * Set the time that we last logged in successfully.
183
+ *
184
+ * @since 1.7.2
185
+ */
186
+ public function set_last_login() {
187
+ $this->save_setting( $this->last_login_key, time() );
188
+ }
189
+ }
boldgrid-backup.php CHANGED
@@ -16,7 +16,7 @@
16
  * Plugin Name: BoldGrid Backup
17
  * Plugin URI: https://www.boldgrid.com/boldgrid-backup/
18
  * Description: BoldGrid Backup provides WordPress backup and restoration with update protection.
19
- * Version: 1.7.1
20
  * Author: BoldGrid
21
  * Author URI: https://www.boldgrid.com/
22
  * License: GPL-2.0+
@@ -40,6 +40,11 @@ if ( ! defined( 'BOLDGRID_BACKUP_PATH' ) ) {
40
  define( 'BOLDGRID_BACKUP_PATH', dirname( __FILE__ ) );
41
  }
42
 
 
 
 
 
 
43
  /**
44
  * The code that runs during plugin activation.
45
  * This action is documented in includes/class-boldgrid-backup-activator.php
16
  * Plugin Name: BoldGrid Backup
17
  * Plugin URI: https://www.boldgrid.com/boldgrid-backup/
18
  * Description: BoldGrid Backup provides WordPress backup and restoration with update protection.
19
+ * Version: 1.7.2
20
  * Author: BoldGrid
21
  * Author URI: https://www.boldgrid.com/
22
  * License: GPL-2.0+
40
  define( 'BOLDGRID_BACKUP_PATH', dirname( __FILE__ ) );
41
  }
42
 
43
+ // Define boldgrid-backup key.
44
+ if ( ! defined( 'BOLDGRID_BACKUP_KEY' ) ) {
45
+ define( 'BOLDGRID_BACKUP_KEY', 'boldgrid-backup' );
46
+ }
47
+
48
  /**
49
  * The code that runs during plugin activation.
50
  * This action is documented in includes/class-boldgrid-backup-activator.php
build/clipboard.min.js CHANGED
@@ -1,7 +1,7 @@
1
  /*!
2
- * clipboard.js v2.0.1
3
  * https://zenorocha.github.io/clipboard.js
4
  *
5
  * Licensed MIT © Zeno Rocha
6
  */
7
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(t){function e(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,o){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:o})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=3)}([function(t,e,n){var o,r,i;!function(a,c){r=[t,n(7)],o=c,void 0!==(i="function"==typeof o?o.apply(e,r):o)&&(t.exports=i)}(0,function(t,e){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var o=function(t){return t&&t.__esModule?t:{default:t}}(e),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),a=function(){function t(e){n(this,t),this.resolveOptions(e),this.initSelection()}return i(t,[{key:"resolveOptions",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var t=this,e="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,o.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,o.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==(void 0===t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}]),t}();t.exports=a})},function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return r(t,e,n);if(c.nodeList(t))return i(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function r(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function i(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return u(document.body,t,e,n)}var c=n(6),u=n(5);t.exports=o},function(t,e){function n(){}n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){r.off(t,o),e.apply(n,arguments)}var r=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;for(o;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,a=o.length;i<a;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},t.exports=n},function(t,e,n){var o,r,i;!function(a,c){r=[t,n(0),n(2),n(1)],o=c,void 0!==(i="function"==typeof o?o.apply(e,r):o)&&(t.exports=i)}(0,function(t,e,n,o){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function a(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function c(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function u(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}var l=r(e),s=r(n),f=r(o),d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},h=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),p=function(t){function e(t,n){i(this,e);var o=a(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return o.resolveOptions(n),o.listenClick(t),o}return c(e,t),h(e,[{key:"resolveOptions",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===d(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,f.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return u("action",t)}},{key:"defaultTarget",value:function(t){var e=u("target",t);if(e)return document.querySelector(e)}},{key:"defaultText",value:function(t){return u("text",t)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),e}(s.default);t.exports=p})},function(t,e){function n(t,e){for(;t&&t.nodeType!==o;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}var o=9;if("undefined"!=typeof Element&&!Element.prototype.matches){var r=Element.prototype;r.matches=r.matchesSelector||r.mozMatchesSelector||r.msMatchesSelector||r.oMatchesSelector||r.webkitMatchesSelector}t.exports=n},function(t,e,n){function o(t,e,n,o,r){var a=i.apply(this,arguments);return t.addEventListener(n,a,r),{destroy:function(){t.removeEventListener(n,a,r)}}}function r(t,e,n,r,i){return"function"==typeof t.addEventListener?o.apply(null,arguments):"function"==typeof n?o.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return o(t,e,n,r,i)}))}function i(t,e,n,o){return function(n){n.delegateTarget=a(n.target,e),n.delegateTarget&&o.call(t,n)}}var a=n(4);t.exports=r},function(t,e){e.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},e.nodeList=function(t){var n=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===n||"[object HTMLCollection]"===n)&&"length"in t&&(0===t.length||e.node(t[0]))},e.string=function(t){return"string"==typeof t||t instanceof String},e.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},function(t,e){function n(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()}return e}t.exports=n}])});
1
  /*!
2
+ * clipboard.js v2.0.4
3
  * https://zenorocha.github.io/clipboard.js
4
  *
5
  * Licensed MIT © Zeno Rocha
6
  */
7
+ !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=o(n(1)),c=o(n(3)),u=o(n(4));function o(t){return t&&t.__esModule?t:{default:t}}var l=function(t){function o(t,e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,o);var n=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,(o.__proto__||Object.getPrototypeOf(o)).call(this));return n.resolveOptions(e),n.listenClick(t),n}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(o,c.default),i(o,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===r(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,u.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new a.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return s("action",t)}},{key:"defaultTarget",value:function(t){var e=s("target",t);if(e)return document.querySelector(e)}},{key:"defaultText",value:function(t){return s("text",t)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),o}();function s(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}t.exports=l},function(t,e,n){"use strict";var o,r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=n(2),c=(o=a)&&o.__esModule?o:{default:o};var u=function(){function e(t){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),this.resolveOptions(t),this.initSelection()}return i(e,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var t=this,e="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,c.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,c.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==(void 0===t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}]),e}();t.exports=u},function(t,e){t.exports=function(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()}return e}},function(t,e){function n(){}n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)}return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,a=o.length;i<a;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},t.exports=n},function(t,e,n){var d=n(5),h=n(6);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!d.string(e))throw new TypeError("Second argument must be a String");if(!d.fn(n))throw new TypeError("Third argument must be a Function");if(d.node(t))return s=e,f=n,(l=t).addEventListener(s,f),{destroy:function(){l.removeEventListener(s,f)}};if(d.nodeList(t))return a=t,c=e,u=n,Array.prototype.forEach.call(a,function(t){t.addEventListener(c,u)}),{destroy:function(){Array.prototype.forEach.call(a,function(t){t.removeEventListener(c,u)})}};if(d.string(t))return o=t,r=e,i=n,h(document.body,o,r,i);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var o,r,i,a,c,u,l,s,f}},function(t,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},function(t,e,n){var a=n(7);function i(t,e,n,o,r){var i=function(e,n,t,o){return function(t){t.delegateTarget=a(t.target,n),t.delegateTarget&&o.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,r),{destroy:function(){t.removeEventListener(n,i,r)}}}t.exports=function(t,e,n,o,r){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,o,r)}))}},function(t,e){if("undefined"!=typeof Element&&!Element.prototype.matches){var n=Element.prototype;n.matches=n.matchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector||n.webkitMatchesSelector}t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}}])});
includes/class-boldgrid-backup.php CHANGED
@@ -210,6 +210,7 @@ class Boldgrid_Backup {
210
  require_once BOLDGRID_BACKUP_PATH . '/admin/remote/class-boldgrid-backup-admin-ftp.php';
211
  require_once BOLDGRID_BACKUP_PATH . '/admin/remote/class-boldgrid-backup-admin-ftp-hooks.php';
212
  require_once BOLDGRID_BACKUP_PATH . '/admin/remote/class-boldgrid-backup-admin-ftp-page.php';
 
213
 
214
  require_once BOLDGRID_BACKUP_PATH . '/admin/class-boldgrid-backup-admin-go-pro.php';
215
 
@@ -391,6 +392,7 @@ class Boldgrid_Backup {
391
  $this->loader->add_action( 'wp_ajax_boldgrid_backup_remote_storage_download_ftp', $plugin_admin_core->ftp->hooks, 'wp_ajax_download' );
392
  // Styles and Scripts for FTP settings page.
393
  $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin_core->ftp->page, 'enqueue_scripts' );
 
394
 
395
  $this->loader->add_action( 'admin_notices', $plugin_admin_core->go_pro, 'admin_notice_setup' );
396
 
@@ -428,6 +430,8 @@ class Boldgrid_Backup {
428
 
429
  $this->loader->add_action( 'admin_menu', $plugin_admin_core->local, 'add_submenus' );
430
  $this->loader->add_action( 'wp_ajax_boldgrid_backup_is_setup_local', $plugin_admin_core->local, 'is_setup_ajax' );
 
 
431
  }
432
 
433
  /**
210
  require_once BOLDGRID_BACKUP_PATH . '/admin/remote/class-boldgrid-backup-admin-ftp.php';
211
  require_once BOLDGRID_BACKUP_PATH . '/admin/remote/class-boldgrid-backup-admin-ftp-hooks.php';
212
  require_once BOLDGRID_BACKUP_PATH . '/admin/remote/class-boldgrid-backup-admin-ftp-page.php';
213
+ require_once BOLDGRID_BACKUP_PATH . '/admin/remote/class-boldgrid-backup-admin-remote-settings.php';
214
 
215
  require_once BOLDGRID_BACKUP_PATH . '/admin/class-boldgrid-backup-admin-go-pro.php';
216
 
392
  $this->loader->add_action( 'wp_ajax_boldgrid_backup_remote_storage_download_ftp', $plugin_admin_core->ftp->hooks, 'wp_ajax_download' );
393
  // Styles and Scripts for FTP settings page.
394
  $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin_core->ftp->page, 'enqueue_scripts' );
395
+ $this->loader->add_filter( 'shutdown', $plugin_admin_core->ftp->hooks, 'shutdown' );
396
 
397
  $this->loader->add_action( 'admin_notices', $plugin_admin_core->go_pro, 'admin_notice_setup' );
398
 
430
 
431
  $this->loader->add_action( 'admin_menu', $plugin_admin_core->local, 'add_submenus' );
432
  $this->loader->add_action( 'wp_ajax_boldgrid_backup_is_setup_local', $plugin_admin_core->local, 'is_setup_ajax' );
433
+
434
+ $this->loader->add_filter( 'boldgrid_backup_get_core', $plugin_admin_core, 'get_core' );
435
  }
436
 
437
  /**
includes/config/config.plugin.php CHANGED
@@ -38,4 +38,15 @@ return array(
38
  ),
39
  'public_link_lifetime' => '1 HOUR',
40
  'url_regex' => '^https?:\/\/[a-z0-9\-\.]+(\.[a-z]{2,5})?(:[0-9]{1,5})?(\/.*)?$',
 
 
 
 
 
 
 
 
 
 
 
41
  );
38
  ),
39
  'public_link_lifetime' => '1 HOUR',
40
  'url_regex' => '^https?:\/\/[a-z0-9\-\.]+(\.[a-z]{2,5})?(:[0-9]{1,5})?(\/.*)?$',
41
+ /*
42
+ * When we login to a remote storage provider, we log the utc timestamp of that login. Sometimes
43
+ * we want to know if a remote storage provider is setup, and usually we check by trying to log
44
+ * in successfully. To skip having to log in, we can simply check the last time we logged in.
45
+ * For example, if we logged in 2 hours ago, usually we can say that the remote storage is setup
46
+ * correctly because we logged in successfully just 2 hours prior. last_login_lifetime specifies
47
+ * this time limit. If we logged in within 'last_login_lifetime' ago, assume the remote storage
48
+ * is still setup successfully. This is not across the board though, each storage provider must
49
+ * setup this last login cache and check against it.
50
+ */
51
+ 'last_login_lifetime' => DAY_IN_SECONDS,
52
  );
includes/config/config.rating-prompt.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: config.activity.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.7.2
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/includes
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ *
14
+ * @link https://github.com/BoldGrid/library/wiki/Library-RatingPrompt
15
+ */
16
+
17
+ // Prevent direct calls.
18
+ if ( ! defined( 'WPINC' ) ) {
19
+ header( 'Status: 403 Forbidden' );
20
+ header( 'HTTP/1.1 403 Forbidden' );
21
+ exit();
22
+ }
23
+
24
+ $allowed_tags = array(
25
+ 'a' => array(
26
+ 'href' => array(),
27
+ 'target' => array(),
28
+ ),
29
+ );
30
+
31
+ $lang = array(
32
+ 'feel_good_value' => __( 'If you feel you\'re getting really good value from the BoldGrid Backup plugin, could you do us a favor and rate us 5 stars on WordPress?', 'boldgrid-backup' ),
33
+ );
34
+
35
+ $default_prompt = array(
36
+ 'plugin' => BOLDGRID_BACKUP_KEY,
37
+ 'name' => 'REPLACE_THIS_NAME',
38
+ 'slides' => array(
39
+ 'start' => array(
40
+ 'text' => $lang['feel_good_value'],
41
+ /*
42
+ * Decisions
43
+ *
44
+ * @param string text The text used as the decision.
45
+ * @param string link A link to navigate to if the decision is clicked.
46
+ * @param string slide The name of a slide to show after clicking this decision.
47
+ * @param int snooze A number to indicate how long a prompt should be snoozed for if
48
+ * the decision
49
+ * is selected. If no snooze is set, the decision will dismiss the
50
+ * prompt.
51
+ */
52
+ 'decisions' => array(
53
+ 'sure_will' => array(
54
+ 'text' => __( 'Yes, I sure will!', 'boldgrid-backup' ),
55
+ 'link' => 'https://wordpress.org/support/plugin/boldgrid-backup/reviews/',
56
+ 'slide' => 'thanks',
57
+ ),
58
+ 'maybe_still_testing' => array(
59
+ 'text' => __( 'Maybe later, I\'m still testing the plugin.', 'boldgrid-backup' ),
60
+ 'snooze' => WEEK_IN_SECONDS,
61
+ 'slide' => 'maybe_later',
62
+ ),
63
+ 'already_did' => array(
64
+ 'text' => __( 'I already did', 'boldgrid-backup' ),
65
+ 'slide' => 'already_did',
66
+ ),
67
+ ),
68
+ ),
69
+ 'thanks' => array(
70
+ 'text' => sprintf(
71
+ wp_kses(
72
+ /* translators: The URL to the boldgrid-backup plugin in the plugin repo. */
73
+ __( 'Thanks! A new page should have opened to the BoldGrid Backup ratings page on WordPress.org. You will need to log in to your WordPress.org account before you can post a review. If the page didn\'t open, please click the following link: <a href="%1$s" target="_blank">%1$s</a>', 'boldgrid-backup' ),
74
+ $allowed_tags
75
+ ),
76
+ 'https://wordpress.org/support/plugin/boldgrid-backup/reviews/'
77
+ ),
78
+ ),
79
+ 'maybe_later' => array(
80
+ 'text' => sprintf(
81
+ wp_kses(
82
+ /* translators: The URL to submit boldgrid-backup bug reports and feature requests. */
83
+ __( 'No problem, maybe now is not a good time. We want to be your WordPress backup plugin of choice. If you\'re experiencing a problem or want to make a suggestion, please %1$sclick here%2$s.', 'boldgrid-backup' ),
84
+ $allowed_tags
85
+ ),
86
+ '<a href="https://www.boldgrid.com/feedback" target="_blank">',
87
+ '</a>'
88
+ ),
89
+ ),
90
+ 'already_did' => array(
91
+ 'text' => sprintf(
92
+ wp_kses(
93
+ /* translators: The URL to submit boldgrid-backup bug reports and feature requests. */
94
+ __( 'Thank you for the previous rating! You can help us to continue improving the BoldGrid Backup plugin by reporting any bugs or submitting feature requests %1$shere%2$s. Thank you for using the BoldGrid Backup plugin!', 'boldgrid-backup' ),
95
+ $allowed_tags
96
+ ),
97
+ '<a href="https://www.boldgrid.com/feedback" target="_blank">',
98
+ '</a>'
99
+ ),
100
+ ),
101
+ ),
102
+ );
103
+
104
+ // Set a title or description for your backup.
105
+ $title_description_prompt = $default_prompt;
106
+ $title_description_prompt['name'] = 'update_title_description';
107
+ $title_description_prompt['slides']['start']['text'] = __( 'We hope that you\'re finding adding titles and descriptions to your backups helpful in keeping things organized.', 'boldgrid-backup' ) . ' ' . $lang['feel_good_value'];
108
+
109
+ // Download a backup to your local machine.
110
+ $download_prompt = $default_prompt;
111
+ $download_prompt['name'] = 'download_to_local_machine';
112
+ $download_prompt['slides']['start']['text'] = __( 'We\'re glad to see you\'re keeping your backups safe and downloading them to your local machine!', 'boldgrid-backup' ) . ' ' . $lang['feel_good_value'];
113
+
114
+ // Create any type of backup.
115
+ $any_backup_prompt = $default_prompt;
116
+ $any_backup_prompt['name'] = 'any_backup_created';
117
+ $any_backup_prompt['slides']['start']['text'] = __( 'It looks like you\'ve created 10 backups with the BoldGrid Backup Plugin!', 'boldgrid-backup' ) . ' ' . $lang['feel_good_value'];
118
+
119
+ return array(
120
+ 'update_title_description' => array(
121
+ 'threshold' => 10,
122
+ 'prompt' => $title_description_prompt,
123
+ ),
124
+ 'download_to_local_machine' => array(
125
+ 'threshold' => 2,
126
+ 'prompt' => $download_prompt,
127
+ ),
128
+
129
+ 'any_backup_created' => array(
130
+ 'threshold' => 10,
131
+ 'prompt' => $any_backup_prompt,
132
+ ),
133
+ );
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: boldgrid, joemoto, imh_brad, rramo012, timph, bgnicolepaschen
3
  Tags: boldgrid, backup, restore, migrate, migration
4
  Requires at least: 4.4
5
- Tested up to: 5.0.2
6
  Requires PHP: 5.4
7
- Stable tag: 1.7.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -12,7 +12,9 @@ BoldGrid Backup provides WordPress backup and restoration with update protection
12
 
13
  == Description ==
14
 
15
- The BoldGrid Backup Plugin will backup your entire WordPress site with just a couple of clicks right in your WordPress dashboard. Just select a time and day for backups to run automatically. Or manually create a backup at any time with a single click.
 
 
16
 
17
  == Features ==
18
 
@@ -41,8 +43,8 @@ The following features are available, of which you can find additional info for
41
  1. Easily schedule backups using Cron or WP Cron. Set a time of day, select the days of the week, and BoldGrid Backup will automate backups for you. You will receive an email after each backup has been completed.
42
  2. Automatically perform a backup before WordPress auto updates itself. This feature hooks into the [pre_auto_update](https://developer.wordpress.org/reference/hooks/pre_auto_update/) action.
43
  3. After a scheduled backup completes, you can have it uploaded automatically to an FTP / SFTP server. Users who upgrade to premium can also store backups on Amazon S3.
44
- 4. You can configure which files and folders and included in your backups. "Include" and "Exclude" filters are easy to set up, and you can click the "Preview" button to get a listing of which files and folders will actually be included in your backup.
45
- 5. Have tables you don't want to back up? Within the list of database tables, uncheck the tables you want excluded from backups, and they won't be included.
46
  6. Take control of how WordPress automatically updates itself. Select whether to auto update for major updates, minor updates, development updates, and/or translation updates.
47
  7. Select which of your plugins to have automatically updated when updates are available.
48
  8. Select which of your themes to have automatically updated when updates are available.
@@ -50,13 +52,13 @@ The following features are available, of which you can find additional info for
50
  10. For large sites, backups can sometimes take a bit of time to complete. During backups, a progress bar is shown to keep you updated on the backup's status.
51
  11. When backups are completed, or when a backup is restored, BoldGrid Backup will send you an email.
52
  12. The Backup Archives page will list all of your backups, and show you where each backup is stored (Web Server, FTP/SFTP, etc).
53
- 13. When viewing the details of a backup, click the "Upload" button to easily upload the backup archive to one of your remote storage providers, such as a FTP server.
54
  14. To help keep your backups organized, you can add titles and descriptions to each backup.
55
  15. Use the Backup Browser to view what files are contained in each of your backups.
56
- 16. You can also use the Backup Browser to see which database tables are included in the backup, and compare the # records to your current database.
57
  17. The right sidebar of the Backup Archive Details page shows information about a backup, including who made the backup, what was backed up, how long the backup took, and more.
58
  18. You can configure retention settings (only keep X number of backups) so that disk space used by your Web Server and/or your FTP/SFTP to store backups does not grow out of control.
59
- 19. For backups you don't want deleted by your retention settings, you can configure them to be saved and not deleted when the retention process deletes backup.
60
  20. Migrating websites from one host to another only takes a few steps. On the source server, generate a protected link for which a backup can be downloaded. Then, on the destination server, upload a backup using that protected link. All that's left is clicking restore!
61
 
62
  == Installation ==
@@ -74,6 +76,15 @@ The following features are available, of which you can find additional info for
74
 
75
  == Changelog ==
76
 
 
 
 
 
 
 
 
 
 
77
  = 1.7.1 =
78
 
79
  Release date: Dec 18th, 2018
@@ -88,15 +99,15 @@ Release date: Dec 4th, 2018
88
  * New feature: Added auto-update settings for individual plugins and themes.
89
  * New feature: Added limited-lifetime download links for archive files.
90
  * New feature: Added import backup archive from URL address.
91
- * New feature: Added progress bar to show status of backups.
92
  * New feature: Adding the ability to set and title and description to a backup.
93
- * New feature: Adding the ability to flag a backup as being proteced (excluded from retention).
94
  * Update: Update protection is now valid for 1 hour after a full backup from the WordPress Updates or Plugins page.
95
  * Update: Made the Backup Archives page the default page in the admin menu.
96
- * Bug fix: Set a default backup directory if path in settings is not valid. Remove filters before fixing home and siteurl on restore.
97
  * Bug fix: Some HTML was caught in translations.
98
  * Bug fix: Duplicate emails were sent when a backup was complete, fixed.
99
- * Bug fix: Preserve timestamp on ftp / sftp uploads.
100
  * Bug fix: Fixed CLI support detection on some EA4 servers.
101
  * Update: Save settings and reload to the current section.
102
  * Update: Reorganized settings sections.
@@ -149,11 +160,11 @@ Release Date: April 11th, 2018
149
  * New feature: Control which files and database tables are backed up.
150
  * Compatibility: PclZip support added for creating archives.
151
  * Compatibility: WP Cron support added for scheduled backups.
152
- * Compatibility: PHP Script used to backup database, rather than system commands.
153
  * Improvement: Update admin pages to use WP UI/UX standards.
154
  * Improvement: Improved UI in regards to time zones.
155
  * Improvement: Failed items on Preflight Check page are highlighted in red.
156
- * Improvement: Send email if backup fails via cron.
157
  * Improvement: More details in Preflight Check to help with troubleshooting.
158
  * Bug fix: Bug fixed with auto restoration feature.
159
 
@@ -179,7 +190,7 @@ Release Date: June 27th, 2017
179
 
180
  Release Date: May 16th, 2017
181
 
182
- * Bug fix: Fixed undefined property when pre-flight test fails.
183
  * Bug fix: Fixed an undefined index when home dir is not writable.
184
  * Bug fix: Fixed auto plugin update.
185
 
@@ -201,7 +212,7 @@ Release Date: February 20th, 2017
201
 
202
  * Bug fix: Fixed issue when installing plugins from the Tools Import page.
203
  * Bug fix: Fixed check for system tar and zip.
204
- * Bug fix: Fixed method of locating home directory.
205
 
206
  = 1.3.6 =
207
 
@@ -222,9 +233,9 @@ Release Date: February 7th, 2017
222
 
223
  Release Date: January 10th, 2017
224
 
225
- * Update: Update support urls.
226
- * Update: Close session on gathering disk space api call.
227
- * Bug fix: Fixed missing link in email.
228
  * Bug fix: Uncaught TypeError: wp.template is not a function.
229
  * Testing: Tested on WordPress 4.7.
230
 
@@ -235,7 +246,7 @@ Release Date: December 20th, 2016
235
  * Update: Show backup limits to users.
236
  * Update: Misc notices.
237
  * Update: Disable backup now button.
238
- * Update: Prevent backup if account is too large.
239
 
240
  = 1.3.2 =
241
 
@@ -243,7 +254,7 @@ Release Date: December 6th, 2016
243
 
244
  * Update: Move backups when changing backup directory.
245
  * Update: Improve time to calculate disk space.
246
- * Bug fix: Added double-quote encapsulation to password in mysqldump defaults file.
247
  * Bug fix: Typo fix.
248
 
249
 
@@ -251,18 +262,18 @@ Release Date: December 6th, 2016
251
 
252
  Release Date: November 15th, 2016
253
 
254
- * Update: Modify 'last created archive' message with link to archives.
255
- * Update: Modify backup success message with link to settings.
256
  * Update: Modify BoldGrid Backup menus.
257
  * Update: Adjust display of preflight check.
258
  * Update: Free limitations to days of the week.
259
  * Update: Free limitations to retention.
260
  * Update: Standard tooltips.
261
- * Update: Add intro message to Archive page.
262
- * Update: Modify backup id section on archives page.
263
  * Update: Modify Backup Site messages.
264
  * Update: Cache disk space data.
265
- * Update: Add free / premium messages next to disk / db sizes.
266
  * Misc: Added plugin requirements to readme.txt file.
267
 
268
  = 1.3 =
@@ -294,7 +305,7 @@ Release Date: September 7th, 2016
294
  Release Date: August 23rd, 2016
295
 
296
  * Bug fix: Updates via adminajax now updates the rollback timer.
297
- * Misc: Updated readme.txt for Tested up to: 4.6.
298
 
299
  = 1.2 =
300
 
@@ -302,7 +313,7 @@ Release Date: August 9th, 2016
302
 
303
  * New feature: Added XHProf for optional PHP profiling. Can be enabled in "config.local.php" by setting "xhprof" to true.
304
  * Bug fix: Fixed auto-update action hook.
305
- * Bug fix: Changed restore and delete buttons to POST forms, to resolve issue with people reloading the restore URL.
306
  * Bug fix: Reworked error notices for restoration. Emptying archive list before updating after performing a backup.
307
  * Bug fix: Disabled backup and restore buttons after starting a restoration.
308
  * Bug fix: Removed homedir not writable notice; moved info to the functionality test page.
@@ -324,18 +335,18 @@ Release Date: July 22nd, 2016
324
 
325
  Release Date: July 6th, 2016
326
 
327
- * New feature: Added setting for notification email address.
328
  * New feature: Added setting for backup directory.
329
- * New feature: Cancel auto-rollback if a restoration is performed.
330
  * New feature: Added Rollback Site Now button in the rollback notice.
331
  * New feature: Made it possible to change siteurl and retain matched archives (backups made as of this update).
332
  * New feature: Added capability for auto-updates by BoldGrid API response.
333
- * Redesign: Formatted the Functionality Test page.
334
- * Bug fix: Removed PHP SAPI check in cron script.
335
  * Bug fix: Restoration cron did not always complete.
336
- * Bug fix: Better aligned rollback countdown timer with cron job.
337
  * Bug fix: Provided message for empty archive list.
338
- * Bug fix: Rollback information is now removed after timer reaches 0:00.
339
  * Bug fix: Test for crontab now works when crontab is empty.
340
  * Bug fix: Now closing PHP session on backup, download, and restore, so that other PHP requests from the client may load.
341
  * Testing: Tested on WordPress 4.5.3.
@@ -345,5 +356,3 @@ Release Date: July 6th, 2016
345
  Release Date: June 21st, 2016
346
 
347
  * Initial public release.
348
-
349
- == Upgrade Notice ==
2
  Contributors: boldgrid, joemoto, imh_brad, rramo012, timph, bgnicolepaschen
3
  Tags: boldgrid, backup, restore, migrate, migration
4
  Requires at least: 4.4
5
+ Tested up to: 5.1
6
  Requires PHP: 5.4
7
+ Stable tag: 1.7.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
12
 
13
  == Description ==
14
 
15
+ The BoldGrid Backup Plugin will backup your entire WordPress site with just a couple of clicks right in your WordPress dashboard. Just select a time and day for backups to run automatically, or manually create a backup at any time with a single click.
16
+
17
+ Try out the [BoldGrid Backup Plugin](https://www.boldgrid.com/central/get-it-now?plugins=boldgrid-backup&redirect_url=wp-admin%2Fadmin.php%3Fpage%3Dboldgrid-backup) on Cloud WordPress to see for yourself!
18
 
19
  == Features ==
20
 
43
  1. Easily schedule backups using Cron or WP Cron. Set a time of day, select the days of the week, and BoldGrid Backup will automate backups for you. You will receive an email after each backup has been completed.
44
  2. Automatically perform a backup before WordPress auto updates itself. This feature hooks into the [pre_auto_update](https://developer.wordpress.org/reference/hooks/pre_auto_update/) action.
45
  3. After a scheduled backup completes, you can have it uploaded automatically to an FTP / SFTP server. Users who upgrade to premium can also store backups on Amazon S3.
46
+ 4. You can configure which files and folders and include in your backups. "Include" and "Exclude" filters are easy to set up, and you can click the "Preview" button to get a listing of which files and folders will actually be included in your backup.
47
+ 5. Have tables you don't want to back up? Within the list of database tables, uncheck the tables you want to be excluded from backups, and they won't be included.
48
  6. Take control of how WordPress automatically updates itself. Select whether to auto update for major updates, minor updates, development updates, and/or translation updates.
49
  7. Select which of your plugins to have automatically updated when updates are available.
50
  8. Select which of your themes to have automatically updated when updates are available.
52
  10. For large sites, backups can sometimes take a bit of time to complete. During backups, a progress bar is shown to keep you updated on the backup's status.
53
  11. When backups are completed, or when a backup is restored, BoldGrid Backup will send you an email.
54
  12. The Backup Archives page will list all of your backups, and show you where each backup is stored (Web Server, FTP/SFTP, etc).
55
+ 13. When viewing the details of a backup, click the "Upload" button to easily upload the backup archive to one of your remote storage providers, such as an FTP server.
56
  14. To help keep your backups organized, you can add titles and descriptions to each backup.
57
  15. Use the Backup Browser to view what files are contained in each of your backups.
58
+ 16. You can also use the Backup Browser to see which database tables are included in the backup and compare the # records to your current database.
59
  17. The right sidebar of the Backup Archive Details page shows information about a backup, including who made the backup, what was backed up, how long the backup took, and more.
60
  18. You can configure retention settings (only keep X number of backups) so that disk space used by your Web Server and/or your FTP/SFTP to store backups does not grow out of control.
61
+ 19. For backups you don't want to be deleted by your retention settings, you can configure them to be saved and not deleted when the retention process deletes the backup.
62
  20. Migrating websites from one host to another only takes a few steps. On the source server, generate a protected link for which a backup can be downloaded. Then, on the destination server, upload a backup using that protected link. All that's left is clicking restore!
63
 
64
  == Installation ==
76
 
77
  == Changelog ==
78
 
79
+ = 1.7.2 =
80
+
81
+ Release date: Jan 15th, 2019
82
+
83
+ * Update: Improved journey for downloading the premium plugin.
84
+ * Update: Reduced the number of FTP connections made on the settings page.
85
+ * Update: Overhauled this readme file, added more info on features and added screenshots.
86
+ * Update: New system that asks user for bug fixes / new features, or requests plugin rating.
87
+
88
  = 1.7.1 =
89
 
90
  Release date: Dec 18th, 2018
99
  * New feature: Added auto-update settings for individual plugins and themes.
100
  * New feature: Added limited-lifetime download links for archive files.
101
  * New feature: Added import backup archive from URL address.
102
+ * New feature: Added progress bar to show the status of backups.
103
  * New feature: Adding the ability to set and title and description to a backup.
104
+ * New feature: Adding the ability to flag a backup as being protected (excluded from retention).
105
  * Update: Update protection is now valid for 1 hour after a full backup from the WordPress Updates or Plugins page.
106
  * Update: Made the Backup Archives page the default page in the admin menu.
107
+ * Bug fix: Set a default backup directory if the path in settings is not valid. Remove filters before fixing home and siteurl on restore.
108
  * Bug fix: Some HTML was caught in translations.
109
  * Bug fix: Duplicate emails were sent when a backup was complete, fixed.
110
+ * Bug fix: Preserve timestamp on ftp/sftp uploads.
111
  * Bug fix: Fixed CLI support detection on some EA4 servers.
112
  * Update: Save settings and reload to the current section.
113
  * Update: Reorganized settings sections.
160
  * New feature: Control which files and database tables are backed up.
161
  * Compatibility: PclZip support added for creating archives.
162
  * Compatibility: WP Cron support added for scheduled backups.
163
+ * Compatibility: PHP Script used to backup the database, rather than system commands.
164
  * Improvement: Update admin pages to use WP UI/UX standards.
165
  * Improvement: Improved UI in regards to time zones.
166
  * Improvement: Failed items on Preflight Check page are highlighted in red.
167
+ * Improvement: Send an email if a backup fails via cron.
168
  * Improvement: More details in Preflight Check to help with troubleshooting.
169
  * Bug fix: Bug fixed with auto restoration feature.
170
 
190
 
191
  Release Date: May 16th, 2017
192
 
193
+ * Bug fix: Fixed undefined property when the pre-flight test fails.
194
  * Bug fix: Fixed an undefined index when home dir is not writable.
195
  * Bug fix: Fixed auto plugin update.
196
 
212
 
213
  * Bug fix: Fixed issue when installing plugins from the Tools Import page.
214
  * Bug fix: Fixed check for system tar and zip.
215
+ * Bug fix: Fixed method of locating the home directory.
216
 
217
  = 1.3.6 =
218
 
233
 
234
  Release Date: January 10th, 2017
235
 
236
+ * Update: Update support URLs.
237
+ * Update: Close session on gathering disk space API call.
238
+ * Bug fix: Fixed missing link in an email template.
239
  * Bug fix: Uncaught TypeError: wp.template is not a function.
240
  * Testing: Tested on WordPress 4.7.
241
 
246
  * Update: Show backup limits to users.
247
  * Update: Misc notices.
248
  * Update: Disable backup now button.
249
+ * Update: Prevent backup if the account is too large.
250
 
251
  = 1.3.2 =
252
 
254
 
255
  * Update: Move backups when changing backup directory.
256
  * Update: Improve time to calculate disk space.
257
+ * Bug fix: Added double-quote encapsulation to the password in the mysqldump defaults file.
258
  * Bug fix: Typo fix.
259
 
260
 
262
 
263
  Release Date: November 15th, 2016
264
 
265
+ * Update: Modify 'last created archive' message with a link to archives.
266
+ * Update: Modify backup success message with a link to settings.
267
  * Update: Modify BoldGrid Backup menus.
268
  * Update: Adjust display of preflight check.
269
  * Update: Free limitations to days of the week.
270
  * Update: Free limitations to retention.
271
  * Update: Standard tooltips.
272
+ * Update: Add intro message to the Archive page.
273
+ * Update: Modify backup id section on the archives page.
274
  * Update: Modify Backup Site messages.
275
  * Update: Cache disk space data.
276
+ * Update: Add free / premium messages next to disk / database sizes.
277
  * Misc: Added plugin requirements to readme.txt file.
278
 
279
  = 1.3 =
305
  Release Date: August 23rd, 2016
306
 
307
  * Bug fix: Updates via adminajax now updates the rollback timer.
308
+ * Misc: Updated readme.txt for Tested up to 4.6.
309
 
310
  = 1.2 =
311
 
313
 
314
  * New feature: Added XHProf for optional PHP profiling. Can be enabled in "config.local.php" by setting "xhprof" to true.
315
  * Bug fix: Fixed auto-update action hook.
316
+ * Bug fix: Changed restore and delete buttons to POST forms, to resolve an issue with people reloading the restoration URL.
317
  * Bug fix: Reworked error notices for restoration. Emptying archive list before updating after performing a backup.
318
  * Bug fix: Disabled backup and restore buttons after starting a restoration.
319
  * Bug fix: Removed homedir not writable notice; moved info to the functionality test page.
335
 
336
  Release Date: July 6th, 2016
337
 
338
+ * New feature: Added setting for a notification email address.
339
  * New feature: Added setting for backup directory.
340
+ * New feature: Cancel auto-rollback if restoration is performed.
341
  * New feature: Added Rollback Site Now button in the rollback notice.
342
  * New feature: Made it possible to change siteurl and retain matched archives (backups made as of this update).
343
  * New feature: Added capability for auto-updates by BoldGrid API response.
344
+ * Redesign: Formatted the Functionality Test page.
345
+ * Bug fix: Removed PHP SAPI check in the cron script.
346
  * Bug fix: Restoration cron did not always complete.
347
+ * Bug fix: Better aligned rollback countdown timer with the cron job.
348
  * Bug fix: Provided message for empty archive list.
349
+ * Bug fix: Rollback information is now removed after the timer reaches 0:00.
350
  * Bug fix: Test for crontab now works when crontab is empty.
351
  * Bug fix: Now closing PHP session on backup, download, and restore, so that other PHP requests from the client may load.
352
  * Testing: Tested on WordPress 4.5.3.
356
  Release Date: June 21st, 2016
357
 
358
  * Initial public release.
 
 
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInita6df5ba1202853e2f5d815b67bc99335::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit3179cc8cf55bc33a7a6470fb79d3732a::getLoader();
vendor/boldgrid/library/README.md CHANGED
@@ -11,8 +11,30 @@ composer require boldgrid/library
11
 
12
  ## Changelog ##
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  ### 2.7.4 ###
15
 
 
 
16
  * Bug fix: JIRA BGCONN-35 Prevent Connect Key notice on block editor pages.
17
 
18
  ### 2.7.3 ###
11
 
12
  ## Changelog ##
13
 
14
+ ### 2.7.7 ###
15
+
16
+ Release date: Jan 15th, 2019
17
+
18
+ * Update: Add method to get a plugin's download url from the api server.
19
+ * Update: New system that asks user for bug fixes / new features, or requests plugin rating.
20
+ * Update: Minor updates to the BoldGrid Connect Key prompt.
21
+
22
+ ### 2.7.6 ###
23
+
24
+ Release date: Dec 5th, 2018
25
+
26
+ * Update: Inverse logic fixes, is_plugin_active vs is_plugin_inactive.
27
+
28
+ ### 2.7.5 ###
29
+
30
+ Release date: Dec 4th, 2018
31
+
32
+ * Bug fix: BoldGrid logo not showing in front end admin bar.
33
+
34
  ### 2.7.4 ###
35
 
36
+ Release date: Dec 4th, 2018
37
+
38
  * Bug fix: JIRA BGCONN-35 Prevent Connect Key notice on block editor pages.
39
 
40
  ### 2.7.3 ###
vendor/boldgrid/library/src/Library/Activity.php ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BoldGrid Library Activity Class
4
+ *
5
+ * @package Boldgrid\Library
6
+ * @subpackage \Library\License
7
+ *
8
+ * @version 2.7.7
9
+ * @author BoldGrid <wpb@boldgrid.com>
10
+ */
11
+
12
+ namespace Boldgrid\Library\Library;
13
+
14
+ use Boldgrid\Library\Library;
15
+
16
+ /**
17
+ * BoldGrid Library Activity Class.
18
+ *
19
+ * @since 2.7.7
20
+ */
21
+ class Activity {
22
+ /**
23
+ * Whether or not the filters in the constructor have been added.
24
+ *
25
+ * They only need to be added once.
26
+ *
27
+ * @since 2.7.7
28
+ * @var bool
29
+ */
30
+ private static $filtersAdded = false;
31
+
32
+ /**
33
+ * The option name where activity data is stored.
34
+ *
35
+ * @since 2.7.7
36
+ * @var string
37
+ */
38
+ private $optionName = 'bglib_activity';
39
+
40
+ /**
41
+ * The name of the plugin this class represents.
42
+ *
43
+ * For example, 'boldgrid-backup'.
44
+ *
45
+ * @since 2.7.7
46
+ * @var string
47
+ */
48
+ private $plugin;
49
+
50
+ /**
51
+ * Initialize class and set class properties.
52
+ *
53
+ * @since 2.7.7
54
+ */
55
+ public function __construct( $plugin ) {
56
+ $this->plugin = $plugin;
57
+
58
+ if ( ! self::$filtersAdded ) {
59
+ Filter::add( $this );
60
+ self::$filtersAdded = true;
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Add / update an activity count.
66
+ *
67
+ * @since 2.7.7
68
+ *
69
+ * @param string $activity The name of the activity.
70
+ * @param int $count The amount to increment the activity by.
71
+ * @param string $config_path The path to the config file for rating prompts. If the path is
72
+ * passed in, this method will also attempt to add a new prompt if
73
+ * the activities threshold has been reached.
74
+ * @return bool Whether or not the activity was added.
75
+ */
76
+ public function add( $activity, $count = 1, $config_path = null ) {
77
+ $added = false;
78
+
79
+ $plugin_activities = $this->getPluginActivities();
80
+
81
+ if ( ! isset( $plugin_activities[ $activity ] ) ) {
82
+ $plugin_activities[ $activity ] = $count;
83
+ } else {
84
+ $plugin_activities[ $activity ] += $count;
85
+ }
86
+
87
+ $added = $this->savePluginActivities( $plugin_activities );
88
+
89
+ if ( $added && ! empty( $config_path ) ) {
90
+ $this->maybeAddRatingPrompt( $activity, $config_path );
91
+ }
92
+
93
+ return $added;
94
+ }
95
+
96
+ /**
97
+ * Get all activities.
98
+ *
99
+ * @since 2.7.7
100
+ *
101
+ * @return array
102
+ */
103
+ public function getActivities() {
104
+ return get_option( $this->optionName, array() );
105
+ }
106
+
107
+ /**
108
+ * Get the configs for a particular activity.
109
+ *
110
+ * @since 2.7.7
111
+ *
112
+ * @var string $activity The name of the activity.
113
+ * @var string $config_path The full path to the config file.
114
+ * @return array An array of configs.
115
+ */
116
+ public function getActivityConfigs( $activity, $config_path ) {
117
+ $configs = array();
118
+
119
+ if ( file_exists( $config_path ) ) {
120
+ $configs = require $config_path;
121
+ }
122
+
123
+ return isset( $configs[ $activity ] ) ? $configs[ $activity ] : array();
124
+ }
125
+
126
+ /**
127
+ * Get the count for an activity.
128
+ *
129
+ * @since 2.7.7
130
+ *
131
+ * @param string $activity The name of the activity.
132
+ * @return int The activity's count.
133
+ */
134
+ public function getActivityCount( $activity ) {
135
+ $plugin_activities = $this->getPluginActivities();
136
+
137
+ return empty( $plugin_activities[ $activity ] ) ? 0 : $plugin_activities[ $activity ];
138
+ }
139
+
140
+ /**
141
+ * Get all activities for a plugin.
142
+ *
143
+ * @since 2.7.7
144
+ *
145
+ * @return array
146
+ */
147
+ public function getPluginActivities() {
148
+ $activities = $this->getActivities();
149
+
150
+ if ( ! isset( $activities[ $this->plugin ] ) ) {
151
+ $activities[ $this->plugin ] = array();
152
+ }
153
+
154
+ return $activities[ $this->plugin ];
155
+ }
156
+
157
+ /**
158
+ * Maybe add a rating prompt for an activity.
159
+ *
160
+ * @since 2.7.7
161
+ *
162
+ * @param string $activity The name of an activity
163
+ * @param string $config_path The path to our plugin's rating prompt configs.
164
+ * @return bool Whether or not we added a rating prompt.
165
+ */
166
+ public function maybeAddRatingPrompt( $activity, $config_path ) {
167
+ $added = false;
168
+
169
+ $configs = $this->getActivityConfigs( $activity, $config_path );
170
+
171
+ if ( isset( $configs['threshold'] ) && $this->getActivityCount( $activity ) >= $configs['threshold'] ) {
172
+ $rating_prompt = new \Boldgrid\Library\Library\RatingPrompt();
173
+ $added = $rating_prompt->addPrompt( $configs['prompt'] );
174
+ }
175
+
176
+ return $added;
177
+ }
178
+
179
+ /**
180
+ * Save all activities.
181
+ *
182
+ * This overwrites all activites, not just the ones for this plugin.
183
+ *
184
+ * @since 2.7.7
185
+ *
186
+ * @param array $activities An array of activities.
187
+ * @return bool Whether or not the activities were updated successfully.
188
+ */
189
+ public function saveActivities( $activities ) {
190
+ return update_option( $this->optionName, $activities );
191
+ }
192
+
193
+ /**
194
+ * Save all activities for this plugin.
195
+ *
196
+ * @since 2.7.7
197
+ *
198
+ * @param array $plugin_activities An array of activities.
199
+ * @return bool Whether or not the activities were updated successfully.
200
+ */
201
+ public function savePluginActivities( $plugin_activities ) {
202
+ $activities = $this->getActivities();
203
+
204
+ $activities[ $this->plugin ] = $plugin_activities;
205
+
206
+ return $this->saveActivities( $activities );
207
+ }
208
+ }
vendor/boldgrid/library/src/Library/Asset.php CHANGED
@@ -27,6 +27,20 @@ class Asset {
27
  Filter::add( $this );
28
  }
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  /**
31
  * Add styles for all admin pages.
32
  *
@@ -37,6 +51,21 @@ class Asset {
37
  public function addStyles() {
38
  wp_enqueue_style( 'bglib-admin',
39
  Configs::get( 'libraryUrl' ) . 'src/assets/css/admin.css' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
41
  }
42
  ?>
27
  Filter::add( $this );
28
  }
29
 
30
+ /**
31
+ * Add front end scripts.
32
+ *
33
+ * @since 2.7.5
34
+ *
35
+ * @hook wp_enqueue_scripts
36
+ */
37
+ public function addWpScripts() {
38
+ if ( is_user_logged_in() ) {
39
+ // Enqueue on front end for logged in users so they get BoldGrid logo in admin bar.
40
+ $this->EnqueueAdminIcon();
41
+ }
42
+ }
43
+
44
  /**
45
  * Add styles for all admin pages.
46
  *
51
  public function addStyles() {
52
  wp_enqueue_style( 'bglib-admin',
53
  Configs::get( 'libraryUrl' ) . 'src/assets/css/admin.css' );
54
+
55
+ $this->EnqueueAdminIcon();
56
+ }
57
+
58
+ /**
59
+ * Enqueue admin icon css.
60
+ *
61
+ * Used to show BoldGrid font / logo. Separate method created for reusability on front end vs
62
+ * back end.
63
+ *
64
+ * @since 2.7.5
65
+ */
66
+ public function EnqueueAdminIcon() {
67
+ wp_enqueue_style( 'bglib-admin-icon',
68
+ Configs::get( 'libraryUrl' ) . 'src/assets/css/admin-icon.css' );
69
  }
70
  }
71
  ?>
vendor/boldgrid/library/src/Library/Plugin/Plugin.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BoldGrid Library Plugin Plugin.
4
+ *
5
+ * @package Boldgrid\Plugin
6
+ *
7
+ * @since 2.7.7
8
+ * @author BoldGrid <wpb@boldgrid.com>
9
+ */
10
+
11
+ namespace Boldgrid\Library\Library\Plugin;
12
+
13
+ use Boldgrid\Library\Library\Configs;
14
+
15
+ /**
16
+ * Generic plugin class.
17
+ *
18
+ * This class represents a specific plugin.
19
+ *
20
+ * @since 2.7.7
21
+ */
22
+ class Plugin {
23
+
24
+ /**
25
+ * Plugin slug.
26
+ *
27
+ * Examples: boldgrid-backup, boldgrid-backup-premium, etc.
28
+ *
29
+ * @var string
30
+ * @since 2.7.7
31
+ */
32
+ private $slug;
33
+
34
+ /**
35
+ * Constructor.
36
+ *
37
+ * @since 2.7.7
38
+ */
39
+ public function __construct( $slug ) {
40
+ $this->slug = $slug;
41
+ }
42
+
43
+ /**
44
+ * Return the download url for a plugin.
45
+ *
46
+ * @since 2.7.7
47
+ *
48
+ * @return string
49
+ */
50
+ public function getDownloadUrl() {
51
+ $url = Configs::get( 'api' ) . '/v1/plugins/' . $this->slug . '/download';
52
+
53
+ $url = add_query_arg( 'key', Configs::get( 'key' ), $url );
54
+
55
+ return $url;
56
+ }
57
+ }
vendor/boldgrid/library/src/Library/RatingPrompt.php ADDED
@@ -0,0 +1,525 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BoldGrid Library Rating Prompt Class
4
+ *
5
+ * @package Boldgrid\Library
6
+ * @subpackage \Library\License
7
+ *
8
+ * @version 2.7.7
9
+ * @author BoldGrid <wpb@boldgrid.com>
10
+ */
11
+
12
+ namespace Boldgrid\Library\Library;
13
+
14
+ use Boldgrid\Library\Library;
15
+
16
+ /**
17
+ * BoldGrid Library Rating Prompt Class.
18
+ *
19
+ * This class is responsible for displaying admin notices asking for feedback / a rating on wp.org.
20
+ *
21
+ * @since 2.7.7
22
+ */
23
+ class RatingPrompt {
24
+ /**
25
+ * Whether or not we've already added the filters in the constructor.
26
+ *
27
+ * Filters only need to be added once.
28
+ *
29
+ * @since 2.7.7
30
+ * @var bool
31
+ */
32
+ private static $filtersAdded = false;
33
+
34
+ /**
35
+ * The minimum amount of time between showing different prompts.
36
+ *
37
+ * @since 2.7.7
38
+ * @var int
39
+ * @see self::getLastDismissal()
40
+ */
41
+ private $minInterval = 0;
42
+
43
+ /**
44
+ * The option name where rating prompts are stored.
45
+ *
46
+ * @since 2.7.7
47
+ * @var string
48
+ */
49
+ private $optionName = 'bglib_rating_prompt';
50
+
51
+ /**
52
+ * The role required to see a rating prompt.
53
+ *
54
+ * @since 2.7.7
55
+ * @var string
56
+ */
57
+ private $userRole = 'update_plugins';
58
+
59
+ /**
60
+ * Initialize class and set class properties.
61
+ *
62
+ * @since 2.7.7
63
+ */
64
+ public function __construct() {
65
+ // Only add the filters once.
66
+ if ( ! self::$filtersAdded ) {
67
+ Filter::add( $this );
68
+ self::$filtersAdded = true;
69
+ }
70
+
71
+ $this->minInterval = 2 * DAY_IN_SECONDS;
72
+ }
73
+
74
+ /**
75
+ * Add a prompt.
76
+ *
77
+ * This only adds a prompt if it doesn't already exist by name.
78
+ *
79
+ * @since 2.7.7
80
+ *
81
+ * @param array $prompt An array of configs for a prompt.
82
+ * @return bool Whether or not the prompt was added.
83
+ */
84
+ public function addPrompt( $prompt ) {
85
+ $added = false;
86
+
87
+ /*
88
+ * Determine whether to add the new prompt or not.
89
+ *
90
+ * If we've already a prompt for user_did_this_x_times, don't add another prompt for the
91
+ * same thing.
92
+ *
93
+ * If a plugin has already been dismissed, no need to add any additional rating prompts,
94
+ * they will never be showing.
95
+ */
96
+ if ( ! $this->isPrompt( $prompt['name'] ) && ! $this->isPluginDismissed( $prompt['plugin'] ) ) {
97
+ $prompt['time_added'] = time();
98
+
99
+ $prompts = $this->getPrompts();
100
+
101
+ $prompts[] = $prompt;
102
+
103
+ $added = $this->savePrompts( $prompts );
104
+ }
105
+
106
+ return $added;
107
+ }
108
+
109
+ /**
110
+ * Add admin notices.
111
+ *
112
+ * @since 2.7.7
113
+ */
114
+ public function admin_notices() {
115
+ if ( ! current_user_can( $this->userRole ) ) {
116
+ return;
117
+ }
118
+
119
+ $prompt = $this->getNext();
120
+ if ( empty( $prompt ) ) {
121
+ return;
122
+ }
123
+
124
+ $slides = $this->getPromptSlides( $prompt );
125
+ if ( ! empty( $slides ) ) {
126
+ echo '<div class="notice notice-success bglib-rating-prompt is-dismissible" data-slide-name="' . esc_attr( $prompt['name'] ) . '">';
127
+ foreach ( $slides as $slide ) {
128
+ echo $slide;
129
+ }
130
+ wp_nonce_field( 'bglib-rating-prompt' );
131
+ echo '</div>';
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Dismiss a rating prompt via ajax.
137
+ *
138
+ * @since 2.7.7
139
+ *
140
+ * @hook wp_ajax_blib_rating_prompt_dismiss
141
+ */
142
+ public function ajaxDismiss() {
143
+ if ( ! current_user_can( $this->userRole ) ) {
144
+ wp_send_json_error( __( 'Permission denied.', 'boldgrid-backup' ) );
145
+ }
146
+
147
+ if( ! check_ajax_referer( 'bglib-rating-prompt', 'security', false ) ) {
148
+ wp_send_json_error( __( 'Invalid nonce.', 'boldgrid-backup' ) );
149
+ }
150
+
151
+ $name = sanitize_text_field( $_POST['name'] );
152
+ $type = sanitize_text_field( $_POST['type'] );
153
+ $snooze_length = (int) $_POST['length'];
154
+
155
+ switch( $type ) {
156
+ case 'dismiss':
157
+ $dismissed = $this->updatePromptKey( $name, 'time_dismissed', time() );
158
+ $dismissed ? wp_send_json_success() : wp_send_json_error( __( 'Error dismissing prompt', 'boldgrid-backup' ) );
159
+ break;
160
+ case 'snooze':
161
+ $time_snoozed_set = $this->updatePromptKey( $name, 'time_snoozed', time() );
162
+ $snoozed = $this->updatePromptKey( $name, 'time_snoozed_until', time() + $snooze_length );
163
+ $time_snoozed_set && $snoozed ? wp_send_json_success() : wp_send_json_error( __( 'Error snoozing prompt', 'boldgrid-backup' ) );
164
+ break;
165
+ default:
166
+ wp_send_json_error( __( 'Unknown action.', 'boldgrid-backup' ) );
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Get an array of attributes for a decision's <a> tag.
172
+ *
173
+ * @since 2.7.7
174
+ *
175
+ * @param array $decision A decision from a slide.
176
+ * @return array
177
+ */
178
+ public function getDecisionAttributes( $decision ) {
179
+ $attributes = array();
180
+
181
+ $action = isset( $decision['snooze'] ) ? 'snooze' : 'dismiss';
182
+
183
+ $attributes['data-action'] = esc_attr( $action );
184
+
185
+ if ( isset( $decision['link'] ) ) {
186
+ $attributes['href'] = esc_url( $decision['link'] );
187
+ $attributes['target'] = '_blank';
188
+ } else {
189
+ $attributes['href'] = '';
190
+ }
191
+
192
+ if ( isset( $decision['snooze'] ) ) {
193
+ $attributes['data-snooze'] = esc_attr( $decision['snooze'] );
194
+ }
195
+
196
+ if ( isset( $decision['slide'] ) ) {
197
+ $attributes['data-next-slide'] = esc_attr( $decision['slide'] );
198
+ }
199
+
200
+ return $attributes;
201
+ }
202
+
203
+ /**
204
+ * Get the time of the last dismissal or snooze, whichever is latest.
205
+ *
206
+ * One reason this is used is to ensure prompts don't show one after another for the user. For
207
+ * example, if the user just dismissed a rating prompt, we may not want to show them another
208
+ * prompt for at least 2 days.
209
+ *
210
+ * @since 2.7.7
211
+ *
212
+ * @return int
213
+ */
214
+ public function getLastDismissal() {
215
+ $lastDismissal = 0;
216
+
217
+ $prompts = $this->getPrompts();
218
+ foreach ( $prompts as $prompt ) {
219
+ $promptDismissal = 0;
220
+
221
+ if ( ! empty( $prompt['time_dismissed'] ) ) {
222
+ $promptDismissal = $prompt['time_dismissed'];
223
+ } elseif ( ! empty( $prompt['time_snoozed'] ) ) {
224
+ $promptDismissal = $prompt['time_snoozed'];
225
+ }
226
+
227
+ $lastDismissal = $promptDismissal > $lastDismissal ? $promptDismissal : $lastDismissal;
228
+ }
229
+
230
+ return $lastDismissal;
231
+ }
232
+
233
+ /**
234
+ * Get the minInterval value.
235
+ *
236
+ * @since 2.7.7
237
+ *
238
+ * @return int
239
+ */
240
+ public function getMinInterval() {
241
+ return $this->minInterval;
242
+ }
243
+
244
+ /**
245
+ * Admin enqueue scripts.
246
+ *
247
+ * @since 2.7.7
248
+ */
249
+ public function admin_enqueue_scripts() {
250
+ if ( ! current_user_can( $this->userRole ) ) {
251
+ return;
252
+ }
253
+
254
+ $prompt = $this->getNext();
255
+
256
+ if ( ! empty( $prompt ) ) {
257
+ wp_enqueue_script(
258
+ 'bglib-rating-prompt-js',
259
+ Library\Configs::get( 'libraryUrl' ) . 'src/assets/js/rating-prompt.js',
260
+ 'jquery',
261
+ date( 'Ymd' )
262
+ );
263
+
264
+ wp_enqueue_style(
265
+ 'bglib-rating-prompt-css',
266
+ Library\Configs::get( 'libraryUrl' ) . 'src/assets/css/rating-prompt.css',
267
+ array(),
268
+ date( 'Ymd' )
269
+ );
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Return the markup of a prompt's slides.
275
+ *
276
+ * @since 2.7.7
277
+ *
278
+ * @param array $prompt A prompt.
279
+ * @return string
280
+ */
281
+ public function getPromptSlides( $prompt ) {
282
+ $slides = array();
283
+
284
+ if ( ! empty( $prompt['slides'] ) ) {
285
+ foreach ( $prompt['slides'] as $slide_id => $slide ) {
286
+ $slideMarkup = $this->getSlideMarkup( $slide_id, $slide );
287
+
288
+ $slides[$slide_id] = $slideMarkup;
289
+ }
290
+ }
291
+
292
+ return $slides;
293
+ }
294
+
295
+ /**
296
+ * Get the markup for an individual slide.
297
+ *
298
+ * @since 2.7.7
299
+ *
300
+ * @param string $slide_id The id of a slide.
301
+ * @param array $slide A array of slide configs.
302
+ * @return string
303
+ */
304
+ public function getSlideMarkup( $slide_id, $slide ) {
305
+ $slideMarkup = '<div data-slide-id="' . esc_attr( $slide_id ) . '">';
306
+
307
+ $slideMarkup .= '<p>' . $slide['text'] . '</p>';
308
+
309
+ if ( ! empty( $slide['decisions'] ) ) {
310
+ $slide_decisions = array();
311
+
312
+ foreach( $slide['decisions'] as $decision ) {
313
+ $attributes = $this->getDecisionAttributes( $decision );
314
+
315
+ $markup = '<a ';
316
+ foreach ( $attributes as $key => $value ) {
317
+ $markup .= $key . '="' . $value . '" ';
318
+ }
319
+ $markup .= '>' . esc_html( $decision['text'] ) . '</a>';
320
+
321
+ $slide_decisions[] = $markup;
322
+ }
323
+ $slideMarkup .= '<ul><li>' . implode( '</li><li>', $slide_decisions ) . '</li></ul>';
324
+ }
325
+
326
+ $slideMarkup .= '</div>';
327
+
328
+ return $slideMarkup;
329
+ }
330
+
331
+ /**
332
+ * Whether or not the minimum amount of time between showing prompts has been reached.
333
+ *
334
+ * @since 2.7.7
335
+ *
336
+ * @see self::getLastDismissal().
337
+ *
338
+ * @return bool
339
+ */
340
+ public function isMinInterval() {
341
+ return time() > $this->getLastDismissal() + $this->minInterval;
342
+ }
343
+
344
+ /**
345
+ * Get a prompt by name.
346
+ *
347
+ * @since 2.7.7
348
+ *
349
+ * @param string $name The name of a prompt.
350
+ * @return array
351
+ */
352
+ public function getPrompt( $name ) {
353
+ $prompt_found = array();
354
+
355
+ $prompts = $this->getPrompts();
356
+
357
+ foreach( $prompts as $prompt ) {
358
+ if ( $name === $prompt['name'] ) {
359
+ $prompt_found = $prompt;
360
+ break;
361
+ }
362
+ }
363
+
364
+ return $prompt_found;
365
+ }
366
+
367
+ /**
368
+ * Get all rating prompts.
369
+ *
370
+ * @since 2.7.7
371
+ *
372
+ * @return array
373
+ */
374
+ public function getPrompts() {
375
+ return get_option( $this->optionName, array() );
376
+ }
377
+
378
+ /**
379
+ * Determine whether or not a given plugin has any dismissed notices.
380
+ *
381
+ * @since 2.7.7
382
+ *
383
+ * @param string $plugin A plugin name.
384
+ * @return bool
385
+ */
386
+ public function isPluginDismissed( $plugin ) {
387
+ $dismissed = false;
388
+
389
+ $plugin_prompts = $this->getPluginPrompts( $plugin );
390
+
391
+ foreach ( $plugin_prompts as $prompt ) {
392
+ if ( ! empty( $prompt['time_dismissed'] ) ) {
393
+ $dismissed = true;
394
+ }
395
+ }
396
+
397
+ return $dismissed;
398
+ }
399
+
400
+ /**
401
+ * Whether or not a prompt (by prompt name) exists.
402
+ *
403
+ * @since 2.7.7
404
+ *
405
+ * @param string $name A prompt name.
406
+ * @return bool
407
+ */
408
+ public function isPrompt( $name ) {
409
+ $prompt = $this->getPrompt( $name );
410
+
411
+ return ! empty( $prompt );
412
+ }
413
+
414
+ /**
415
+ * Get all prompts for a plugin.
416
+ *
417
+ * @since 2.7.7
418
+ *
419
+ * @param string $plugin The name of a plugin.
420
+ * @return array
421
+ */
422
+ public function getPluginPrompts( $plugin ) {
423
+ $pluginPrompts = array();
424
+
425
+ $prompts = $this->getPrompts();
426
+
427
+ foreach ( $prompts as $prompt ) {
428
+ if ( $prompt['plugin'] === $plugin ) {
429
+ $pluginPrompts[] = $prompt;
430
+ }
431
+ }
432
+
433
+ return $pluginPrompts;
434
+ }
435
+
436
+ /**
437
+ * Get the next prompt to display.
438
+ *
439
+ * We only display one prompt at a time. Get that prompt.
440
+ *
441
+ * @since 2.7.7
442
+ */
443
+ public function getNext() {
444
+ $nextPrompt = array();
445
+ $prompts = $this->getPrompts();
446
+
447
+ foreach ( $prompts as $prompt ) {
448
+ $isDismissed = isset( $prompt['time_dismissed'] );
449
+ $isOlder = empty( $nextPrompt ) || ( ! $isDismissed && $prompt['time_added'] < $nextPrompt['time_added'] );
450
+ $isStillSnoozing = ! empty( $prompt['time_snoozed_until'] ) && $prompt['time_snoozed_until'] > time();
451
+
452
+ if ( ! $isDismissed && $isOlder && ! $isStillSnoozing ) {
453
+ $nextPrompt = $prompt;
454
+ }
455
+ }
456
+
457
+ if ( ! $this->isMinInterval() ) {
458
+ $nextPrompt = array();
459
+ }
460
+
461
+ return $nextPrompt;
462
+ }
463
+
464
+ /**
465
+ * Update an existing prompt.
466
+ *
467
+ * If the prompt is not found, this method will not make any changes.
468
+ *
469
+ * @since 2.7.7
470
+ *
471
+ * @param array $prompt_to_save A prompt.
472
+ * @return bool Whether or not the prompt was found and updated.
473
+ */
474
+ public function updatePrompt( $prompt_to_save ) {
475
+ $found = false;
476
+
477
+ $prompts = $this->getPrompts();
478
+
479
+ foreach ( $prompts as $key => $prompt ) {
480
+ if ( $prompt_to_save['name'] === $prompt['name'] ) {
481
+ $found = true;
482
+
483
+ $prompts[$key] = $prompt_to_save;
484
+
485
+ break;
486
+ }
487
+ }
488
+
489
+ return $found ? $this->savePrompts( $prompts ) : false;
490
+ }
491
+
492
+ /**
493
+ * Save prompts.
494
+ *
495
+ * Be sure to pass in all prompts. This replaces the existing option.
496
+ *
497
+ * @since 2.7.7
498
+ *
499
+ * @param array $prompts An array of prompts.
500
+ * @return bool Whether or not the prompts were saved.
501
+ */
502
+ public function savePrompts( $prompts ) {
503
+ return update_option( $this->optionName, $prompts );
504
+ }
505
+
506
+ /**
507
+ * Update an attribute for a prompt.
508
+ *
509
+ * Commonly used to set the time a prompt was dismissed.
510
+ *
511
+ * @since 2.7.7
512
+ *
513
+ * @param string $name The name of a prompt.
514
+ * @param string $key The key to update.
515
+ * @param mixed $value The new value for the key.
516
+ * @return bool Whether or not the prompt was saved successfully.
517
+ */
518
+ public function updatePromptKey( $name, $key, $value ) {
519
+ $prompt = $this->getPrompt( $name );
520
+
521
+ $prompt[$key] = $value;
522
+
523
+ return $this->updatePrompt( $prompt );
524
+ }
525
+ }
vendor/boldgrid/library/src/Library/Views/Connect/AutoUpdates.php CHANGED
@@ -187,10 +187,10 @@ $pluginsActive = array();
187
  $pluginsInactive = array();
188
 
189
  foreach ( $plugins as $slug => $pluginData ) {
190
- if ( is_plugin_active( $slug ) ) {
191
- $pluginsActive[ $slug ] = $pluginData;
192
- } else {
193
  $pluginsInactive[ $slug ] = $pluginData;
 
 
194
  }
195
  }
196
 
187
  $pluginsInactive = array();
188
 
189
  foreach ( $plugins as $slug => $pluginData ) {
190
+ if ( is_plugin_inactive( $slug ) ) {
 
 
191
  $pluginsInactive[ $slug ] = $pluginData;
192
+ } else {
193
+ $pluginsActive[ $slug ] = $pluginData;
194
  }
195
  }
196
 
vendor/boldgrid/library/src/Library/Views/KeyPrompt.php CHANGED
@@ -61,7 +61,7 @@
61
  } else {
62
  // Display either the Envato message or the default signup message.
63
  ?>
64
- <p><a href="#" class="boldgridApiKeyLink">
65
  <?php
66
  esc_html_e( 'Don\'t have a Connect Key yet or lost your Key?', 'boldgrid-connect' );
67
  ?>
@@ -74,29 +74,23 @@
74
  ?>
75
  <div class="new-api-key hidden">
76
  <h2 class="dashicons-before dashicons-admin-network">
77
- <?php esc_html_e( 'Request a BoldGrid Connect Key', 'boldgrid-connect' ); ?>
78
  </h2>
79
- <a href="#" class="enterKeyLink">
80
- <?php esc_html_e( 'Have a Connect Key to enter?', 'boldgrid-connect' ); ?>
81
- </a>
82
- <br />
83
- <br />
84
  <div class="key-request-content">
85
  <p id="requestKeyMessage">
86
  <?php printf(
87
  esc_html__(
88
- 'There are two types of BoldGrid Connect Keys, a free key or an Official Host Premium Connect Key.
89
- %sA Premium Connect Key is highly recommended and may already come with your hosting account.%s
90
- If you do not have a Premium Connect Key, then you may request a free key below.
91
- Please visit %sour site%s for full details.%s
92
- If you have lost your key, you can have it resent by entering your information below.',
93
  'boldgrid-connect'
94
  ),
95
  '<b>',
96
  '</b>',
97
- "<a href='https://www.boldgrid.com/get-it-now/' target='_blank'>",
98
- '</a>',
99
- '<br /><br />' );
100
  ?>
101
  <br />
102
  </p>
@@ -114,14 +108,22 @@
114
  <?php esc_html_e( 'E-mail', 'boldgrid-connect' ); ?>:
115
  </label>
116
  <input type="text" id="emailAddr" maxlength="50" placeholder="your@name.com" value="<?php echo esc_attr( $email ); ?>" />
117
- <br />
 
 
 
 
 
118
  <input type="hidden" id="siteUrl" value="<?php echo get_admin_url(); ?>" />
119
- <br />
120
  <button id="requestKey" class="button button-primary">
121
  <?php esc_html_e( 'Submit', 'boldgrid-connect' ); ?>
122
  </button>
123
  <span class="spinner"></span>
124
  <input type="hidden" id="generate-api-key" value="<?php echo esc_attr( $api ); ?>" />
 
 
 
 
125
  </form>
126
  </div>
127
  </div>
61
  } else {
62
  // Display either the Envato message or the default signup message.
63
  ?>
64
+ <p><a href="#" class="boldgridApiKeyLink button button-secondary">
65
  <?php
66
  esc_html_e( 'Don\'t have a Connect Key yet or lost your Key?', 'boldgrid-connect' );
67
  ?>
74
  ?>
75
  <div class="new-api-key hidden">
76
  <h2 class="dashicons-before dashicons-admin-network">
77
+ <?php esc_html_e( 'Request or Reset a BoldGrid Connect Key', 'boldgrid-connect' ); ?>
78
  </h2>
 
 
 
 
 
79
  <div class="key-request-content">
80
  <p id="requestKeyMessage">
81
  <?php printf(
82
  esc_html__(
83
+ 'You may obtain two different types of Connect Keys: A Free Key or a Premium Connect Key (%4$sclick here%5$s for the benefits of a Premium Key).
84
+ %1$sA Premium Connect Key is highly recommended and may already come with your hosting account.%2$s
85
+ %3$s
86
+ To get your Free Key (or to have it emailed to you if you\'ve lost it), enter your info below:',
 
87
  'boldgrid-connect'
88
  ),
89
  '<b>',
90
  '</b>',
91
+ '<br /><br />',
92
+ '<a href="https://www.boldgrid.com/connect-keys/" target="_blank">',
93
+ '</a>' );
94
  ?>
95
  <br />
96
  </p>
108
  <?php esc_html_e( 'E-mail', 'boldgrid-connect' ); ?>:
109
  </label>
110
  <input type="text" id="emailAddr" maxlength="50" placeholder="your@name.com" value="<?php echo esc_attr( $email ); ?>" />
111
+ <p>
112
+ <label>
113
+ <input id="requestTos" type="checkbox" value="0">
114
+ <?php printf( esc_html__( 'Check here to agree to our %sTerms of Use and Privacy Policy%s.', 'boldgrid-connect' ), '<a href="https://www.boldgrid.com/software-privacy-policy/" target="_blank">', '</a>' ); ?>
115
+ </label>
116
+ </p>
117
  <input type="hidden" id="siteUrl" value="<?php echo get_admin_url(); ?>" />
 
118
  <button id="requestKey" class="button button-primary">
119
  <?php esc_html_e( 'Submit', 'boldgrid-connect' ); ?>
120
  </button>
121
  <span class="spinner"></span>
122
  <input type="hidden" id="generate-api-key" value="<?php echo esc_attr( $api ); ?>" />
123
+
124
+ <a href="#" class="enterKeyLink">
125
+ <?php esc_html_e( 'Have a Connect Key to enter?', 'boldgrid-connect' ); ?>
126
+ </a>
127
  </form>
128
  </div>
129
  </div>
vendor/boldgrid/library/src/assets/css/admin-icon.css ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @font-face {
2
+ font-family: 'boldgrid';
3
+ src: url('../fonts/boldgrid.eot?-k3w47');
4
+ src: url('../fonts/boldgrid.eot?#iefix-k3w47')
5
+ format('embedded-opentype'), url('../fonts/boldgrid.woff?-k3w47')
6
+ format('woff'), url('../fonts/boldgrid.ttf?-k3w47') format('truetype'),
7
+ url('../fonts/boldgrid.svg?-k3w47#boldgrid') format('svg');
8
+ font-weight: normal;
9
+ font-style: normal;
10
+ }
11
+
12
+ @font-face {
13
+ font-family: 'bg-admin-icons';
14
+ src: url('../fonts/bg-admin-icons.eot?11633397');
15
+ src: url('../fonts/bg-admin-icons.eot?11633397#iefix')
16
+ format('embedded-opentype'),
17
+ url('../fonts/bg-admin-icons.woff?11633397') format('woff'),
18
+ url('../fonts/bg-admin-icons.ttf?11633397') format('truetype'),
19
+ url('../fonts/bg-admin-icons.svg?11633397#bg-admin-icons')
20
+ format('svg');
21
+ font-weight: normal;
22
+ font-style: normal;
23
+ }
24
+
25
+ #toplevel_page_boldgrid-transactions .wp-menu-image::before,
26
+ #toplevel_page_boldgrid-inspirations .wp-menu-image:not(.dashicons-lightbulb)::before {
27
+ content: "\e801";
28
+ font-family: "bg-admin-icons";
29
+ font-style: normal;
30
+ font-weight: normal;
31
+ font-size: 19px;
32
+ speak: none;
33
+ display: inline-block;
34
+ text-decoration: inherit;
35
+ width: 1em;
36
+ margin-right: .2em;
37
+ text-align: center;
38
+ /* opacity: .8; */
39
+ /* For safety - reset parent styles, that can break glyph codes*/
40
+ font-variant: normal;
41
+ text-transform: none;
42
+ /* fix buttons height, for twitter bootstrap */
43
+ line-height: 1em;
44
+ /* Animation center compensation - margins should be symmetric */
45
+ /* remove if not needed */
46
+ margin-left: .2em;
47
+ /* You can be more comfortable with increased icons size */
48
+ /* font-size: 120%; */
49
+ /* Font smoothing. That was taken from TWBS */
50
+ -webkit-font-smoothing: antialiased;
51
+ -moz-osx-font-smoothing: grayscale;
52
+ }
53
+
54
+ .toplevel_page_boldgrid-inspirations #step-2 .theme-browser .theme .theme-screenshot {
55
+ overflow: visible;
56
+ }
57
+
58
+ .toplevel_page_boldgrid-inspirations #step-2 .theme-browser .theme .theme-name {
59
+ position: relative;
60
+ }
61
+
62
+ .theme-install-php .theme-browser .theme .theme-screenshot img,
63
+ .toplevel_page_boldgrid-inspirations #step-2 .theme-browser .theme .theme-screenshot img {
64
+ transition: opacity 0s;
65
+ }
66
+
67
+ .theme-install-php .theme-browser .theme .theme-name,
68
+ .toplevel_page_boldgrid-inspirations #step-2 .theme-browser .theme .theme-name {
69
+ background-color: #FAFAFA;
70
+ }
71
+
72
+ #toplevel_page_boldgrid-transactions .wp-menu-image::before {
73
+ content: "\e800";
74
+ }
75
+
76
+ .whh-icon:before {
77
+ content: "\e601";
78
+ font-family: 'boldgrid';
79
+ speak: none;
80
+ font-size: large;
81
+ font-style: normal;
82
+ font-weight: normal;
83
+ font-variant: normal;
84
+ text-transform: none;
85
+ -webkit-font-smoothing: antialiased;
86
+ -moz-osx-font-smoothing: grayscale;
87
+ }
88
+
89
+ .imh-icon:before {
90
+ content: "\e602";
91
+ font-family: 'boldgrid';
92
+ speak: none;
93
+ font-size: large;
94
+ font-style: normal;
95
+ font-weight: normal;
96
+ font-variant: normal;
97
+ text-transform: none;
98
+ -webkit-font-smoothing: antialiased;
99
+ -moz-osx-font-smoothing: grayscale;
100
+ }
101
+
102
+ .boldgrid-icon:before {
103
+ content: "\e600";
104
+ font-family: 'boldgrid';
105
+ speak: none;
106
+ font-size: large;
107
+ font-style: normal;
108
+ font-weight: normal;
109
+ font-variant: normal;
110
+ text-transform: none;
111
+ -webkit-font-smoothing: antialiased;
112
+ -moz-osx-font-smoothing: grayscale;
113
+ }
vendor/boldgrid/library/src/assets/css/admin.css CHANGED
@@ -17,122 +17,6 @@
17
  }
18
  /** BoldGrid Connect Page End **/
19
 
20
- /** Admin Bar Icons **/
21
- @font-face {
22
- font-family: 'boldgrid';
23
- src: url('../fonts/boldgrid.eot?-k3w47');
24
- src: url('../fonts/boldgrid.eot?#iefix-k3w47')
25
- format('embedded-opentype'), url('../fonts/boldgrid.woff?-k3w47')
26
- format('woff'), url('../fonts/boldgrid.ttf?-k3w47') format('truetype'),
27
- url('../fonts/boldgrid.svg?-k3w47#boldgrid') format('svg');
28
- font-weight: normal;
29
- font-style: normal;
30
- }
31
-
32
- @font-face {
33
- font-family: 'bg-admin-icons';
34
- src: url('../fonts/bg-admin-icons.eot?11633397');
35
- src: url('../fonts/bg-admin-icons.eot?11633397#iefix')
36
- format('embedded-opentype'),
37
- url('../fonts/bg-admin-icons.woff?11633397') format('woff'),
38
- url('../fonts/bg-admin-icons.ttf?11633397') format('truetype'),
39
- url('../fonts/bg-admin-icons.svg?11633397#bg-admin-icons')
40
- format('svg');
41
- font-weight: normal;
42
- font-style: normal;
43
- }
44
-
45
- #toplevel_page_boldgrid-transactions .wp-menu-image::before,
46
- #toplevel_page_boldgrid-inspirations .wp-menu-image:not(.dashicons-lightbulb)::before {
47
- content: "\e801";
48
- font-family: "bg-admin-icons";
49
- font-style: normal;
50
- font-weight: normal;
51
- font-size: 19px;
52
- speak: none;
53
- display: inline-block;
54
- text-decoration: inherit;
55
- width: 1em;
56
- margin-right: .2em;
57
- text-align: center;
58
- /* opacity: .8; */
59
- /* For safety - reset parent styles, that can break glyph codes*/
60
- font-variant: normal;
61
- text-transform: none;
62
- /* fix buttons height, for twitter bootstrap */
63
- line-height: 1em;
64
- /* Animation center compensation - margins should be symmetric */
65
- /* remove if not needed */
66
- margin-left: .2em;
67
- /* You can be more comfortable with increased icons size */
68
- /* font-size: 120%; */
69
- /* Font smoothing. That was taken from TWBS */
70
- -webkit-font-smoothing: antialiased;
71
- -moz-osx-font-smoothing: grayscale;
72
- }
73
-
74
- .toplevel_page_boldgrid-inspirations #step-2 .theme-browser .theme .theme-screenshot {
75
- overflow: visible;
76
- }
77
-
78
- .toplevel_page_boldgrid-inspirations #step-2 .theme-browser .theme .theme-name {
79
- position: relative;
80
- }
81
-
82
- .theme-install-php .theme-browser .theme .theme-screenshot img,
83
- .toplevel_page_boldgrid-inspirations #step-2 .theme-browser .theme .theme-screenshot img {
84
- transition: opacity 0s;
85
- }
86
-
87
- .theme-install-php .theme-browser .theme .theme-name,
88
- .toplevel_page_boldgrid-inspirations #step-2 .theme-browser .theme .theme-name {
89
- background-color: #FAFAFA;
90
- }
91
-
92
- #toplevel_page_boldgrid-transactions .wp-menu-image::before {
93
- content: "\e800";
94
- }
95
-
96
- .whh-icon:before {
97
- content: "\e601";
98
- font-family: 'boldgrid';
99
- speak: none;
100
- font-size: large;
101
- font-style: normal;
102
- font-weight: normal;
103
- font-variant: normal;
104
- text-transform: none;
105
- -webkit-font-smoothing: antialiased;
106
- -moz-osx-font-smoothing: grayscale;
107
- }
108
-
109
- .imh-icon:before {
110
- content: "\e602";
111
- font-family: 'boldgrid';
112
- speak: none;
113
- font-size: large;
114
- font-style: normal;
115
- font-weight: normal;
116
- font-variant: normal;
117
- text-transform: none;
118
- -webkit-font-smoothing: antialiased;
119
- -moz-osx-font-smoothing: grayscale;
120
- }
121
-
122
- .boldgrid-icon:before {
123
- content: "\e600";
124
- font-family: 'boldgrid';
125
- speak: none;
126
- font-size: large;
127
- font-style: normal;
128
- font-weight: normal;
129
- font-variant: normal;
130
- text-transform: none;
131
- -webkit-font-smoothing: antialiased;
132
- -moz-osx-font-smoothing: grayscale;
133
- }
134
- /** Admin Bar Icons End **/
135
-
136
  /** div-table classes Start **/
137
  .div-table {
138
  display: table;
17
  }
18
  /** BoldGrid Connect Page End **/
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  /** div-table classes Start **/
21
  .div-table {
22
  display: table;
vendor/boldgrid/library/src/assets/css/api-notice.css CHANGED
@@ -3,7 +3,7 @@
3
  }
4
 
5
  #container_boldgrid_api_key_notice .dashicons-before:before {
6
- padding-right: .8em !important;
7
  font-size: 58px !important;
8
  color: #ff6600;
9
  }
@@ -13,7 +13,7 @@
13
  padding: 1.4em;
14
  }
15
 
16
- #requestKeyForm input {
17
  width: 83%;
18
  margin: .5em 0;
19
  }
@@ -108,11 +108,17 @@
108
  #boldgrid_api_key_notice_message,
109
  .tos-box,
110
  .key-request-content,
111
- .enterKeyLink,
112
- .boldgridApiKeyLink {
113
  margin-left: 66px;
114
  }
115
 
 
 
 
 
 
 
 
116
  #requestKeyMessage {
117
  margin-right: 66px;
118
  }
3
  }
4
 
5
  #container_boldgrid_api_key_notice .dashicons-before:before {
6
+ padding-right: .73em !important;
7
  font-size: 58px !important;
8
  color: #ff6600;
9
  }
13
  padding: 1.4em;
14
  }
15
 
16
+ #requestKeyForm input:not( [type='checkbox'] ) {
17
  width: 83%;
18
  margin: .5em 0;
19
  }
108
  #boldgrid_api_key_notice_message,
109
  .tos-box,
110
  .key-request-content,
111
+ .api-notice .boldgridApiKeyLink {
 
112
  margin-left: 66px;
113
  }
114
 
115
+ /* Have a Connect Key to enter? */
116
+ .enterKeyLink {
117
+ float: right;
118
+ margin: 0 40px 0 0;
119
+ padding-top: 6px;
120
+ }
121
+
122
  #requestKeyMessage {
123
  margin-right: 66px;
124
  }
vendor/boldgrid/library/src/assets/css/rating-prompt.css ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ .bglib-rating-prompt [data-slide-id]:not(:first-child) {
2
+ display:none;
3
+ }
vendor/boldgrid/library/src/assets/js/api-notice.js CHANGED
@@ -40,7 +40,8 @@ BOLDGRID.LIBRARY.Api = function( $ ) {
40
  $genericError =
41
  'There was an error communicating with the BoldGrid Connect Key server. Please try again.',
42
  $submit = $form.find( '#requestKey' ),
43
- $spinner = $form.find( '.spinner' );
 
44
 
45
  $( '.error-color' ).removeClass( 'error-color' );
46
 
@@ -69,6 +70,11 @@ BOLDGRID.LIBRARY.Api = function( $ ) {
69
  .addClass( 'error-color' );
70
  return false;
71
  }
 
 
 
 
 
72
 
73
  $submit.prop( 'disabled', 'disabled' );
74
  $spinner.addClass( 'inline' );
40
  $genericError =
41
  'There was an error communicating with the BoldGrid Connect Key server. Please try again.',
42
  $submit = $form.find( '#requestKey' ),
43
+ $spinner = $form.find( '.spinner' ),
44
+ $tos = $form.find( '#requestTos' );
45
 
46
  $( '.error-color' ).removeClass( 'error-color' );
47
 
70
  .addClass( 'error-color' );
71
  return false;
72
  }
73
+ if ( ! $tos.prop( 'checked' ) ) {
74
+ $alertBox.text( 'You must agree to the Terms of Service before continuing.' );
75
+ $tos.closest( 'label' ).addClass( 'error-color' );
76
+ return false;
77
+ }
78
 
79
  $submit.prop( 'disabled', 'disabled' );
80
  $spinner.addClass( 'inline' );
vendor/boldgrid/library/src/assets/js/rating-prompt.js ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Handle rating prompts in the dashboard.
3
+ *
4
+ * @since 2.7.7
5
+ */
6
+
7
+ /* global ajaxurl, jQuery */
8
+
9
+ var BOLDGRID = BOLDGRID || {};
10
+ BOLDGRID.LIBRARY = BOLDGRID.LIBRARY || {};
11
+
12
+ ( function( $ ) {
13
+ 'use strict';
14
+
15
+ var self;
16
+
17
+ BOLDGRID.LIBRARY.RatingPrompt = {
18
+ /**
19
+ * @summary Dismiss (or snooze) a rating prompt.
20
+ *
21
+ * @since 2.7.7
22
+ *
23
+ * @param string name
24
+ * @param string type
25
+ * @param string length
26
+ */
27
+ dismiss: function( name, type, length ) {
28
+ var data = {
29
+ 'action': 'blib_rating_prompt_dismiss',
30
+ 'type': type,
31
+ 'length': length,
32
+ 'name': name,
33
+ 'security': $( '.bglib-rating-prompt #_wpnonce' ).val()
34
+ };
35
+
36
+ $.ajax( {
37
+ url: ajaxurl,
38
+ data: data,
39
+ type: 'post',
40
+ dataType: 'json'
41
+ } );
42
+ },
43
+
44
+ /**
45
+ * @summary Take action when a decision is clicked.
46
+ *
47
+ * @since 2.7.7
48
+ */
49
+ onClickDecision: function() {
50
+ var $decision = $( this ),
51
+ $slides = $( '.bglib-rating-prompt [data-slide-id]' ),
52
+ action = $decision.attr( 'data-action' ),
53
+ name = $decision.closest( '.bglib-rating-prompt' ).attr( 'data-slide-name' ),
54
+ nextSlide = $decision.attr( 'data-next-slide' );
55
+
56
+ // Handle the toggle to another slide.
57
+ if ( nextSlide ) {
58
+ $slides.hide();
59
+ $( '.bglib-rating-prompt [data-slide-id="' + nextSlide + '"]' ).show();
60
+ }
61
+
62
+ // Handle dismissing / snoozing.
63
+ if ( 'dismiss' === action ) {
64
+ self.dismiss( name, 'dismiss', 0 );
65
+ } else if ( 'snooze' === action ) {
66
+ self.dismiss( name, 'snooze', $decision.attr( 'data-snooze' ) );
67
+ }
68
+
69
+ if ( 0 === $decision.attr( 'href' ).length ) {
70
+ return false;
71
+ }
72
+ },
73
+ };
74
+
75
+ self = BOLDGRID.LIBRARY.RatingPrompt;
76
+
77
+ $( function() {
78
+ $( 'body' ).on( 'click', '.notice.bglib-rating-prompt li a', BOLDGRID.LIBRARY.RatingPrompt.onClickDecision );
79
+ } );
80
+ })( jQuery );
vendor/boldgrid/library/tests/Library/Library/test-activity.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BoldGrid Library Activity Test Class
4
+ *
5
+ * @package Boldgrid\Library
6
+ * @subpackage \Library\License
7
+ *
8
+ * @version 2.7.7
9
+ * @author BoldGrid <wpb@boldgrid.com>
10
+ */
11
+
12
+ use Boldgrid\Library\Library;
13
+
14
+ /**
15
+ * BoldGrid Library Rating Prompt Class.
16
+ *
17
+ * This class is responsible for displaying admin notices asking for feedback / a rating on wp.org.
18
+ *
19
+ * @since 2.7.7
20
+ */
21
+ class Test_Activty extends WP_UnitTestCase {
22
+
23
+ public $activity;
24
+
25
+ public $activityClass;
26
+
27
+ /**
28
+ *
29
+ */
30
+ public function setup() {
31
+ $this->reset();
32
+
33
+ $this->activityClass = new \Boldgrid\Library\Library\Activity( 'boldgrid-backup' );
34
+ }
35
+
36
+ /**
37
+ *
38
+ */
39
+ public function reset() {
40
+ $this->activity = array(
41
+ 'boldgrid-backup' => array(
42
+ 'activityA' => 5,
43
+ 'activityB' => 10,
44
+ 'activityC' => 15,
45
+ ),
46
+ 'post-and-page-builder' => array(
47
+ 'activityA' => 20,
48
+ 'activityB' => 25,
49
+ 'activityC' => 30,
50
+ ),
51
+ );
52
+
53
+ update_option( 'bglib_activity', $this->activity );
54
+ }
55
+
56
+ /**
57
+ * Add / update an activity count.
58
+ *
59
+ * @since 2.7.7
60
+ *
61
+ * @param string $activity The name of the activity.
62
+ * @param int $count The amount to increment the activity by.
63
+ * @param string $config_path The path to the config file for rating prompts. If the path is
64
+ * passed in, this method will also attempt to add a new prompt if
65
+ * the activities threshold has been reached.
66
+ * @return bool Whether or not the activity was added.
67
+ */
68
+ public function testAdd() {
69
+ $this->reset();
70
+
71
+ $activity = 'activityD';
72
+
73
+ $this->activityClass->add( $activity );
74
+ $this->assertEquals( 1, $this->activityClass->getActivityCount( $activity ) );
75
+
76
+ $this->activityClass->add( $activity, 2 );
77
+ $this->assertEquals( 3, $this->activityClass->getActivityCount( $activity ) );
78
+ }
79
+
80
+ /**
81
+ * Get all activities.
82
+ *
83
+ * @since 2.7.7
84
+ *
85
+ * @return array
86
+ */
87
+ public function testGetActivities() {
88
+ $this->reset();
89
+
90
+ $this->assertEquals( $this->activity, $this->activityClass->getActivities() );
91
+ }
92
+
93
+ /**
94
+ * Get the configs for a particular activity.
95
+ *
96
+ * @since 2.7.7
97
+ *
98
+ * @var string $activity The name of the activity.
99
+ * @var string $config_path The full path to the config file.
100
+ * @return array An array of configs.
101
+ */
102
+ public function testGetActivityConfigs() {
103
+ // NOT TESTED.
104
+ }
105
+
106
+ /**
107
+ * Get the count for an activity.
108
+ *
109
+ * @since 2.7.7
110
+ *
111
+ * @param string $activity The name of the activity.
112
+ * @return int The activity's count.
113
+ */
114
+ public function testGetActivityCount() {
115
+ $this->reset();
116
+
117
+ $this->assertEquals( 10, $this->activityClass->getActivityCount( 'activityB' ) );
118
+ }
119
+
120
+ /**
121
+ * Get all activities for a plugin.
122
+ *
123
+ * @since 2.7.7
124
+ *
125
+ * @return array
126
+ */
127
+ public function testGetPluginActivities() {
128
+ $this->reset();
129
+
130
+ $this->assertEquals( $this->activity['boldgrid-backup'], $this->activityClass->getPluginActivities() );
131
+ }
132
+
133
+ /**
134
+ * Maybe add a rating prompt for an activity.
135
+ *
136
+ * @since 2.7.7
137
+ *
138
+ * @param string $activity The name of an activity
139
+ * @param string $config_path The path to our plugin's rating prompt configs.
140
+ * @return bool Whether or not we added a rating prompt.
141
+ */
142
+ public function testMaybeAddRatingPrompt() {
143
+ // NOT TESTED.
144
+ }
145
+
146
+ /**
147
+ * Save all activities.
148
+ *
149
+ * This overwrites all activites, not just the ones for this plugin.
150
+ *
151
+ * @since 2.7.7
152
+ *
153
+ * @param array $activities An array of activities.
154
+ * @return bool Whether or not the activities were updated successfully.
155
+ */
156
+ public function testSaveActivities() {
157
+ $this->reset();
158
+
159
+ $this->activity['boldgrid-backup']['jump-10-times'] = 5;
160
+ $this->activityClass->saveActivities( $this->activity );
161
+
162
+ $this->assertEquals( $this->activity, $this->activityClass->getActivities() );
163
+ }
164
+
165
+ /**
166
+ * Save all activities for this plugin.
167
+ *
168
+ * @since 2.7.7
169
+ *
170
+ * @param array $plugin_activities An array of activities.
171
+ * @return bool Whether or not the activities were updated successfully.
172
+ */
173
+ public function testSavePluginActivities() {
174
+ $activities = 5;
175
+
176
+ $this->activityClass->savePluginActivities( $activities );
177
+
178
+ $this->assertEquals( $activities, $this->activityClass->getPluginActivities() );
179
+ }
180
+ }
vendor/boldgrid/library/tests/Library/Library/test-rating-prompt.php ADDED
@@ -0,0 +1,553 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BoldGrid Library Rating Prompt Test Class
4
+ *
5
+ * @package Boldgrid\Library
6
+ * @subpackage \Library\License
7
+ *
8
+ * @version 2.7.7
9
+ * @author BoldGrid <wpb@boldgrid.com>
10
+ */
11
+
12
+ use Boldgrid\Library\Library;
13
+
14
+ /**
15
+ * BoldGrid Library Rating Prompt Class.
16
+ *
17
+ * This class is responsible for displaying admin notices asking for feedback / a rating on wp.org.
18
+ *
19
+ * @since 2.7.7
20
+ */
21
+ class Test_Rating_Prompt extends WP_UnitTestCase {
22
+
23
+ public $existingPrompt;
24
+
25
+ public $prompts;
26
+
27
+ public $newPrompt;
28
+
29
+ public $ratingPrompt;
30
+
31
+ /**
32
+ *
33
+ */
34
+ public function reset() {
35
+ $allowed_tags = array(
36
+ 'a' => array(
37
+ 'href' => array(),
38
+ 'target' => array(),
39
+ ),
40
+ );
41
+
42
+ $lang = array(
43
+ 'feel_good_value' => __( 'If you feel you\'re getting really good value from the BoldGrid Backup plugin, could you do us a favor and rate us 5 stars on WordPress?', 'boldgrid-backup' ),
44
+ );
45
+
46
+ $default_prompt = array(
47
+ 'plugin' => 'boldgrid-backup',
48
+ 'name' => 'REPLACE_THIS_NAME',
49
+ 'slides' => array(
50
+ 'start' => array(
51
+ 'text' => $lang['feel_good_value'],
52
+ 'decisions' => array(
53
+ 'sure_will' => array(
54
+ 'text' => __( 'Yes, I sure will!', 'boldgrid-backup' ),
55
+ 'link' => 'https://wordpress.org/support/plugin/boldgrid-backup/reviews/',
56
+ 'slide' => 'thanks',
57
+ ),
58
+ 'maybe_still_testing' => array(
59
+ 'text' => __( 'Maybe later, I\'m still testing the plugin.', 'boldgrid-backup' ),
60
+ 'snooze' => WEEK_IN_SECONDS,
61
+ 'slide' => 'maybe_later',
62
+ ),
63
+ 'already_did' => array(
64
+ 'text' => __( 'I already did', 'boldgrid-backup' ),
65
+ 'slide' => 'already_did',
66
+ ),
67
+ ),
68
+ ),
69
+ 'thanks' => array(
70
+ 'text' => sprintf(
71
+ wp_kses(
72
+ /* translators: The URL to the boldgrid-backup plugin in the plugin repo. */
73
+ __( 'Thanks! A new page should have opened to the BoldGrid Backup ratings page on WordPress.org. You will need to log in to your WordPress.org account before you can post a review. If the page didn\'t open, please click the following link: <a href="%1$s" target="_blank">%1$s</a>', 'boldgrid-backup' ),
74
+ $allowed_tags
75
+ ),
76
+ 'https://wordpress.org/support/plugin/boldgrid-backup/reviews/'
77
+ ),
78
+ ),
79
+ 'maybe_later' => array(
80
+ 'text' => sprintf(
81
+ wp_kses(
82
+ /* translators: The URL to submit boldgrid-backup bug reports and feature requests. */
83
+ __( 'No problem, maybe now is not a good time. We want to be your WordPress backup plugin of choice. If you\'re experiencing a problem or want to make a suggestion, please %1$sclick here%2$s.', 'boldgrid-backup' ),
84
+ $allowed_tags
85
+ ),
86
+ '<a href="https://www.boldgrid.com/feedback" target="_blank">',
87
+ '</a>'
88
+ ),
89
+ ),
90
+ 'already_did' => array(
91
+ 'text' => sprintf(
92
+ wp_kses(
93
+ /* translators: The URL to submit boldgrid-backup bug reports and feature requests. */
94
+ __( 'Thank you for the previous rating! You can help us to continue improving the BoldGrid Backup plugin by reporting any bugs or submitting feature requests %1$shere%2$s. Thank you for using the BoldGrid Backup plugin!', 'boldgrid-backup' ),
95
+ $allowed_tags
96
+ ),
97
+ '<a href="https://www.boldgrid.com/feedback" target="_blank">',
98
+ '</a>'
99
+ ),
100
+ ),
101
+ ),
102
+ );
103
+
104
+ // Set a title or description for your backup.
105
+ $title_description_prompt = $default_prompt;
106
+ $title_description_prompt['name'] = 'update_title_description';
107
+ $title_description_prompt['slides']['start']['text'] = __( 'We hope that you\'re finding adding titles and descriptions to your backups helpful in keeping things organized.', 'boldgrid-backup' ) . ' ' . $lang['feel_good_value'];
108
+
109
+ // Download a backup to your local machine.
110
+ $download_prompt = $default_prompt;
111
+ $download_prompt['name'] = 'download_to_local_machine';
112
+ $download_prompt['slides']['start']['text'] = __( 'We\'re glad to see you\'re keeping your backups safe and downloading them to your local machine!', 'boldgrid-backup' ) . ' ' . $lang['feel_good_value'];
113
+
114
+ // Create any type of backup.
115
+ $any_backup_prompt = $default_prompt;
116
+ $any_backup_prompt['name'] = 'any_backup_created';
117
+ $any_backup_prompt['slides']['start']['text'] = __( 'It looks like you\'ve created 10 backups with the BoldGrid Backup Plugin!', 'boldgrid-backup' ) . ' ' . $lang['feel_good_value'];
118
+
119
+ $this->prompts = array(
120
+ $title_description_prompt,
121
+ $download_prompt,
122
+ $any_backup_prompt,
123
+ );
124
+
125
+ $this->ratingPrompt->savePrompts( $this->prompts );
126
+
127
+ $this->existingPrompt = $any_backup_prompt;
128
+
129
+ $this->newPrompt = $default_prompt;
130
+ $this->newPrompt['name'] = 'new_prompt';
131
+ $this->newPrompt['slides']['start']['text'] = 'Start slide text';
132
+ }
133
+
134
+ public function setup() {
135
+ $this->ratingPrompt = new \Boldgrid\Library\Library\RatingPrompt();
136
+
137
+ $this->reset();
138
+ }
139
+
140
+ /**
141
+ * Add a prompt.
142
+ *
143
+ * This only adds a prompt if it doesn't already exist by name.
144
+ *
145
+ * @since 2.7.7
146
+ *
147
+ * @param array $prompt An array of configs for a prompt.
148
+ * @return bool Whether or not the prompt was added.
149
+ */
150
+ public function testAddPrompt() {
151
+ // Reset our prompts.
152
+ update_option( 'bglib_rating_prompt', $this->prompts );
153
+
154
+ // Add a new prompt.
155
+ $added = $this->ratingPrompt->addPrompt( $this->newPrompt );
156
+ $this->assertTrue( $added );
157
+
158
+ // Add a prompt that already exists.
159
+ $added = $this->ratingPrompt->addPrompt( $this->existingPrompt );
160
+ $this->assertFalse( $added );
161
+ }
162
+
163
+ /**
164
+ * Add admin notices.
165
+ *
166
+ * @since 2.7.7
167
+ */
168
+ public function testAdminNotices() {
169
+ // NOT TESTED.
170
+ }
171
+
172
+ /**
173
+ * Dismiss a rating prompt via ajax.
174
+ *
175
+ * @since 2.7.7
176
+ *
177
+ * @hook wp_ajax_blib_rating_prompt_dismiss
178
+ */
179
+ public function testAjaxDismiss() {
180
+ // NOT TESTED.
181
+ }
182
+
183
+ /**
184
+ * Get an array of attributes for a decision's <a> tag.
185
+ *
186
+ * @since 2.7.7
187
+ *
188
+ * @param array $decision A decision from a slide.
189
+ * @return array
190
+ */
191
+ public function testGetDecisionAttributes() {
192
+ /*
193
+ * [data-action] => dismiss
194
+ * [href] => https://wordpress.org/support/plugin/boldgrid-backup/reviews/
195
+ * [target] => _blank
196
+ * [data-next-slide] => thanks
197
+ */
198
+ $attributes = $this->ratingPrompt->getDecisionAttributes( $this->prompts[0]['slides']['start']['decisions']['sure_will'] );
199
+ $this->assertEquals( 4, count( $attributes ) );
200
+ $this->assertEquals( 'dismiss', $attributes['data-action'] );
201
+ $this->assertEquals( $attributes['href'], $this->prompts[0]['slides']['start']['decisions']['sure_will']['link'] );
202
+ $this->assertEquals( '_blank', $attributes['target'] );
203
+ $this->assertEquals( $attributes['data-next-slide'], $this->prompts[0]['slides']['start']['decisions']['sure_will']['slide'] );
204
+
205
+ /*
206
+ * [data-action] => snooze
207
+ * [href] =>
208
+ * [data-snooze] => 604800
209
+ * [data-next-slide] => maybe_later
210
+ */
211
+ $attributes = $this->ratingPrompt->getDecisionAttributes( $this->prompts[0]['slides']['start']['decisions']['maybe_still_testing'] );
212
+ $this->assertEquals( 4, count( $attributes ) );
213
+ $this->assertEquals( 'snooze', $attributes['data-action'] );
214
+ $this->assertEquals( '', $attributes['href'] );
215
+ $this->assertEquals( $attributes['data-snooze'], $this->prompts[0]['slides']['start']['decisions']['maybe_still_testing']['snooze'] );
216
+ $this->assertEquals( $attributes['data-next-slide'], $this->prompts[0]['slides']['start']['decisions']['maybe_still_testing']['slide'] );
217
+
218
+ /*
219
+ * [data-action] => dismiss
220
+ * [href] =>
221
+ * [data-next-slide] => already_did
222
+ */
223
+ $attributes = $this->ratingPrompt->getDecisionAttributes( $this->prompts[0]['slides']['start']['decisions']['already_did'] );
224
+ $this->assertEquals( 3, count( $attributes ) );
225
+ $this->assertEquals( 'dismiss', $attributes['data-action'] );
226
+ $this->assertEquals( '', $attributes['href'] );
227
+ $this->assertEquals( $attributes['data-next-slide'], $this->prompts[0]['slides']['start']['decisions']['already_did']['slide'] );
228
+ }
229
+
230
+ /**
231
+ * Get the time of the last dismissal or snooze, whichever is latest.
232
+ *
233
+ * One reason this is used is to ensure prompts don't show one after another for the user. For
234
+ * example, if the user just dismissed a rating prompt, we may not want to show them another
235
+ * prompt for at least 2 days.
236
+ *
237
+ * @since 2.7.7
238
+ *
239
+ * @return int
240
+ */
241
+ public function testGetLastDismissal() {
242
+ // Test based on time_dismissed only.
243
+ $this->reset();
244
+
245
+ $prompts = $this->ratingPrompt->getPrompts();
246
+ $prompts[0]['time_dismissed'] = 2;
247
+ $prompts[1]['time_dismissed'] = 1;
248
+ $prompts[3]['time_dismissed'] = 3;
249
+ $this->ratingPrompt->savePrompts( $prompts );
250
+
251
+ $lastDismissed = $this->ratingPrompt->getLastDismissal();
252
+ $this->assertEquals( 3, $lastDismissed );
253
+
254
+ // Test using time_snoozed too.
255
+ $this->reset();
256
+
257
+ $prompts = $this->ratingPrompt->getPrompts();
258
+ $prompts[0]['time_dismissed'] = 1;
259
+ $prompts[1]['time_snoozed'] = 3;
260
+ $prompts[3]['time_dismissed'] = 2;
261
+ $this->ratingPrompt->savePrompts( $prompts );
262
+
263
+ $lastDismissed = $this->ratingPrompt->getLastDismissal();
264
+ $this->assertEquals( 3, $lastDismissed );
265
+ }
266
+
267
+ /**
268
+ * Admin enqueue scripts.
269
+ *
270
+ * @since 2.7.7
271
+ */
272
+ public function testAdminEnqueueScripts() {
273
+ // NOT TESTED.
274
+ }
275
+
276
+ /**
277
+ * Return the markup of a prompt's slides.
278
+ *
279
+ * @since 2.7.7
280
+ *
281
+ * @param array $prompt A prompt.
282
+ * @return string
283
+ */
284
+ public function testGetPromptSlides() {
285
+ // NOT TESTED.
286
+ }
287
+
288
+ /**
289
+ * Get the markup for an individual slide.
290
+ *
291
+ * @since 2.7.7
292
+ *
293
+ * @param string $slide_id The id of a slide.
294
+ * @param array $slide A array of slide configs.
295
+ * @return string
296
+ */
297
+ public function testGetSlideMarkup() {
298
+ // NOT TESTED.
299
+ }
300
+
301
+ /**
302
+ * Whether or not the minimum amount of time between showing prompts has been reached.
303
+ *
304
+ * @since 2.7.7
305
+ *
306
+ * @see self::getLastDismissal().
307
+ *
308
+ * @return bool
309
+ */
310
+ public function testIsMinInterval() {
311
+ // return time() > $this->getLastDismissal() + $this->minInterval;
312
+
313
+ // With nothing dismissed, should be true.
314
+ $this->reset();
315
+
316
+ $this->assertTrue( $this->ratingPrompt->isMinInterval() );
317
+
318
+ // Something dismissed in the future, not enough time will have passed to display the next.
319
+ $prompts = $this->ratingPrompt->getPrompts();
320
+ $prompts[2]['time_dismissed'] = '99999999999999999999';
321
+ $this->ratingPrompt->savePrompts( $prompts );
322
+
323
+ $this->assertFalse( $this->ratingPrompt->isMinInterval() );
324
+
325
+ // Set dismissal to ( minInterval + 60 seconds ) ago.
326
+ $this->reset();
327
+ $prompts = $this->ratingPrompt->getPrompts();
328
+ // I dismissed this rating 2 days and 60 seconds ago.
329
+ $prompts[2]['time_dismissed'] = time() - $this->ratingPrompt->getMinInterval() - 60;
330
+ $this->ratingPrompt->savePrompts( $prompts );
331
+
332
+ $this->assertTrue( $this->ratingPrompt->isMinInterval() );
333
+
334
+ // Set dismissal to ( minInterval - 60 seconds ) ago.
335
+ $this->reset();
336
+ $prompts = $this->ratingPrompt->getPrompts();
337
+ $prompts[2]['time_dismissed'] = time() + $this->ratingPrompt->getMinInterval() + 60;
338
+ $this->ratingPrompt->savePrompts( $prompts );
339
+
340
+ $this->assertFalse( $this->ratingPrompt->isMinInterval() );
341
+ }
342
+
343
+ /**
344
+ * Get a prompt by name.
345
+ *
346
+ * @since 2.7.7
347
+ *
348
+ * @param string $name
349
+ * @return array
350
+ */
351
+ public function testGetPrompt() {
352
+ $this->reset();
353
+
354
+ $prompt = $this->ratingPrompt->getPrompt( 'update_title_description' );
355
+
356
+ $this->assertEquals( $prompt, $this->prompts[0] );
357
+ }
358
+
359
+ /**
360
+ * Get all rating prompts.
361
+ *
362
+ * @since 2.7.7
363
+ *
364
+ * @return array
365
+ */
366
+ public function testGetPrompts() {
367
+ $this->reset();
368
+
369
+ $prompts = $this->ratingPrompt->getPrompts();
370
+
371
+ $this->assertEquals( $prompts, $this->prompts );
372
+ }
373
+
374
+ /**
375
+ * Determine whether or not a given plugin has any dismissed notices.
376
+ *
377
+ * @since 2.7.7
378
+ *
379
+ * @param string $plugin A plugin name.
380
+ * @return bool
381
+ */
382
+ public function testIsPluginDismissed() {
383
+ // By default, nothing is dismissed.
384
+ $this->reset();
385
+
386
+ $this->assertFalse( $this->ratingPrompt->isPluginDismissed( 'boldgrid-backup' ) );
387
+
388
+ // Have only 1 dismissed prompt, but it's for a different plugin.
389
+ $prompts = $this->ratingPrompt->getPrompts();
390
+ $prompts[0]['plugin'] = 'some-plugin';
391
+ $prompts[0]['time_dismissed'] = 5;
392
+ $this->ratingPrompt->savePrompts( $prompts );
393
+
394
+ $this->assertFalse( $this->ratingPrompt->isPluginDismissed( 'boldgrid-backup' ) );
395
+
396
+ // Have 1 dismissed prompt, for the plugin in question.
397
+ $this->reset();
398
+ $prompts = $this->ratingPrompt->getPrompts();
399
+ $prompts[0]['time_dismissed'] = 5;
400
+ $this->ratingPrompt->savePrompts( $prompts );
401
+
402
+ $this->assertTrue( $this->ratingPrompt->isPluginDismissed( 'boldgrid-backup' ) );
403
+ }
404
+
405
+ /**
406
+ * Whether or not a prompt (by prompt name) exists.
407
+ *
408
+ * @since 2.7.7
409
+ *
410
+ * @param string $name A prompt name.
411
+ * @return bool
412
+ */
413
+ public function testIsPrompt() {
414
+ $this->reset();
415
+
416
+ $this->assertTrue( $this->ratingPrompt->isPrompt( 'download_to_local_machine' ) );
417
+
418
+ $this->assertFalse( $this->ratingPrompt->isPrompt( 'this-does-not-exist' ) );
419
+ }
420
+
421
+ /**
422
+ * Get all prompts for a plugin.
423
+ *
424
+ * @since 2.7.7
425
+ *
426
+ * @param string $plugin The name of a plugin.
427
+ * @return array
428
+ */
429
+ public function testGetPluginPrompts() {
430
+ $this->reset();
431
+
432
+ $plugin = 'my-cool-plugin';
433
+
434
+ $prompts = $this->ratingPrompt->getPrompts();
435
+ $prompts[2]['plugin'] = $plugin;
436
+ $this->ratingPrompt->savePrompts( $prompts );
437
+
438
+ $pluginPrompts = $this->ratingPrompt->getPluginPrompts( $plugin );
439
+ $this->assertEquals( $prompts[2], $pluginPrompts[0] );
440
+ }
441
+
442
+ /**
443
+ * Get the next prompt to display.
444
+ *
445
+ * We only display one prompt at a time. Get that prompt.
446
+ *
447
+ * @since 2.7.7
448
+ */
449
+ public function testGetNext() {
450
+ // Empty array when no next prompt.
451
+ update_option( 'bglib_rating_prompt', array() );
452
+
453
+ $next = $this->ratingPrompt->getNext();
454
+ $this->assertEquals( array(), $next );
455
+
456
+ // Basic, only looking at time dismissed.
457
+ $this->reset();
458
+ $prompts = $this->ratingPrompt->getPrompts();
459
+ $prompts[0]['time_dismissed'] = 5;
460
+ $prompts[2]['time_dismissed'] = 10;
461
+ $this->ratingPrompt->savePrompts( $prompts );
462
+ $prompts = $this->ratingPrompt->getPrompts();
463
+
464
+ $next = $this->ratingPrompt->getNext();
465
+ $this->assertEquals( $prompts[1]['name'], $next['name'] );
466
+
467
+ // Looking at time_dismissed and snoozed.
468
+ $this->reset();
469
+ $prompts = $this->ratingPrompt->getPrompts();
470
+ $prompts[0]['time_snoozed_until'] = 6;
471
+ $prompts[0]['time_dismissed'] = 10;
472
+ $prompts[1]['time_snoozed_until'] = 9999999999999;
473
+ $prompts[2]['time_snoozed_until'] = 12;
474
+ $this->ratingPrompt->savePrompts( $prompts );
475
+ $prompts = $this->ratingPrompt->getPrompts();
476
+
477
+ $next = $this->ratingPrompt->getNext();
478
+ $this->assertEquals( $prompts[2]['name'], $next['name'] );
479
+ }
480
+
481
+ /**
482
+ * Update an existing prompt.
483
+ *
484
+ * If the prompt is not found, this method will not make any changes.
485
+ *
486
+ * @since 2.7.7
487
+ *
488
+ * @param array $prompt_to_save A prompt.
489
+ * @return bool Whether or not the prompt was found and updated.
490
+ */
491
+ public function testUpdatePrompt() {
492
+ $this->reset();
493
+
494
+ $pet = 'fish';
495
+
496
+ // Update the prompt.
497
+ $updatedPrompt = $this->prompts[0];
498
+ $updatedPrompt['pet'] = $pet;
499
+ $this->ratingPrompt->updatePrompt( $updatedPrompt );
500
+
501
+ // Make sure it updated.
502
+ $prompts = $this->ratingPrompt->getPrompts();
503
+ $this->assertEquals( $pet, $prompts[0]['pet'] );
504
+ }
505
+
506
+ /**
507
+ * Save prompts.
508
+ *
509
+ * Be sure to pass in all prompts. This replaces the existing option.
510
+ *
511
+ * @since 2.7.7
512
+ *
513
+ * @param array $prompts An array of prompts.
514
+ * @return bool Whether or not the prompts were saved.
515
+ */
516
+ public function testSavePrompts() {
517
+ $this->reset();
518
+
519
+ $newPrompts = array( 1, 2, 3 );
520
+
521
+ $this->ratingPrompt->savePrompts( $newPrompts );
522
+
523
+ $prompts = $this->ratingPrompt->getPrompts();
524
+
525
+ $this->assertEquals( $newPrompts, $prompts );
526
+ }
527
+
528
+ /**
529
+ * Update an attribute for a prompt.
530
+ *
531
+ * Commonly used to set the time a prompt was dismissed.
532
+ *
533
+ * @since 2.7.7
534
+ *
535
+ * @param string $name The name of a prompt.
536
+ * @param string $key The key to update.
537
+ * @param mixed $value The new value for the key.
538
+ * @return bool Whether or not the prompt was saved successfully.
539
+ */
540
+ public function testUpdatePromptKey() {
541
+ $this->reset();
542
+
543
+ $name = 'update_title_description';
544
+ $key = 'fish';
545
+ $value = 'catfish';
546
+
547
+ $this->ratingPrompt->updatePromptKey( $name, $key, $value );
548
+
549
+ $prompt = $this->ratingPrompt->getPrompt( $name );
550
+
551
+ $this->assertEquals( $value, $prompt[$key] );
552
+ }
553
+ }
vendor/boldgrid/library/tests/Library/Plugin/test-plugin.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BoldGrid Source Code
4
+ *
5
+ * @package Boldgrid_Plugintest
6
+ * @copyright BoldGrid.com
7
+ * @version $Id$
8
+ * @author BoldGrid.com <wpb@boldgrid.com>
9
+ */
10
+
11
+ use Boldgrid\Library\Library\Configs;
12
+
13
+ /**
14
+ * BoldGrid Library Library Plugin Plugin Test class.
15
+ *
16
+ * @since 2.7.7
17
+ */
18
+ class Test_BoldGrid_Library_Library_Plugin_Plugin extends WP_UnitTestCase {
19
+
20
+ private
21
+ $backup,
22
+ $backup_premium,
23
+ $key = 'CONNECT-KEY';
24
+
25
+ private static $configs;
26
+
27
+ /**
28
+ * Setup.
29
+ *
30
+ * @since 1.7.7
31
+ */
32
+ public function setUp() {
33
+
34
+ // Setup our configs.
35
+ update_site_option( 'boldgrid_api_key', $this->key );
36
+ // Initialization needed so the constructor will include library.global.php.
37
+ new \Boldgrid\Library\Library\Configs();
38
+ // Configs are a real problem in this test. If we can get configs, save them.
39
+ $configs = Configs::get();
40
+ if ( ! empty( $configs ) ) {
41
+ self::$configs = $configs;
42
+ }
43
+
44
+ $this->backup = new Boldgrid\Library\Library\Plugin\Plugin( 'boldgrid-backup' );
45
+ $this->backup_premium = new Boldgrid\Library\Library\Plugin\Plugin( 'boldgrid-backup-premium' );
46
+ }
47
+
48
+ /**
49
+ * Test getDownloadUrl.
50
+ *
51
+ * @since 2.7.7
52
+ */
53
+ public function testGetDownloadUrl() {
54
+
55
+ // Reset our configs.
56
+ Configs::set( self::$configs );
57
+
58
+ $this->assertEquals( $this->backup->getDownloadUrl(), 'https://api.boldgrid.com/v1/plugins/boldgrid-backup/download?key=' . $this->key );
59
+
60
+ $this->assertEquals( $this->backup_premium->getDownloadUrl(), 'https://api.boldgrid.com/v1/plugins/boldgrid-backup-premium/download?key=' . $this->key );
61
+ }
62
+ }
vendor/boldgrid/library/tests/bootstrap.php CHANGED
@@ -1,19 +1,23 @@
1
- <?php
2
-
3
- $_tests_dir = getenv( 'WP_TESTS_DIR' );
4
- if ( ! $_tests_dir ) {
5
- $_tests_dir = '/tmp/wordpress-tests-lib';
6
- }
7
-
8
- require_once $_tests_dir . '/includes/functions.php';
9
-
10
- require_once dirname( dirname( __FILE__ ) ) . '/src/Library/License.php';
11
- require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Api/Call.php';
12
- require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Api/Availability.php';
13
- require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Configs.php';
14
- require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Filter.php';
15
- require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Reseller.php';
16
- require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Util/Plugin.php';
17
- require_once dirname( dirname( __FILE__ ) ) . '/src/Util/Option.php';
18
-
19
- require $_tests_dir . '/includes/bootstrap.php';
 
 
 
 
1
+ <?php
2
+
3
+ $_tests_dir = getenv( 'WP_TESTS_DIR' );
4
+ if ( ! $_tests_dir ) {
5
+ $_tests_dir = '/tmp/wordpress-tests-lib';
6
+ }
7
+
8
+ require_once $_tests_dir . '/includes/functions.php';
9
+
10
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/License.php';
11
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Api/Call.php';
12
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Api/Availability.php';
13
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Configs.php';
14
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Filter.php';
15
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Reseller.php';
16
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Util/Plugin.php';
17
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Plugin/Plugin.php';
18
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/RatingPrompt.php';
19
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Library/Activity.php';
20
+ require_once dirname( dirname( __FILE__ ) ) . '/src/Util/Option.php';
21
+
22
+ require $_tests_dir . '/includes/bootstrap.php';
23
+
vendor/boldgrid/library/yarn.lock CHANGED
@@ -307,9 +307,9 @@ chalk@^1.0.0, chalk@^1.1.3:
307
  supports-color "^2.0.0"
308
 
309
  chalk@^2.0.0, chalk@^2.1.0:
310
- version "2.4.1"
311
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
312
- integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==
313
  dependencies:
314
  ansi-styles "^3.2.1"
315
  escape-string-regexp "^1.0.5"
@@ -445,9 +445,9 @@ copy-props@^2.0.1:
445
  is-plain-object "^2.0.1"
446
 
447
  core-js@^2.4.0:
448
- version "2.5.7"
449
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
450
- integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==
451
 
452
  core-util-is@~1.0.0:
453
  version "1.0.2"
@@ -570,15 +570,10 @@ dom-serializer@0:
570
  domelementtype "~1.1.1"
571
  entities "~1.1.1"
572
 
573
- domelementtype@1:
574
- version "1.2.1"
575
- resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.2.1.tgz#578558ef23befac043a1abb0db07635509393479"
576
- integrity sha512-SQVCLFS2E7G5CRCMdn6K9bIhRj1bS6QBWZfF0TUPh4V/BbqrQ619IdSS3/izn0FZ+9l+uODzaZjb08fjOfablA==
577
-
578
- domelementtype@^1.3.0:
579
- version "1.3.0"
580
- resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
581
- integrity sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=
582
 
583
  domelementtype@~1.1.1:
584
  version "1.1.3"
@@ -848,12 +843,13 @@ extglob@^2.0.4:
848
  to-regex "^3.0.1"
849
 
850
  fancy-log@^1.1.0, fancy-log@^1.3.2:
851
- version "1.3.2"
852
- resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.2.tgz#f41125e3d84f2e7d89a43d06d958c8f78be16be1"
853
- integrity sha1-9BEl49hPLn2JpD0G2VjI94vha+E=
854
  dependencies:
855
  ansi-gray "^0.1.1"
856
  color-support "^1.1.3"
 
857
  time-stamp "^1.0.0"
858
 
859
  fast-deep-equal@^1.0.0:
@@ -927,9 +923,9 @@ findup-sync@^2.0.0:
927
  resolve-dir "^1.0.1"
928
 
929
  fined@^1.0.1:
930
- version "1.1.0"
931
- resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.0.tgz#b37dc844b76a2f5e7081e884f7c0ae344f153476"
932
- integrity sha1-s33IRLdqL15wgeiE98CuNE8VNHY=
933
  dependencies:
934
  expand-tilde "^2.0.2"
935
  is-plain-object "^2.0.3"
@@ -943,9 +939,9 @@ first-chunk-stream@^1.0.0:
943
  integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=
944
 
945
  flagged-respawn@^1.0.0:
946
- version "1.0.0"
947
- resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.0.tgz#4e79ae9b2eb38bf86b3bb56bf3e0a56aa5fcabd7"
948
- integrity sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=
949
 
950
  flat-cache@^1.2.1:
951
  version "1.3.4"
@@ -1049,7 +1045,7 @@ glob@^4.3.1:
1049
  minimatch "^2.0.1"
1050
  once "^1.3.0"
1051
 
1052
- glob@^7.0.5, glob@^7.1.1, glob@^7.1.2:
1053
  version "7.1.3"
1054
  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
1055
  integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
@@ -1103,9 +1099,9 @@ global-prefix@^1.0.1:
1103
  which "^1.2.14"
1104
 
1105
  globals@^11.0.1:
1106
- version "11.9.0"
1107
- resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249"
1108
- integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==
1109
 
1110
  globule@~0.1.0:
1111
  version "0.1.0"
@@ -1117,9 +1113,9 @@ globule@~0.1.0:
1117
  minimatch "~0.2.11"
1118
 
1119
  glogg@^1.0.0:
1120
- version "1.0.1"
1121
- resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810"
1122
- integrity sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==
1123
  dependencies:
1124
  sparkles "^1.0.0"
1125
 
@@ -1359,9 +1355,9 @@ inquirer@^3.0.6:
1359
  through "^2.3.6"
1360
 
1361
  interpret@^1.0.0, interpret@^1.1.0:
1362
- version "1.1.0"
1363
- resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
1364
- integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=
1365
 
1366
  invert-kv@^1.0.0:
1367
  version "1.0.0"
@@ -1566,9 +1562,9 @@ js-tokens@^3.0.2:
1566
  integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
1567
 
1568
  js-yaml@^3.9.1:
1569
- version "3.12.0"
1570
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
1571
- integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==
1572
  dependencies:
1573
  argparse "^1.0.7"
1574
  esprima "^4.0.0"
@@ -1798,12 +1794,12 @@ lru-cache@2:
1798
  integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=
1799
 
1800
  lru-cache@^4.0.1:
1801
- version "4.1.4"
1802
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.4.tgz#51cc46e8e6d9530771c857e24ccc720ecdbcc031"
1803
- integrity sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA==
1804
  dependencies:
1805
  pseudomap "^1.0.2"
1806
- yallist "^3.0.2"
1807
 
1808
  make-iterator@^1.0.0:
1809
  version "1.0.1"
@@ -2192,6 +2188,11 @@ parse-json@^2.2.0:
2192
  dependencies:
2193
  error-ex "^1.2.0"
2194
 
 
 
 
 
 
2195
  parse-passwd@^1.0.0:
2196
  version "1.0.0"
2197
  resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
@@ -2229,7 +2230,7 @@ path-key@^2.0.0:
2229
  resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
2230
  integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
2231
 
2232
- path-parse@^1.0.5:
2233
  version "1.0.6"
2234
  resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
2235
  integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
@@ -2331,9 +2332,9 @@ prettier-eslint@^8.5.0, prettier-eslint@^8.8.1:
2331
  vue-eslint-parser "^2.0.2"
2332
 
2333
  prettier@^1.7.0:
2334
- version "1.15.2"
2335
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e"
2336
- integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug==
2337
 
2338
  pretty-format@^23.0.1:
2339
  version "23.6.0"
@@ -2354,9 +2355,9 @@ process-nextick-args@~2.0.0:
2354
  integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
2355
 
2356
  progress@^2.0.0:
2357
- version "2.0.1"
2358
- resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31"
2359
- integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==
2360
 
2361
  pseudomap@^1.0.2:
2362
  version "1.0.2"
@@ -2409,9 +2410,9 @@ readable-stream@^2.2.2, readable-stream@~2.3.6:
2409
  util-deprecate "~1.0.1"
2410
 
2411
  readable-stream@^3.0.6:
2412
- version "3.0.6"
2413
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.0.6.tgz#351302e4c68b5abd6a2ed55376a7f9a25be3057a"
2414
- integrity sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==
2415
  dependencies:
2416
  inherits "^2.0.3"
2417
  string_decoder "^1.1.1"
@@ -2528,11 +2529,11 @@ resolve-url@^0.2.1:
2528
  integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
2529
 
2530
  resolve@^1.1.6, resolve@^1.1.7, resolve@^1.4.0:
2531
- version "1.8.1"
2532
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
2533
- integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==
2534
  dependencies:
2535
- path-parse "^1.0.5"
2536
 
2537
  restore-cursor@^2.0.0:
2538
  version "2.0.0"
@@ -2548,11 +2549,11 @@ ret@~0.1.10:
2548
  integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
2549
 
2550
  rimraf@~2.6.2:
2551
- version "2.6.2"
2552
- resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
2553
- integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==
2554
  dependencies:
2555
- glob "^7.0.5"
2556
 
2557
  run-async@^2.2.0:
2558
  version "2.3.0"
@@ -2735,9 +2736,9 @@ sparkles@^1.0.0:
2735
  integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==
2736
 
2737
  spdx-correct@^3.0.0:
2738
- version "3.0.2"
2739
- resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e"
2740
- integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==
2741
  dependencies:
2742
  spdx-expression-parse "^3.0.0"
2743
  spdx-license-ids "^3.0.0"
@@ -2756,9 +2757,9 @@ spdx-expression-parse@^3.0.0:
2756
  spdx-license-ids "^3.0.0"
2757
 
2758
  spdx-license-ids@^3.0.0:
2759
- version "3.0.2"
2760
- resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2"
2761
- integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==
2762
 
2763
  split-string@^3.0.1, split-string@^3.0.2:
2764
  version "3.1.0"
@@ -2807,10 +2808,10 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
2807
  is-fullwidth-code-point "^2.0.0"
2808
  strip-ansi "^4.0.0"
2809
 
2810
- string_decoder@^1.1.1, string_decoder@~1.1.1:
2811
- version "1.1.1"
2812
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
2813
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
2814
  dependencies:
2815
  safe-buffer "~5.1.0"
2816
 
@@ -2819,6 +2820,13 @@ string_decoder@~0.10.x:
2819
  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
2820
  integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
2821
 
 
 
 
 
 
 
 
2822
  strip-ansi@^3.0.0, strip-ansi@^3.0.1:
2823
  version "3.0.1"
2824
  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
@@ -3053,9 +3061,9 @@ v8flags@^2.0.2:
3053
  user-home "^1.1.1"
3054
 
3055
  v8flags@^3.0.1:
3056
- version "3.1.1"
3057
- resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.1.tgz#42259a1461c08397e37fe1d4f1cfb59cad85a053"
3058
- integrity sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ==
3059
  dependencies:
3060
  homedir-polyfill "^1.0.1"
3061
 
@@ -3162,10 +3170,10 @@ y18n@^3.2.1:
3162
  resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
3163
  integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
3164
 
3165
- yallist@^3.0.2:
3166
- version "3.0.2"
3167
- resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9"
3168
- integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=
3169
 
3170
  yargs-parser@^5.0.0:
3171
  version "5.0.0"
307
  supports-color "^2.0.0"
308
 
309
  chalk@^2.0.0, chalk@^2.1.0:
310
+ version "2.4.2"
311
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
312
+ integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
313
  dependencies:
314
  ansi-styles "^3.2.1"
315
  escape-string-regexp "^1.0.5"
445
  is-plain-object "^2.0.1"
446
 
447
  core-js@^2.4.0:
448
+ version "2.6.2"
449
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944"
450
+ integrity sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g==
451
 
452
  core-util-is@~1.0.0:
453
  version "1.0.2"
570
  domelementtype "~1.1.1"
571
  entities "~1.1.1"
572
 
573
+ domelementtype@1, domelementtype@^1.3.0:
574
+ version "1.3.1"
575
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
576
+ integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
 
 
 
 
 
577
 
578
  domelementtype@~1.1.1:
579
  version "1.1.3"
843
  to-regex "^3.0.1"
844
 
845
  fancy-log@^1.1.0, fancy-log@^1.3.2:
846
+ version "1.3.3"
847
+ resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7"
848
+ integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==
849
  dependencies:
850
  ansi-gray "^0.1.1"
851
  color-support "^1.1.3"
852
+ parse-node-version "^1.0.0"
853
  time-stamp "^1.0.0"
854
 
855
  fast-deep-equal@^1.0.0:
923
  resolve-dir "^1.0.1"
924
 
925
  fined@^1.0.1:
926
+ version "1.1.1"
927
+ resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.1.tgz#95d88ff329123dd1a6950fdfcd321f746271e01f"
928
+ integrity sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==
929
  dependencies:
930
  expand-tilde "^2.0.2"
931
  is-plain-object "^2.0.3"
939
  integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=
940
 
941
  flagged-respawn@^1.0.0:
942
+ version "1.0.1"
943
+ resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41"
944
+ integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==
945
 
946
  flat-cache@^1.2.1:
947
  version "1.3.4"
1045
  minimatch "^2.0.1"
1046
  once "^1.3.0"
1047
 
1048
+ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3:
1049
  version "7.1.3"
1050
  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
1051
  integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
1099
  which "^1.2.14"
1100
 
1101
  globals@^11.0.1:
1102
+ version "11.10.0"
1103
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.10.0.tgz#1e09776dffda5e01816b3bb4077c8b59c24eaa50"
1104
+ integrity sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==
1105
 
1106
  globule@~0.1.0:
1107
  version "0.1.0"
1113
  minimatch "~0.2.11"
1114
 
1115
  glogg@^1.0.0:
1116
+ version "1.0.2"
1117
+ resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f"
1118
+ integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==
1119
  dependencies:
1120
  sparkles "^1.0.0"
1121
 
1355
  through "^2.3.6"
1356
 
1357
  interpret@^1.0.0, interpret@^1.1.0:
1358
+ version "1.2.0"
1359
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
1360
+ integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
1361
 
1362
  invert-kv@^1.0.0:
1363
  version "1.0.0"
1562
  integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
1563
 
1564
  js-yaml@^3.9.1:
1565
+ version "3.12.1"
1566
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600"
1567
+ integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==
1568
  dependencies:
1569
  argparse "^1.0.7"
1570
  esprima "^4.0.0"
1794
  integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=
1795
 
1796
  lru-cache@^4.0.1:
1797
+ version "4.1.5"
1798
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
1799
+ integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
1800
  dependencies:
1801
  pseudomap "^1.0.2"
1802
+ yallist "^2.1.2"
1803
 
1804
  make-iterator@^1.0.0:
1805
  version "1.0.1"
2188
  dependencies:
2189
  error-ex "^1.2.0"
2190
 
2191
+ parse-node-version@^1.0.0:
2192
+ version "1.0.0"
2193
+ resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.0.tgz#33d9aa8920dcc3c0d33658ec18ce237009a56d53"
2194
+ integrity sha512-02GTVHD1u0nWc20n2G7WX/PgdhNFG04j5fi1OkaJzPWLTcf6vh6229Lta1wTmXG/7Dg42tCssgkccVt7qvd8Kg==
2195
+
2196
  parse-passwd@^1.0.0:
2197
  version "1.0.0"
2198
  resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
2230
  resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
2231
  integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
2232
 
2233
+ path-parse@^1.0.6:
2234
  version "1.0.6"
2235
  resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
2236
  integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
2332
  vue-eslint-parser "^2.0.2"
2333
 
2334
  prettier@^1.7.0:
2335
+ version "1.15.3"
2336
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a"
2337
+ integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==
2338
 
2339
  pretty-format@^23.0.1:
2340
  version "23.6.0"
2355
  integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
2356
 
2357
  progress@^2.0.0:
2358
+ version "2.0.3"
2359
+ resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
2360
+ integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
2361
 
2362
  pseudomap@^1.0.2:
2363
  version "1.0.2"
2410
  util-deprecate "~1.0.1"
2411
 
2412
  readable-stream@^3.0.6:
2413
+ version "3.1.1"
2414
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06"
2415
+ integrity sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==
2416
  dependencies:
2417
  inherits "^2.0.3"
2418
  string_decoder "^1.1.1"
2529
  integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
2530
 
2531
  resolve@^1.1.6, resolve@^1.1.7, resolve@^1.4.0:
2532
+ version "1.9.0"
2533
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06"
2534
+ integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==
2535
  dependencies:
2536
+ path-parse "^1.0.6"
2537
 
2538
  restore-cursor@^2.0.0:
2539
  version "2.0.0"
2549
  integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
2550
 
2551
  rimraf@~2.6.2:
2552
+ version "2.6.3"
2553
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
2554
+ integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
2555
  dependencies:
2556
+ glob "^7.1.3"
2557
 
2558
  run-async@^2.2.0:
2559
  version "2.3.0"
2736
  integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==
2737
 
2738
  spdx-correct@^3.0.0:
2739
+ version "3.1.0"
2740
+ resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4"
2741
+ integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==
2742
  dependencies:
2743
  spdx-expression-parse "^3.0.0"
2744
  spdx-license-ids "^3.0.0"
2757
  spdx-license-ids "^3.0.0"
2758
 
2759
  spdx-license-ids@^3.0.0:
2760
+ version "3.0.3"
2761
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e"
2762
+ integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==
2763
 
2764
  split-string@^3.0.1, split-string@^3.0.2:
2765
  version "3.1.0"
2808
  is-fullwidth-code-point "^2.0.0"
2809
  strip-ansi "^4.0.0"
2810
 
2811
+ string_decoder@^1.1.1:
2812
+ version "1.2.0"
2813
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
2814
+ integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==
2815
  dependencies:
2816
  safe-buffer "~5.1.0"
2817
 
2820
  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
2821
  integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
2822
 
2823
+ string_decoder@~1.1.1:
2824
+ version "1.1.1"
2825
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
2826
+ integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
2827
+ dependencies:
2828
+ safe-buffer "~5.1.0"
2829
+
2830
  strip-ansi@^3.0.0, strip-ansi@^3.0.1:
2831
  version "3.0.1"
2832
  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
3061
  user-home "^1.1.1"
3062
 
3063
  v8flags@^3.0.1:
3064
+ version "3.1.2"
3065
+ resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.2.tgz#fc5cd0c227428181e6c29b2992e4f8f1da5e0c9f"
3066
+ integrity sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==
3067
  dependencies:
3068
  homedir-polyfill "^1.0.1"
3069
 
3170
  resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
3171
  integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
3172
 
3173
+ yallist@^2.1.2:
3174
+ version "2.1.2"
3175
+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
3176
+ integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
3177
 
3178
  yargs-parser@^5.0.0:
3179
  version "5.0.0"
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInita6df5ba1202853e2f5d815b67bc99335
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInita6df5ba1202853e2f5d815b67bc99335
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInita6df5ba1202853e2f5d815b67bc99335', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInita6df5ba1202853e2f5d815b67bc99335', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInita6df5ba1202853e2f5d815b67bc99335::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInita6df5ba1202853e2f5d815b67bc99335
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInita6df5ba1202853e2f5d815b67bc99335::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequirea6df5ba1202853e2f5d815b67bc99335($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
- function composerRequirea6df5ba1202853e2f5d815b67bc99335($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit3179cc8cf55bc33a7a6470fb79d3732a
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit3179cc8cf55bc33a7a6470fb79d3732a', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit3179cc8cf55bc33a7a6470fb79d3732a', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit3179cc8cf55bc33a7a6470fb79d3732a::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
+ $includeFiles = Composer\Autoload\ComposerStaticInit3179cc8cf55bc33a7a6470fb79d3732a::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequire3179cc8cf55bc33a7a6470fb79d3732a($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
+ function composerRequire3179cc8cf55bc33a7a6470fb79d3732a($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInita6df5ba1202853e2f5d815b67bc99335
8
  {
9
  public static $files = array (
10
  'f15d016d70663d5e96ccd2b863511eb8' => __DIR__ . '/..' . '/cbschuld/browser.php/lib/Browser.php',
@@ -91,9 +91,9 @@ class ComposerStaticInita6df5ba1202853e2f5d815b67bc99335
91
  public static function getInitializer(ClassLoader $loader)
92
  {
93
  return \Closure::bind(function () use ($loader) {
94
- $loader->prefixLengthsPsr4 = ComposerStaticInita6df5ba1202853e2f5d815b67bc99335::$prefixLengthsPsr4;
95
- $loader->prefixDirsPsr4 = ComposerStaticInita6df5ba1202853e2f5d815b67bc99335::$prefixDirsPsr4;
96
- $loader->classMap = ComposerStaticInita6df5ba1202853e2f5d815b67bc99335::$classMap;
97
 
98
  }, null, ClassLoader::class);
99
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit3179cc8cf55bc33a7a6470fb79d3732a
8
  {
9
  public static $files = array (
10
  'f15d016d70663d5e96ccd2b863511eb8' => __DIR__ . '/..' . '/cbschuld/browser.php/lib/Browser.php',
91
  public static function getInitializer(ClassLoader $loader)
92
  {
93
  return \Closure::bind(function () use ($loader) {
94
+ $loader->prefixLengthsPsr4 = ComposerStaticInit3179cc8cf55bc33a7a6470fb79d3732a::$prefixLengthsPsr4;
95
+ $loader->prefixDirsPsr4 = ComposerStaticInit3179cc8cf55bc33a7a6470fb79d3732a::$prefixDirsPsr4;
96
+ $loader->classMap = ComposerStaticInit3179cc8cf55bc33a7a6470fb79d3732a::$classMap;
97
 
98
  }, null, ClassLoader::class);
99
  }
vendor/composer/installed.json CHANGED
@@ -1,20 +1,20 @@
1
  [
2
  {
3
  "name": "boldgrid/library",
4
- "version": "2.7.4",
5
- "version_normalized": "2.7.4.0",
6
  "source": {
7
  "type": "git",
8
  "url": "https://github.com/BoldGrid/library.git",
9
- "reference": "59aa87fcf2cab210e605b922e0e12c7d897d01d5"
10
  },
11
  "dist": {
12
  "type": "zip",
13
- "url": "https://api.github.com/repos/BoldGrid/library/zipball/59aa87fcf2cab210e605b922e0e12c7d897d01d5",
14
- "reference": "59aa87fcf2cab210e605b922e0e12c7d897d01d5",
15
  "shasum": ""
16
  },
17
- "time": "2018-12-04T19:41:29+00:00",
18
  "type": "library",
19
  "installation-source": "dist",
20
  "autoload": {
1
  [
2
  {
3
  "name": "boldgrid/library",
4
+ "version": "2.7.7",
5
+ "version_normalized": "2.7.7.0",
6
  "source": {
7
  "type": "git",
8
  "url": "https://github.com/BoldGrid/library.git",
9
+ "reference": "e6b781f06c8b221c5139b05c980a8a84471fe7d7"
10
  },
11
  "dist": {
12
  "type": "zip",
13
+ "url": "https://api.github.com/repos/BoldGrid/library/zipball/e6b781f06c8b221c5139b05c980a8a84471fe7d7",
14
+ "reference": "e6b781f06c8b221c5139b05c980a8a84471fe7d7",
15
  "shasum": ""
16
  },
17
+ "time": "2019-01-15T17:43:46+00:00",
18
  "type": "library",
19
  "installation-source": "dist",
20
  "autoload": {