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_Manager.php

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

247 lines 6.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Version sync manager
4 *
5 * @package Tableberg
6 */
7
8 namespace Tableberg;
9
10 use Tableberg\includes\traits\Manager_Base_Trait;
11 require_once TABLEBERG_DIR_PATH . 'includes/traits/Manager_Base_Trait.php';
12 use WP_Error;
13 use function add_filter;
14 use function delete_transient;
15 use function get_transient;
16 use function is_wp_error;
17 use function set_transient;
18
19 // if called directly, abort.
20 if ( ! defined( 'WPINC' ) ) {
21 die();
22 }
23
24 /**
25 * Manager for version synchronization.
26 */
27 if (class_exists('Tableberg\Version_Sync_Manager')){
28 return;
29 }
30 class Version_Sync_Manager {
31 use Manager_Base_Trait;
32
33 /**
34 * Subscribers list.
35 *
36 * This array will contain subscriber slug name as keys and instances as values.
37 *
38 * @var array
39 */
40 private static $subscribers = array();
41
42 /**
43 * Seconds in an hour
44 */
45 const HOUR_IN_SECONDS = 60 * 60;
46
47 /**
48 * Error transient key.
49 */
50 const VERSION_SYNC_ERROR_TRANSIENT_KEY = 'tableberg-blocks-version-sync-error';
51
52 /**
53 * Version sync trigger key for upgrader skin.
54 */
55 const TABLEBERG_VERSION_SYNC_TRIGGER = 'tableberg-version-sync-trigger';
56
57 /**
58 * Main process that will be called during initialization of manager.
59 *
60 * @return void
61 */
62 protected function init_process() {
63 add_filter( 'upgrader_pre_download', array( __CLASS__, 'call_subs' ), 10, 3 );
64
65 static::show_error_message();
66 }
67
68 /**
69 * If supplied id is a subscriber.
70 *
71 * @param string $sub_id subscriber id.
72 *
73 * @return bool is subscribed or not
74 */
75 private static function is_subscribed( $sub_id ) {
76 return isset( static::$subscribers[ $sub_id ] );
77 }
78
79 /**
80 * Get a subscriber.
81 *
82 * @param string $sub_id subscriber id.
83 *
84 * @return object|null subscriber context or null if no subscriber is found
85 */
86 private static function get_subscriber( $sub_id ) {
87 $sub = null;
88
89 if ( static::is_subscribed( $sub_id ) ) {
90 $sub = static::$subscribers[ $sub_id ];
91 }
92
93 return $sub;
94 }
95
96 /**
97 * Call subscribers.
98 *
99 * Subscribers will be called at every time an update/downgrade package is started downloading through WordPress upgrader methods. This filter hook will be used as a short circuit to continue/stop current update process depending on values available and responses gathered from subscribers of the manager.
100 *
101 * @param bool $status status of download.
102 * @param string $package package url.
103 * @param Object $context upgrader class context.
104 *
105 * @return bool|WP_Error status of download process
106 */
107 public static function call_subs( $status, $package, $context ) {
108 $final_status = $status;
109
110 if ( is_object( $context ) && property_exists( $context, 'skin' ) ) {
111 $upgrader_skin = $context->skin;
112
113 if ( property_exists( $upgrader_skin, 'plugin_info' ) ) {
114 $plugin_info = (array) $upgrader_skin->plugin_info;
115
116 // short circuit sub calling if current installation process marked as not to trigger version sync manager.
117 if ( isset( $plugin_info[ self::TABLEBERG_VERSION_SYNC_TRIGGER ] ) && $plugin_info[ self::TABLEBERG_VERSION_SYNC_TRIGGER ] === false ) {
118 return $final_status;
119 }
120
121 if ( isset( $plugin_info['slug'] ) && null !== $plugin_info['slug'] ) {
122 $slug = $plugin_info['slug'];
123 } elseif ( isset( $plugin_info['TextDomain'] ) ) {
124 $slug = $plugin_info['TextDomain'];
125 }
126
127 if ( null === $slug ) {
128 return $final_status;
129 }
130
131 // @deprecated
132 // for WP versions 4.9-5.0.2 there is no hook extra argument for this callback hook, so there is no need to check hook_extra
133 // $slug = static::parse_slug_from_relative_path( $hook_extra['plugin'] );
134
135 // only continue logic operations if slug of plugin that is currently being on installation process is a subscribed one.
136 if ( static::is_subscribed( $slug ) ) {
137 // get subscriber context of the addon currently in install process.
138 $active_sub = static::get_subscriber( $slug );
139
140 if ( null !== $active_sub ) {
141 $version = $active_sub->parse_version_from_package( $package );
142
143 // return if version can not be parsed.
144 if ( null === $version ) {
145 return $final_status;
146 }
147
148 // filter subscriber array to get all subscribers except the one currently target of the installation process.
149 $other_subs = array_filter(
150 static::$subscribers,
151 function ( $sub_id ) use ( $slug ) {
152 return $sub_id !== $slug;
153
154 },
155 ARRAY_FILTER_USE_KEY
156 );
157
158 $final_status = array_reduce(
159 array_keys( $other_subs ),
160 function ( $carry, $sub_id ) use ( $slug, $version, $other_subs ) {
161 $sub_status = $other_subs[ $sub_id ]->version_sync_logic( $slug, $version );
162 if ( is_wp_error( $sub_status ) ) {
163 $carry = $sub_status;
164 }
165
166 return $carry;
167 },
168 $final_status
169 );
170
171 // if collective final status is not an error, signal other subscribers to upgrade/downgrade/do nothing themselves.
172 if ( ! is_wp_error( $final_status ) ) {
173 foreach ( $other_subs as $sub_id => $context ) {
174 $context->install( $slug, $version );
175 }
176 }
177 }
178 }
179 }
180 }
181
182 // set an admin notification for error display.
183 if ( is_wp_error( $final_status ) ) {
184 static::set_admin_error_notice( $final_status->get_error_message() );
185 }
186
187 return $final_status;
188 }
189
190 /**
191 * Parse plugin slug from its relative path of entry file to plugin directory.
192 *
193 * @param string $relative_path relative path.
194 *
195 * @return null|string slug or null if no slug found from path
196 */
197 private static function parse_slug_from_relative_path( $relative_path ) {
198 $match = array();
199 preg_match( '/^.+\/(.+)\.php$/', $relative_path, $match );
200
201 if ( isset( $match[1] ) ) {
202 return $match[1];
203 }
204
205 return null;
206 }
207
208 /**
209 * Subscribe to version sync manager events.
210 *
211 * @param string $slug slug name.
212 * @param Object $instance subscriber class instance.
213 */
214 public static function subscribe( $slug, $instance ) {
215 if ( is_subclass_of(
216 $instance,
217 '\Tableberg\includes\Version_Sync_Base'
218 ) || is_subclass_of(
219 $instance,
220 '\Tableberg_Pro\Inc\Version_Sync_Base'
221 ) ) {
222 static::$subscribers[ $slug ] = $instance;
223 }
224 }
225
226 /**
227 * Show admin error messages at admin notice board.
228 */
229 public static function show_error_message() {
230 $error_message = get_transient( self::VERSION_SYNC_ERROR_TRANSIENT_KEY );
231
232 if ( false !== $error_message ) {
233 Admin_Notices_Manager::show_notice( $error_message, Admin_Notices_Manager::ERROR );
234 delete_transient( self::VERSION_SYNC_ERROR_TRANSIENT_KEY );
235 }
236 }
237
238 /**
239 * Set an admin error message.
240 *
241 * @param string $message message.
242 */
243 private static function set_admin_error_notice( $message ) {
244 set_transient( self::VERSION_SYNC_ERROR_TRANSIENT_KEY, $message, self::HOUR_IN_SECONDS );
245 }
246 }
247