PluginProbe
Tableberg – Simple Gutenberg Table Block / 0.2.1
Tableberg – Simple Gutenberg Table Block v0.2.1
1.1.5 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 All 42 releases
tableberg / includes / Version_Sync_Manager.php

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

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