PluginProbe
Themify Builder / 7.6.5
Themify Builder v7.6.5
7.8.1 7.8.0 7.7.9 7.7.8 7.7.7 7.7.6 7.7.5 7.7.4 7.7.3 7.7.2 trunk 7.6.0 7.6.1 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.8 7.6.9 7.7.0 7.7.1
themify-builder / modules / module-widget.php

module-widget.php in Themify Builder 7.6.5, at modules/module-widget.php

335 lines 12.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 defined('ABSPATH') || exit;
4
5 /**
6 * Module Name: Widget
7 * Description: Display any available widgets
8 */
9 class TB_Widget_Module extends Themify_Builder_Component_Module {
10
11 public static function init():void {
12 add_action('wp_ajax_tb_get_widget_items', array(__CLASS__, 'get_items'));
13 add_action('wp_ajax_module_widget_get_form', array(__CLASS__, 'widget_get_form'), 10);
14 add_action('tb_data_before_save', array(__CLASS__, 'before_builder_save'), 10, 2);
15 }
16
17 public static function get_module_name():string {
18 return __('Widget', 'themify');
19 }
20
21 public static function get_items() {
22 $result = array();
23 global $wp_widget_factory;
24 if (!empty($wp_widget_factory->widgets)) {
25 foreach ($wp_widget_factory->widgets as $widget) {
26 $class = get_class($widget);
27 $result[$class] = array('n' => $widget->name, 'b' => $widget->id_base);
28 if (!empty($widget->widget_options['description'])) {
29 $result[$class]['d'] = $widget->widget_options['description'];
30 }
31 }
32 }
33
34 $columns = array_column($result, 'n');
35 array_multisort($columns, SORT_ASC, $result);
36
37 die(json_encode($result));
38 }
39
40 /**
41 * Get a widget's registered key in $wp_widget_factory from its classname.
42 * register_widget() works with WP_Widget instances too, in such cases the
43 * widget's key is a hashed string.
44 *
45 * @return string|null
46 */
47 public static function get_widget_factory_name($classname) {
48 if (empty($classname) || !class_exists($classname,false)) {
49 return;
50 }
51 global $wp_widget_factory;
52 if (isset($wp_widget_factory->widgets[$classname])) {
53 return $classname;
54 }
55 foreach ($wp_widget_factory->widgets as $key => $widget) {
56 if ($widget instanceof WP_Widget && get_class($widget) === $classname) {
57 return $key;
58 }
59 }
60 }
61
62 public static function widget_get_form() {
63 check_ajax_referer('tf_nonce', 'nonce');
64
65 global $wp_widget_factory;
66 require_once ABSPATH . 'wp-admin/includes/widgets.php';
67 $widget_class = $_POST['load_class'];
68 if ($widget_class == '') {
69 die(-1);
70 }
71 $widget_class = str_replace('\\\\', '\\', $widget_class);
72
73 try {
74 $instance = !empty($_POST['widget_instance']) && $_POST['widget_instance'] !== 'null' ? $_POST['widget_instance'] : array();
75 if ( is_string( $instance ) ) {
76 $instance = json_decode( stripslashes( $instance ), true );
77 }
78 } catch( Exception $e ) {
79 $instance = [];
80 }
81 $instance = TB_Widget_Module::sanitize_widget_instance($instance);
82
83 $widget_key = self::get_widget_factory_name($widget_class);
84 if (!$widget_key) {
85 die(-1);
86 }
87 $widget = $wp_widget_factory->widgets[$widget_key];
88
89 $widget->number = next_widget_id_number($_POST['id_base']);
90 ob_start();
91 $instance = stripslashes_deep($instance);
92 $template = '';
93 $src = array();
94
95 if (empty($_POST['tpl_loaded']) && method_exists($widget, 'render_control_template_scripts')) {
96 require_once ABSPATH . WPINC . '/media-template.php';
97 ob_start();
98 $widget->render_control_template_scripts();
99 if ($widget->id_base !== 'text') {
100 wp_print_media_templates();
101 }
102
103 $template = ob_get_contents();
104 ob_end_clean();
105 $widget->enqueue_admin_scripts();
106 $type = str_replace('_', '-', $widget->id_base) . '-widget';
107 if ($widget->id_base === 'text') {
108 $type .= 's';
109 }
110 wp_enqueue_script($type);
111 global $wp_scripts;
112 if (isset($wp_scripts->registered[$type])) {
113 $script = $wp_scripts->registered[$type];
114 if ($widget->id_base !== 'text' && !empty($wp_scripts->registered[$type]->deps)) {
115 foreach ($wp_scripts->registered[$type]->deps as $deps) {
116 $src[] = array('src' => self::resolve_script_path($wp_scripts->registered[$deps]->src));
117 }
118 }
119
120 $src[] = array('src' => self::resolve_script_path($script->src), 'extra' => !empty($script->extra) ? $script->extra : '');
121 }
122 }
123 $widget->form($instance);
124 do_action('in_widget_form', $widget, null, $instance);
125 $form = ob_get_clean();
126 $base_name = 'widget-' . $widget->id_base . '\[' . $widget->number . '\]';
127 $form = preg_replace("/{$base_name}/", '', $form); // remove extra names
128 $form = str_replace(array(
129 '[',
130 ']'
131 ), '', $form); // remove extra [ & ] characters
132 $widget->form = $form;
133
134 /**
135 * The widget-id is not used to save widget data, it is however needed for compatibility
136 * with how core renders the module forms.
137 */
138 $form = '<div class="widget open">
139 <div class="widget-inside">
140 <div class="form">
141 <div class="widget-content">'
142 . $form .
143 '</div>
144 <input type="hidden" class="id_base" name="id_base" value="' . esc_attr($widget->id_base) . '" />
145 <input type="hidden" class="widget-id" name="widget-id" value="w_' . time() . '" />
146 <input type="hidden" class="widget-class" name="widget-class" value="' . $widget_class . '" />
147 </div>
148 </div>
149 <br/>
150 </div>';
151
152 global $wp_version;
153 wp_send_json(array(
154 'form' => $form,
155 'template' => $template,
156 'v' => $wp_version,
157 'src' => $src
158 ));
159 wp_die();
160 }
161
162 private static function resolve_script_path($src) {
163
164 $content_url = defined('WP_CONTENT_URL') ? WP_CONTENT_URL : '';
165
166 if (!preg_match('|^(https?:)?//|', $src) && !( $content_url && 0 === strpos($src, $content_url) )) {
167 if (!($guessurl = site_url() )) {
168 $guessurl = wp_guess_url();
169 }
170 $src = $guessurl . $src;
171 }
172
173 return $src;
174 }
175
176 /*
177 * Sanitize keys for widget fields
178 * This is required to provide backward compatibility with how widget data was saved.
179 *
180 * @return array
181 * @since 3.2.0
182 */
183
184 public static function sanitize_widget_instance($instance) {
185 if (is_array($instance)) {
186 foreach ($instance as $key => $val) {
187 preg_match('/.*\[\d\]\[(.*)\]/', $key, $matches);
188 if (isset($matches[1])) {
189 unset($instance[$key]);
190 $instance[$matches[1]] = $val;
191 }
192 }
193 }
194
195 return $instance;
196 }
197
198 /**
199 * Render plain content for static content.
200 *
201 * @param array $module
202 * @return string
203 */
204 public static function get_static_content(array $module):string {
205 if (!isset($module['mod_settings'])) {
206 return '';
207 }
208 return isset($module['mod_settings']['class_widget']) && 'Themify_Social_Links' === $module['mod_settings']['class_widget']?self::social_links_plain_content():parent::get_static_content($module);
209 }
210
211 private static function social_links_plain_content():string {
212 $out = '';
213 if (function_exists('themify_get_data')){
214 $data = themify_get_data();
215 $pre = 'setting-link_';
216
217 $field_ids = isset($data[$pre . 'field_ids']) ? json_decode($data[$pre . 'field_ids']) : false;
218
219 if (is_array($field_ids) || is_object($field_ids)) {
220 $out .= '<ul>';
221 $is_exist = function_exists('icl_t');
222 foreach ($field_ids as $fid) {
223
224 $title_name = $pre . 'title_' . $fid;
225
226 if ($is_exist) {
227 $title_val = icl_t('Themify', $title_name, $data[$title_name]);
228 } else {
229 $title_val = isset($data[$title_name]) ? $data[$title_name] : '';
230 }
231
232 $link_name = $pre . 'link_' . $fid;
233 $link_val = isset($data[$link_name]) ? trim($data[$link_name]) : '';
234 if ('' === $link_val) {
235 continue;
236 }
237 $out .= sprintf('<li><a href="%s">%s</a></li>', esc_url($link_val), $title_val);
238 }
239 $out .= '</ul>';
240 }
241 }
242 return $out;
243 }
244
245 /**
246 * Before Builder saves data, find all Widget modules and call
247 * WP_Widget::update() method on widget instance data.
248 *
249 * @return array
250 */
251 public static function before_builder_save(array $builder_data, $post_id) {
252 if (!empty($builder_data)) {
253 if (strpos(json_encode($builder_data), 'class_widget') !== false) {
254 foreach ($builder_data as $row_index => $row) {
255 if (!empty($row['cols'])) {
256 foreach ($row['cols'] as $col_index => $column) {
257 if (!empty($column['modules'])) {
258 foreach ($column['modules'] as $module_index => $module) {
259 if (!empty($module['cols'])) {
260 foreach ($module['cols'] as $sub_column_index => $sub_column) {
261 if (!empty($sub_column['modules'])) {
262 foreach ($sub_column['modules'] as $sub_module_index => $sub_module) {
263 if (isset($sub_module['mod_name']) && $sub_module['mod_name'] === 'widget') {
264 $builder_data[$row_index]['cols'][$col_index]['modules'][$module_index]['cols'][$sub_column_index]['modules'][$sub_module_index] = self::call_widget_update($sub_module);
265 }
266 }
267 }
268 }
269 }
270 if (isset($module['mod_name']) && $module['mod_name'] === 'widget') {
271 $builder_data[$row_index]['cols'][$col_index]['modules'][$module_index] = self::call_widget_update($module);
272 }
273 }
274 }
275 }
276 }
277 }
278 }
279 }
280 return $builder_data;
281 }
282
283 /**
284 * Takes a $module array, for "widget" modules will call WP_Widget::update() method
285 * on the widget instance data
286 *
287 * @return array
288 */
289 private static function call_widget_update($module) {
290 if (!empty($module['mod_settings']['instance_widget'])) {
291 global $wp_widget_factory;
292 $widget_class = $module['mod_settings']['class_widget'];
293 if (isset($wp_widget_factory->widgets[$widget_class])) {
294 set_error_handler(function($errno, $errstr, $errfile, $errline) {
295 return false;
296 });
297 try{
298 $instance = $wp_widget_factory->widgets[$widget_class]->update($module['mod_settings']['instance_widget'], array());
299 }
300 catch(Throwable $e){
301 }
302 restore_error_handler();
303
304 if (!isset($instance['widget-id']) && isset($module['mod_settings']['instance_widget']['widget-id'])) {
305 $instance['widget-id'] = $module['mod_settings']['instance_widget']['widget-id'];
306 }
307 // Search Widget
308 $key = 'tf_search_ajax';
309 if (isset($module['mod_settings']['instance_widget'][$key])) {
310 $instance[$key] = $module['mod_settings']['instance_widget'][$key];
311 }
312 $module['mod_settings']['instance_widget'] = $instance;
313 }
314 }
315 return $module;
316 }
317
318 public static function widget_gallery_lightbox($markup) {
319 return str_replace('<a', '<a class="themify_lightbox"', $markup);
320 }
321
322 public static function get_styling_image_fields() : array {
323 return [
324 'background_image' => '',
325 'b_i_w_t' => '.module .widgettitle'
326 ];
327 }
328
329 public static function get_translatable_text_fields( $module ) : array {
330 return [ 'mod_title_widget' ];
331 }
332 }
333
334 TB_Widget_Module::init();
335