PluginProbe
Buttonizer – Floating Menus, Sticky Buttons, & Popup Builder / 3.6.0
Buttonizer – Floating Menus, Sticky Buttons, & Popup Builder v3.6.0
3.6.0 3.5.0 trunk 1.0.10 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.6.1 1.0.7 1.0.8 1.0.9 1.1 1.1.1 1.2 1.3 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.5 1.5.1 All 110 releases
buttonizer-multifunctional-button / app / Migration / Detector.php

Detector.php in Buttonizer – Floating Menus, Sticky Buttons, & Popup Builder 3.6.0, at app/Migration/Detector.php

171 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * SOFTWARE LICENSE INFORMATION
4 *
5 * Copyright (c) 2017 Buttonizer, all rights reserved.
6 *
7 * This file is part of Buttonizer
8 *
9 * For detailed information regarding to the licensing of
10 * this software, please review the license.txt or visit:
11 * https://buttonizer.pro/license/
12 */
13
14 namespace Buttonizer\Migration;
15
16 # No script kiddies
17 defined('ABSPATH') or die('No script kiddies please!');
18
19 /**
20 * Classifies what a source plugin looks like on this site.
21 *
22 * Every state needs a different action, and applying the wrong one breaks the
23 * site — deactivating a legacy install without carrying its module over takes
24 * the user's buttons off the frontend. So detection happens once, explicitly,
25 * and the manager acts on the result.
26 */
27 class Detector
28 {
29 /** Source plugin is not installed and left no data behind. */
30 const STATE_NOT_PRESENT = 'not_present';
31
32 /** Installed, still running its own pre-Buttonizer system. */
33 const STATE_LEGACY = 'legacy';
34
35 /** Installed and connected to the Buttonizer cloud — migratable today. */
36 const STATE_CLOUD_CONNECTED = 'cloud_connected';
37
38 /** Installed on the cloud codebase but never connected. */
39 const STATE_CLOUD_DISCONNECTED = 'cloud_disconnected';
40
41 /** Already handed over to Buttonizer. */
42 const STATE_ALREADY_MIGRATED = 'already_migrated';
43
44 /**
45 * Detect the state of a source plugin.
46 *
47 * @param SourcePlugin $source Source plugin descriptor.
48 *
49 * @return string One of the STATE_* constants.
50 */
51 public static function detect(SourcePlugin $source): string
52 {
53 if (MigrationState::isMigrated($source->id())) {
54 return self::STATE_ALREADY_MIGRATED;
55 }
56
57 if (!self::hasFootprint($source)) {
58 return self::STATE_NOT_PRESENT;
59 }
60
61 if (self::isLegacy($source)) {
62 return self::STATE_LEGACY;
63 }
64
65 if (self::isCloudConnected($source)) {
66 return self::STATE_CLOUD_CONNECTED;
67 }
68
69 return self::STATE_CLOUD_DISCONNECTED;
70 }
71
72 /**
73 * Does the source plugin exist on this site in any form?
74 *
75 * Checks for the plugin files as well as leftover options, so a site that
76 * deleted the plugin but kept its data is still recognised.
77 */
78 public static function hasFootprint(SourcePlugin $source): bool
79 {
80 // Options first: they are autoloaded, while looking for the plugin
81 // files costs a filesystem check on every admin request.
82 if (get_option($source->settingsOption(), null) !== null) {
83 return true;
84 }
85
86 if (!empty(get_option($source->tokenOption(), ''))) {
87 return true;
88 }
89
90 if (self::hasLegacyOptions($source)) {
91 return true;
92 }
93
94 // Installed but never opened, so it has not written anything yet
95 return $source->isInstalled();
96 }
97
98 /**
99 * Is the source plugin running its own legacy system?
100 *
101 * Trusts the plugin's own flag when it has decided, and falls back to
102 * sniffing the legacy options for installs that never ran the detector.
103 */
104 public static function isLegacy(SourcePlugin $source): bool
105 {
106 $flagOption = $source->legacyFlagOption();
107
108 if ($flagOption) {
109 $flag = get_option($flagOption, null);
110
111 if ($flag !== null) {
112 return $flag === $source->legacyFlagValue();
113 }
114 }
115
116 return self::hasLegacyOptions($source);
117 }
118
119 /**
120 * Does the site carry any of the source plugin's legacy options?
121 */
122 public static function hasLegacyOptions(SourcePlugin $source): bool
123 {
124 foreach ($source->legacyOptions() as $option) {
125 $value = get_option($option, '');
126
127 if ($value !== '' && $value !== false && $value !== null) {
128 return true;
129 }
130 }
131
132 return false;
133 }
134
135 /**
136 * Is the source plugin connected to the Buttonizer cloud?
137 *
138 * Requires both a finished setup and a usable token — a half-finished
139 * signup is not something worth adopting.
140 */
141 public static function isCloudConnected(SourcePlugin $source): bool
142 {
143 $settings = get_option($source->settingsOption(), []);
144
145 if (!is_array($settings) || empty($settings['finished_setup']) || empty($settings['site_id'])) {
146 return false;
147 }
148
149 return !empty(self::readToken($source));
150 }
151
152 /**
153 * Read the source plugin's API token.
154 *
155 * Mirrors ApiRequest::getApiToken(): the token normally lives in an
156 * option, but can sit in a transient after a refresh.
157 *
158 * @return string Empty string when there is no token.
159 */
160 public static function readToken(SourcePlugin $source): string
161 {
162 $token = get_option($source->tokenOption(), '');
163
164 if (empty($token)) {
165 $token = get_transient($source->tokenOption());
166 }
167
168 return is_string($token) ? $token : '';
169 }
170 }
171