PluginProbe
Tableberg – Simple Gutenberg Table Block / 0.4.1
Tableberg – Simple Gutenberg Table Block v0.4.1
1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 trunk 0.0.2 0.2.1 0.3.2 0.3.3 0.4.1 0.5.0 0.5.1 0.5.2 0.5.3 0.5.4 0.5.5 0.5.6 0.5.7 0.5.8 All 41 releases
tableberg / includes / Version_Sync_Base.php

Version_Sync_Base.php in Tableberg – Simple Gutenberg Table Block 0.4.1, at includes/Version_Sync_Base.php

296 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Version sync base
4 *
5 * @package Tableberg
6 */
7
8 namespace Tableberg\includes;
9
10 use Plugin_Upgrader;
11 use Tableberg\includes\Version_Control_Upgrader_Skin;
12 use Tableberg\Version_Sync_Manager;
13 use WP_Error;
14 use function add_filter;
15
16 // if called directly, abort.
17 if ( ! defined( 'WPINC' ) ) {
18 die();
19 }
20
21 /**
22 * Class Version_Sync_Base.
23 *
24 * Abstract class for version sync operations for base plugin and its addons.
25 */
26 abstract class Version_Sync_Base {
27 /**
28 * Minute in seconds.
29 */
30 const MINUTE_IN_SECONDS = 60;
31
32 /**
33 * Check availability of version sync manager.
34 *
35 * @return bool status
36 */
37 private function check_version_sync_manager_availability() {
38 return class_exists( '\Tableberg\includes\Version_Sync_Manager' );
39 }
40
41 /**
42 * Get slug of plugin/addon used in its distribution API.
43 *
44 * @return string slug
45 */
46 abstract public function get_version_slug();
47
48 /**
49 * Get text domain of the plugin.
50 *
51 * It will be used for ajax upgraders to identify our plugin since slug is not supplied in plugin info property of that upgrader skin.
52 *
53 * @return string
54 */
55 abstract public function get_text_domain();
56
57 /**
58 * Parse version number from package url.
59 *
60 * @param string $package package url.
61 *
62 * @return string|null version number
63 */
64 abstract public function parse_version_from_package( $package );
65
66 /**
67 * Plugin __FILE__
68 *
69 * @return string plugin file
70 */
71 abstract public function plugin_file();
72
73 /**
74 * Callback hook for version sync manager when a subscriber attempted an installation operation.
75 *
76 * @param string $slug subscriber slug.
77 * @param string $version version to install.
78 *
79 * @return false|WP_Error false to permit install(I know, but it is what it is) or WP_Error to cancel it
80 */
81 abstract public function version_sync_logic( $slug, $version );
82
83 /**
84 * Subscribe to version events of version sync manager.
85 */
86 final public function subscribe_to_version_sync() {
87 if ( $this->check_version_sync_manager_availability() ) {
88 Version_Sync_Manager::subscribe( $this->get_version_slug(), $this );
89 }
90 }
91
92 /**
93 * Plugin specific logic for fetching versions and their info.
94 *
95 * Use plugin version for keys and info for their values. Use 'url' property key for download link.
96 *
97 * @return array|WP_Error versions array
98 */
99 abstract protected function get_plugin_versions();
100
101 /**
102 * Get All available plugin versions and their infos.
103 *
104 * To minimize API calls , this function will set the value of versions info as a transient object with an expiration timer.
105 *
106 * @param bool $force force to fetch versions from remote Freemius API.
107 *
108 * @return WP_Error|array plugin versions
109 */
110 final protected function plugin_versions( $force = false ) {
111 $transient_key = 'tableberg-' . $this->get_version_slug() . '-versions-info';
112 $versions_info = false;
113
114 // get cached version if force options is disabled.
115 if ( ! $force ) {
116 $versions_info = get_transient( $transient_key );
117 }
118
119 if ( false === $versions_info || ! is_array( $versions_info ) ) {
120 // use extending components implemented function to fetch version info.
121 $versions_info = $this->get_plugin_versions();
122
123 // if an error occurred on fetch process, don't update transient value.
124 if ( ! is_wp_error( $versions_info ) ) {
125 // 10 minute expiration timer for transient data
126 set_transient( $transient_key, $versions_info, 10 * self::MINUTE_IN_SECONDS );
127 }
128 }
129
130 return $versions_info;
131 }
132
133
134 /**
135 * Install a version of subscriber.
136 *
137 * @param string $calling_slug slug of calling plugin.
138 * @param string $version version to install.
139 */
140 public function install( $calling_slug, $version ) {
141 $current_version = get_plugin_data( $this->plugin_file() ) ['Version'];
142
143 // only continue to install process if version is different from the current one.
144 if ( $version !== $current_version ) {
145 $relative_path = str_replace( trailingslashit( WP_PLUGIN_DIR ), '', $this->plugin_file() );
146 $versions = $this->plugin_versions();
147 if ( isset( $versions[ $version ] ['url'] ) ) {
148 $this->install_version( $relative_path, $versions[ $version ] ['url'] );
149 }
150 }
151 }
152
153 /**
154 * Install version of plugin.
155 *
156 * @param string $relative_path relative path of entry file of plugin to plugin directory.
157 * @param string $package_url package url.
158 * @param bool $trigger_sync_manager whether this installation process should also trigger version sync manager.
159 *
160 * @return bool|WP_Error true on success, false or WP_Error on failure
161 */
162 final protected function install_version( $relative_path, $package_url, $trigger_sync_manager = false ) {
163 require_once ABSPATH . 'wp-admin/includes/file.php';
164 require_once ABSPATH . 'wp-admin/includes/misc.php';
165 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
166 require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
167
168 // instantiate plugin upgrader with a custom upgrader skin.
169 $upgrader = new Plugin_Upgrader(
170 new Version_Control_Upgrader_Skin(
171 array(),
172 array( Version_Sync_Manager::TABLEBERG_VERSION_SYNC_TRIGGER => false )
173 )
174 );
175
176 add_filter(
177 'upgrader_package_options',
178 function ( $options ) use ( $relative_path, $trigger_sync_manager ) {
179 $options['abort_if_destination_exists'] = false;
180 $options['hook_extra'] = array_merge(
181 $options['hook_extra'],
182 array(
183 'plugin' => $relative_path,
184 Version_Sync_Manager::TABLEBERG_VERSION_SYNC_TRIGGER => $trigger_sync_manager,
185 )
186 );
187
188 return $options;
189 }
190 );
191
192 return $upgrader->install( $package_url, array( 'overwrite_package' => true ) );
193 }
194
195 /**
196 * Check if supplied version is within limits of defined pro versions.
197 *
198 * @param string $version version number to check.
199 * @param array $versions_info versions info array.
200 *
201 * @return bool within limits or not
202 */
203 final protected function is_within_defined_version_limits( $version, $versions_info ) {
204 return in_array( $version, array_keys( $versions_info ) );
205 }
206
207 /**
208 * Generic sync logic that can be used for common install operations.
209 *
210 * @param string $slug subscriber slug.
211 * @param string $version version to install.
212 *
213 * @return bool|WP_Error false for approval or WP_Error on failure
214 */
215 final protected function generic_sync_logic( $slug, $version ) {
216 // override this value for return values of separate version sync logic results.
217 $return_value = false;
218
219 // get all available plugin versions.
220 $versions_info = $this->plugin_versions();
221
222 if ( is_wp_error( $versions_info ) ) {
223 return $return_value;
224 }
225
226 // version is within limits of pro versions.
227 if ( $this->is_within_defined_version_limits( $version, $versions_info ) ) {
228 $return_value = false;
229 } elseif ( version_compare( $version, $this->highest_lowest_version_available( false ), '>' ) ) {
230 // force fetch versions info to check for a last minute latest pro version update.
231 $this->plugin_versions( true );
232
233 // no update found, give error.
234 if ( $version !== $this->highest_lowest_version_available( false ) ) {
235 $return_value = new WP_Error(
236 501,
237 sprintf(
238 esc_html__(
239 'Version mismatch: Version %1$s is not available for %2$s, please check for an update later.',
240 'tableberg'
241 ),
242 $version,
243 $this->get_version_slug()
244 )
245 );
246 } else {
247 // update found.
248 $return_value = false;
249 }
250 } else {
251 // version in check is out of stable bounds of pro addon.
252 $return_value = new WP_Error(
253 501,
254 sprintf(
255 esc_html__( 'Version mismatch: Version %1$s is not available for %2$s.', 'tableberg' ),
256 $version,
257 $this->get_version_slug()
258 )
259 );
260 }
261
262 return $return_value;
263 }
264
265 /**
266 * Highest/Lowest version available for pro.
267 *
268 * @param bool $lowest get the lowest version, if not will get highest.
269 * @param null|array $versions versions info array to use, if not supplied, version infos will be fetched.
270 *
271 * @return string lowest version available
272 */
273 final public function highest_lowest_version_available( $lowest = true, $versions = null ) {
274 $array_to_use = $versions;
275
276 if ( null === $array_to_use || ! is_array( $array_to_use ) ) {
277 // if no versions array is supplied, fetch versions info from api.
278 $array_to_use = $this->plugin_versions();
279
280 if ( is_wp_error( $array_to_use ) ) {
281 $array_to_use = array();
282 }
283 }
284
285 $operator = $lowest ? '<' : '>';
286
287 return array_reduce(
288 array_keys( $array_to_use ),
289 function ( $carry, $version ) use ( $operator ) {
290 return null === $carry ? $version : ( version_compare( $carry, $version, $operator ) ? $carry : $version );
291 },
292 null
293 );
294 }
295 }
296