PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.22
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.22
5.5.84 5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 5.5.41 5.5.42 All 160 releases
wp-data-access / WPDataAccess / Dashboard / WPDA_Widget.php

WPDA_Widget.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.22, at WPDataAccess/Dashboard/WPDA_Widget.php

373 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // phpcs:ignore Standard.Category.SniffName.ErrorCode
4 namespace WPDataAccess\Dashboard;
5
6 use WPDataAccess\WPDA;
7 /**
8 * Abstract widget base class
9 */
10 abstract class WPDA_Widget {
11 /**
12 * Nonce seed
13 */
14 const WIDGET_ADD = 'WPDA_WIDGET_ADD';
15
16 /**
17 * Nonce seed
18 */
19 const WIDGET_REFRESH = 'WPDA_WIDGET_REFRESH';
20
21 /**
22 * Widget sequence number
23 *
24 * @var int
25 */
26 protected static $widget_sequence_nr = 0;
27
28 /**
29 * Active column number
30 *
31 * @var int|mixed
32 */
33 protected $column = 1;
34
35 /**
36 * Share indicator
37 *
38 * @var bool
39 */
40 protected $can_share = false;
41
42 /**
43 * Layout indicator
44 *
45 * @var bool
46 */
47 protected $has_layout = false;
48
49 /**
50 * Settings indicator
51 *
52 * @var bool
53 */
54 protected $has_setting = false;
55
56 /**
57 * Refresh indicator
58 *
59 * @var bool
60 */
61 protected $can_refresh = false;
62
63 /**
64 * Widget name
65 *
66 * @var mixed|string
67 */
68 protected $name = 'No name';
69
70 /**
71 * Widget title
72 *
73 * @var mixed|string
74 */
75 protected $title = 'No title';
76
77 /**
78 * Widget content
79 *
80 * @var mixed|string
81 */
82 protected $content = 'Loading...';
83
84 /**
85 * Nonce
86 *
87 * @var null
88 */
89 protected $wp_nonce = null;
90
91 /**
92 * Current widget id
93 *
94 * @var int|mixed
95 */
96 protected $widget_id = 0;
97
98 /**
99 * Widget positioning
100 *
101 * @var string
102 */
103 protected $position = 'append';
104
105 /**
106 * Current state
107 *
108 * @var mixed|string|null
109 */
110 protected $state = null;
111
112 /**
113 * Lock indicator
114 *
115 * @var bool
116 */
117 protected $is_locked = false;
118
119 /**
120 * Widget shares
121 *
122 * @var array
123 */
124 protected $share = array(
125 'post' => 'true',
126 'page' => 'true',
127 'embed' => 'block',
128 'allow' => array(),
129 );
130
131 /**
132 * Constructor
133 *
134 * @param array $args Constructor arguments.
135 */
136 public function __construct( $args = array() ) {
137 wp_enqueue_script( 'jquery-ui-widget' );
138 if ( isset( $args['name'] ) ) {
139 $this->name = $args['name'];
140 }
141 if ( isset( $args['column'] ) ) {
142 $this->column = $args['column'];
143 }
144 if ( isset( $args['title'] ) ) {
145 $this->title = $args['title'];
146 }
147 if ( isset( $args['content'] ) ) {
148 $this->content = $args['content'];
149 }
150 if ( isset( $args['position'] ) && 'prepend' === $args['position'] ) {
151 $this->position = 'prepend';
152 }
153 if ( isset( $args['widget_id'] ) ) {
154 $this->widget_id = $args['widget_id'];
155 // Used to add widgets via ajax.
156 } else {
157 $this->widget_id = ++self::$widget_sequence_nr;
158 // Used to add widgets on page load.
159 }
160 if ( isset( $args['is_locked'] ) ) {
161 $this->is_locked = true === $args['is_locked'] || 'true' === $args['is_locked'];
162 }
163 if ( isset( $args['share'] ) && isset(
164 $args['share']['roles'],
165 $args['share']['users'],
166 $args['share']['post'],
167 $args['share']['page'],
168 $args['share']['embed'],
169 $args['share']['allow']
170 ) ) {
171 $this->share = array(
172 'roles' => $args['share']['roles'],
173 'users' => $args['share']['users'],
174 'post' => $args['share']['post'],
175 'page' => $args['share']['page'],
176 'embed' => $args['share']['embed'],
177 'allow' => $args['share']['allow'],
178 );
179 }
180 $this->state = ( isset( $args['state'] ) ? $args['state'] : 'new' );
181 $this->wp_nonce = wp_create_nonce( static::WIDGET_REFRESH . WPDA::get_current_user_login() );
182 }
183
184 /**
185 * Construct widget container
186 *
187 * @return false|string
188 */
189 protected function container() {
190 ob_start();
191 ?>
192 <script type="application/javascript" class="wpda-widget-<?php
193 echo esc_attr( $this->widget_id );
194 ?>">
195 jQuery(function() {
196 var widget = `<?php
197 echo $this->html();
198 // phpcs:ignore WordPress.Security.EscapeOutput
199 ?>`;
200
201 jQuery("#wpda-dashboard-column-<?php
202 echo esc_attr( $this->column );
203 ?>").<?php
204 echo esc_attr( $this->position );
205 ?>(widget);
206 jQuery("#wpda-widget-<?php
207 echo esc_attr( $this->widget_id );
208 ?>").data("name", "<?php
209 echo esc_attr( $this->name );
210 ?>" );
211
212 jQuery("#wpda-widget-<?php
213 echo esc_attr( $this->widget_id );
214 ?> .wpda-widget-close").on("click", function() {
215 removePanelFromDashboard(jQuery(this).closest('.wpda-widget'));
216 });
217 });
218 </script>
219 <?php
220 $this->js();
221 return ob_get_clean();
222 }
223
224 /**
225 * Construct widget html
226 *
227 * @return string
228 */
229 protected function html() {
230 $share = '';
231 $layout = '';
232 $setting = '';
233 $refresh = ( $this->can_refresh ? "<i class='fas fa-sync-alt wpda-widget-refresh wpda_tooltip' title='Refresh'></i> &nbsp;" : '' );
234 $close = ( !$this->is_locked ? '<i class="fas fa-window-close wpda-widget-close wpda_tooltip" title="Close"></i>' : '' );
235 $widget = <<<EOF
236 <div id="wpda-widget-{$this->widget_id}" data-id="{$this->widget_id}" class="wpda-widget ui-widget">
237 <div class="wpda-widget-content">
238 <div class="ui-widget-header">
239 <span>{$this->name}</span>
240 <span class="icons">
241 \t\t\t\t\t\t\t\t{$share}
242 \t\t\t\t\t\t\t\t{$layout}
243 \t\t\t\t\t\t\t\t{$setting}
244 \t\t\t\t\t\t\t\t{$refresh}
245 \t\t\t\t\t\t\t\t{$close}
246 \t\t\t\t\t\t\t</span>
247 </div>
248 <div class="ui-widget-content">
249 {$this->content}
250 </div>
251 </div>
252 </div>
253 EOF;
254 return $widget;
255 }
256
257 /**
258 * Cross origin check
259 *
260 * @param WPDA_Widget $widget Widget.
261 * @return bool
262 */
263 protected static function check_cors( $widget ) {
264 if ( isset( $_POST['wpda_caller'] ) && 'embedded' === $_POST['wpda_caller'] ) {
265 // phpcs:ignore WordPress.Security.NonceVerification
266 $share = ( isset( $widget['widgetShare'] ) ? $widget['widgetShare'] : null );
267 if ( 'block' === $share['embed'] ) {
268 WPDA::sent_header( 'application/json', '*' );
269 echo static::msg( 'ERROR', 'No access' );
270 // phpcs:ignore WordPress.Security.EscapeOutput
271 wp_die();
272 } else {
273 if ( '*' === $share['embed'] ) {
274 WPDA::sent_header( 'application/json', '*' );
275 return true;
276 } else {
277 // Access is already checked with sonce token.
278 WPDA::sent_header( 'application/json', '*' );
279 return true;
280 }
281 }
282 }
283 return false;
284 }
285
286 /**
287 * Abstract method forcing each subclass to add its own specific javascript code
288 *
289 * @return mixed
290 */
291 protected abstract function js();
292
293 // Method to add custom JavaScript code.
294 /**
295 * Add widget to dashboard
296 *
297 * @return void
298 */
299 public function add() {
300 echo $this->container();
301 // phpcs:ignore WordPress.Security.EscapeOutput
302 ?>
303 <script type="application/javascript">
304 jQuery(function() {
305 increaseWidgetSequenceNr();
306 });
307 </script>
308 <?php
309 }
310
311 /**
312 * Abstract widget method forcing each subclass to implement its own specific widget functionality
313 *
314 * @return mixed
315 */
316 public static abstract function widget();
317
318 /**
319 * Construct widget via ajax (general part used for each widget)
320 *
321 * @return void
322 */
323 public static function ajax_widget() {
324 $wp_nonce = ( isset( $_POST['wp_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wp_nonce'] ) ) : '' );
325 if ( !wp_verify_nonce( $wp_nonce, static::WIDGET_ADD . WPDA::get_current_user_login() ) ) {
326 WPDA::sent_header( 'application/json' );
327 echo static::msg( 'ERROR', 'Token expired, please refresh page' );
328 // phpcs:ignore WordPress.Security.EscapeOutput
329 wp_die();
330 }
331 static::widget();
332 }
333
334 /**
335 * Abstract refresh method forcing each subclass to implement its own specific refresh functionality
336 *
337 * @return mixed
338 */
339 public static abstract function refresh();
340
341 /**
342 * Refresh widget via ajax (general part used for each widget)
343 *
344 * @return void
345 */
346 public static function ajax_refresh() {
347 $wp_nonce = ( isset( $_POST['wp_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wp_nonce'] ) ) : '' );
348 if ( !wp_verify_nonce( $wp_nonce, static::WIDGET_REFRESH . WPDA::get_current_user_login() ) ) {
349 WPDA::sent_header( 'application/json' );
350 echo static::msg( 'ERROR', 'Token expired, please refresh page' );
351 // phpcs:ignore WordPress.Security.EscapeOutput
352 wp_die();
353 }
354 static::refresh();
355 }
356
357 /**
358 * Construct JSON response message
359 *
360 * @param string $status Response status.
361 * @param string $msg Response message.
362 * @return mixed
363 */
364 protected static function msg( $status, $msg ) {
365 $error = array(
366 'status' => $status,
367 'msg' => $msg,
368 );
369 return wp_json_encode( $error );
370 }
371
372 }
373