PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.18
VikAppointments Services Booking Calendar v1.2.18
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / libraries / adapter / module / helper.php
vikappointments / libraries / adapter / module Last commit date
factory.php 6 months ago helper.php 6 months ago widget.php 6 months ago
helper.php
218 lines
1 <?php
2 /**
3 * @package VikWP - Libraries
4 * @subpackage adapter.module
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2023 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 /**
15 * Helper class for WP widgets.
16 *
17 * @since 10.0
18 */
19 class JModuleHelper
20 {
21 /**
22 * Absolute path of the module.
23 * Since this class is located in the adapter package, it doesn't
24 * know the base path in which all the modules are located.
25 * This means that the path should be changed every time a module
26 * is going to be rendered.
27 *
28 * @var string
29 */
30 protected static $path = null;
31
32 /**
33 * Sets the base path in which the module is contained.
34 * The path should include also the module name.
35 *
36 * @param string $path The module path.
37 *
38 * @return void
39 */
40 public static function setPath($path)
41 {
42 static::$path = rtrim($path, DIRECTORY_SEPARATOR);
43 }
44
45 /**
46 * Gets the current base path.
47 *
48 * @param string $name The module name (optional).
49 *
50 * @return string The module path
51 */
52 public static function getPath($name = null)
53 {
54 // return null if no path
55 if (!static::$path)
56 {
57 return null;
58 }
59
60 // if the name is provided, make sure the path already contains it
61 if ($name)
62 {
63 // get the path chunks
64 $parts = explode(DIRECTORY_SEPARATOR, static::$path);
65
66 // if the last chunk doesn't match the module name, append it
67 if (end($parts) != $name)
68 {
69 $parts[] = $name;
70 }
71
72 // implode the chunks with the DS
73 return implode(DIRECTORY_SEPARATOR, $parts);
74 }
75
76 return static::$path;
77 }
78
79 /**
80 * Returns the layout path of the module.
81 *
82 * @param string $module The module name.
83 * @param string $layout The module layout name.
84 *
85 * @return string The module layout path (relative).
86 */
87 public static function getLayoutPath($module, $layout = null)
88 {
89 if (!$layout)
90 {
91 $layout = 'default';
92 }
93 else if (strpos($layout, DIRECTORY_SEPARATOR) !== false)
94 {
95 // make sure the given layout is a file
96 if (is_file($layout))
97 {
98 /**
99 * The layout is an absolute path that points to an existing
100 * override file. Use it instead of the default one.
101 *
102 * @since 10.1.2
103 */
104 return $layout;
105 }
106
107 /**
108 * Fallback to default layout and trigger error
109 * to inform the user that the configuration of
110 * the widget doesn't work as expected.
111 *
112 * @since 10.1.32
113 */
114 if (WP_DEBUG)
115 {
116 // the warning won't be displayed in production
117 trigger_error(
118 sprintf(
119 'Widget layout [%s] not found! The default one will be used',
120 $layout
121 ),
122 E_USER_WARNING
123 );
124 }
125
126 $layout = 'default';
127 }
128
129 // construct the layout path of the default module
130 $parts = array();
131 $parts[] = static::getPath($module);
132 $parts[] = 'tmpl';
133 $parts[] = $layout . '.php';
134
135 return implode(DIRECTORY_SEPARATOR, array_filter($parts));
136 }
137
138 /**
139 * Get module by element.
140 *
141 * @param string $name The name of the module.
142 *
143 * @return stdClass The Module object.
144 *
145 * @since 10.1.30
146 */
147 public static function getModule($name)
148 {
149 global $wp_widget_factory;
150
151 // build classname of the widget
152 $classname = str_replace('_', ' ', $name);
153 $classname = preg_replace("/\s+/", '', ucwords($classname)) . '_Widget';
154
155 // prepare result
156 $result = new stdClass;
157 $result->id = 0;
158 $result->module = $name;
159 $result->params = '';
160
161 if (isset($wp_widget_factory->widgets[$classname]))
162 {
163 // get settings of all the widgets of this type
164 $settings = $wp_widget_factory->widgets[$classname]->get_settings();
165
166 if ($settings)
167 {
168 // take only the first one
169 $result->id = key($settings);
170 $result->params = reset($settings);
171
172 // JSON encode params for Joomla compatibility
173 $result->params = json_encode($result->params);
174 }
175 }
176
177 /**
178 * If we are not able to find a widget, then we should look into the
179 * posts and pages in search of a Gutenberg block and extract the
180 * settings from there.
181 *
182 * @since 10.1.52
183 */
184 if (!$result->id)
185 {
186 // split the module name in chunks:
187 // [MOD] | [COMPONENT] | ...
188 $block = explode('_', $name);
189 // construct gutenberg block identifier
190 $block = $block[1] . '/' . implode('-', array_slice($block, 2)) . '-widget-block';
191
192 // look for a post/page that contains the block name of the requested module
193 $query = new WP_Query([
194 's' => '<!-- wp:' . $block,
195 ]);
196
197 // fetch all the matching posts, if any
198 foreach ($query->get_posts() as $post)
199 {
200 // use the same ID of the post
201 $result->id = $post->ID;
202
203 // escape characters of the module block name for being safely used in a regex
204 $regex = preg_quote($block, '/');
205
206 // extract parameters from block name
207 if (preg_match("/<!-- wp:$regex\s+({(?:.*?)})(?:.*?)-->/", $post->post_content, $match))
208 {
209 // keep the parameters encoded in JSON format for Joomla compatibility
210 $result->params = $match[1];
211 }
212 }
213 }
214
215 return $result;
216 }
217 }
218