PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / update / adapter.php
vikappointments / site / helpers / libraries / update Last commit date
adapters 3 days ago adapter.php 3 days ago factory.php 3 days ago index.html 3 days ago rule.php 3 days ago urihandler.php 3 days ago
adapter.php
213 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 VAPLoader::import('libraries.update.rule');
15
16 /**
17 * Update adapter base class.
18 *
19 * @since 1.7
20 */
21 abstract class VAPUpdateAdapter
22 {
23 /**
24 * An array of rules to execute, grouped by method.
25 *
26 * @var VAPUpdateRule[]
27 */
28 protected $rules = array();
29
30 /**
31 * Method run during update process.
32 *
33 * @param mixed $parent The parent that calls this method.
34 *
35 * @return boolean True on success, otherwise false to stop the flow.
36 */
37 final public function update($parent)
38 {
39 // process "update" tasks pool
40 return $this->executeRules('update', $parent);
41 }
42
43 /**
44 * Method run during postflight process.
45 *
46 * @param mixed $parent The parent that calls this method.
47 *
48 * @return boolean True on success, otherwise false to stop the flow.
49 */
50 final public function finalise($parent)
51 {
52 // process "finalise" tasks pool
53 return $this->executeRules('finalise', $parent);
54 }
55
56 /**
57 * Method run before executing VikAppointments for the first time
58 * after the update completion.
59 *
60 * @param mixed $parent The parent that calls this method.
61 *
62 * @return void
63 */
64 final public function afterupdate($parent)
65 {
66 // process "afterupdate" tasks pool
67 $success = $this->executeRules('afterupdate', $parent);
68
69 if ($success)
70 {
71 // update BC version to the current one
72 VAPFactory::getConfig()->set('bcv', $this->getVersion($safe = false));
73 }
74
75 return $success;
76 }
77
78 /**
79 * Executes all the rules attached to the specified action.
80 *
81 * @param string $action The action to launch.
82 * @param mixed $parent The parent that calls this method.
83 *
84 * @return boolean True on success, false otherwise.
85 */
86 private function executeRules($action, $parent)
87 {
88 if (!isset($this->rules[$action]))
89 {
90 // nothing to execute
91 return true;
92 }
93
94 // iterate all rules
95 foreach ($this->rules[$action] as $rule)
96 {
97 // do not run the same rule more than once
98 if (!$rule->did())
99 {
100 // trigger the rule
101 if ($rule->launch($parent) === false)
102 {
103 // something went wrong, do not go ahead
104 return false;
105 }
106 }
107 }
108
109 // all the rules went fine
110 return true;
111 }
112
113 /**
114 * Attaches a new rule to execute.
115 * It is possible to pass either a VAPUpdateRule instance or a string,
116 * which will be used as identifier to auto-load the rule class.
117 *
118 * In example, in case of "foo_bar", the system will search for a class named
119 * "VAPUpdateRuleFooBar[VERSION]", with a path similar to this one:
120 * /libraries/update/adapters/[VERSION]/foo_bar.php
121 *
122 * The version has to be safely reported by replacing the dots with the underscores:
123 * "1.7" becomes "1_7".
124 *
125 * @param string $action The action to launch.
126 * @param mixed $rule Either a rule class or a string.
127 *
128 * @return self This object to support chaining.
129 *
130 * @throws RuntimeException
131 */
132 final protected function attachRule($action, $rule)
133 {
134 if (!isset($this->rules[$action]))
135 {
136 // init action pool first
137 $this->rules[$action] = array();
138 }
139
140 if (!$rule instanceof VAPUpdateRule)
141 {
142 // string received, auto-load it from the version folder
143 $version = $this->getVersion();
144
145 if (!$version)
146 {
147 // version not contained within the classname
148 throw new RuntimeException('Unable to detect the version', 500);
149 }
150
151 // attempt to load the file holding the rule
152 if (!VAPLoader::import('libraries.update.adapters.' . $version . '.' . $rule))
153 {
154 // rule not found
155 throw new RuntimeException(sprintf('Update rule [%s] not found for version [%s]', $rule, $version), 404);
156 }
157
158 // refactor rule alias to be compliant with the class name
159 $sfx = preg_replace("/_/", ' ', $rule);
160 $sfx = ucwords($sfx);
161 $sfx = preg_replace("/\s+/", '', $sfx);
162
163 // build rule classname
164 $classname = 'VAPUpdateRule' . $sfx . $version;
165
166 // make sure the class exists
167 if (!class_exists($classname))
168 {
169 // class not found
170 throw new RuntimeException(sprintf('Update rule class [%s] not found', $classname), 404);
171 }
172
173 // instantiate rule
174 $rule = new $classname();
175 }
176
177 // append the rule
178 $this->rules[$action][] = $rule;
179
180 return $this;
181 }
182
183 /**
184 * Returns the adapter version.
185 *
186 * @param string $safe False to replace underscores with dots.
187 *
188 * @return string
189 */
190 protected function getVersion($safe = true)
191 {
192 // get the classname of the current class
193 $classname = get_class($this);
194
195 // make sure the adapter includes the version within the name
196 if (preg_match("/^VAPUpdateAdapter([0-9_]+)$/", $classname, $match))
197 {
198 $version = end($match);
199
200 if (!$safe)
201 {
202 // replaces underscores with dots
203 $version = preg_replace("/_+/", '.', $version);
204 }
205
206 return $version;
207 }
208
209 // unable to detect the version
210 return null;
211 }
212 }
213