Skip to content

Commit 35d5f25

Browse files
Merge pull request #249 from Codeinwp/development
Added revision support for the chart post type Added both % and Value to the Pie Slice Use the blog locale for Visualizer's options Fixed issue with data being fetched from the remote source every single time the chart was shown Fixed issue with scheduled charts not being updated if one of the scheduled charts is deleted
2 parents 0684c08 + 73428b1 commit 35d5f25

File tree

18 files changed

+582
-23
lines changed

18 files changed

+582
-23
lines changed

classes/Visualizer/Module.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ public function __construct( Visualizer_Plugin $plugin ) {
6363

6464
$this->_wpdb = $wpdb;
6565
$this->_plugin = $plugin;
66+
67+
$this->_addFilter( Visualizer_Plugin::FILTER_UNDO_REVISIONS, 'undoRevisions', 10, 2 );
68+
$this->_addFilter( Visualizer_Plugin::FILTER_HANDLE_REVISIONS, 'handleExistingRevisions', 10, 2 );
69+
6670
}
6771

6872
/**
@@ -323,6 +327,57 @@ private function _getHTML( $rows ) {
323327
);
324328
}
325329

330+
/**
331+
* Undo revisions for the chart, and if necessary, restore the earliest version.
332+
*
333+
* @return bool If any revisions were found.
334+
*/
335+
public final function undoRevisions( $chart_id, $restore = false ) {
336+
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'undoRevisions for %d with%s restore', $chart_id, ( $restore ? '' : 'out' ) ), 'debug', __FILE__, __LINE__ );
337+
338+
$revisions = wp_get_post_revisions( $chart_id, array( 'order' => 'ASC' ) );
339+
if ( count( $revisions ) > 1 ) {
340+
$revision_ids = array_keys( $revisions );
341+
342+
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'found %d revisions = %s', count( $revisions ), print_r( $revision_ids, true ) ), 'debug', __FILE__, __LINE__ );
343+
344+
// when we restore, a new revision is likely to be created. so, let's disable revisions for the time being.
345+
add_filter( 'wp_revisions_to_keep', '__return_false' );
346+
347+
if ( $restore ) {
348+
// restore to the oldest one i.e. the first one.
349+
wp_restore_post_revision( array_shift( $revision_ids ) );
350+
}
351+
352+
// delete all revisions.
353+
foreach ( $revision_ids as $id ) {
354+
wp_delete_post_revision( $id );
355+
}
356+
357+
return true;
358+
}
359+
return false;
360+
}
361+
362+
/**
363+
* If existing revisions exist for the chart, restore the earliest version and then create a new revision to initiate editing.
364+
*/
365+
public final function handleExistingRevisions( $chart_id, $chart ) {
366+
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'handleExistingRevisions for %d', $chart_id ), 'debug', __FILE__, __LINE__ );
367+
368+
// undo revisions.
369+
$revisions_found = $this->undoRevisions( $chart_id, true );
370+
371+
// create revision for the edit action.
372+
wp_save_post_revision( $chart_id );
373+
374+
if ( $revisions_found ) {
375+
// fetch chart data again in case it was updated by an earlier revision.
376+
$chart = get_post( $chart_id );
377+
}
378+
return $chart;
379+
}
380+
326381
/**
327382
* Returns the language of the locale.
328383
*
@@ -339,4 +394,5 @@ protected function get_language() {
339394
}
340395
return reset( $array );
341396
}
397+
342398
}

classes/Visualizer/Module/Admin.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,71 @@ public function __construct( Visualizer_Plugin $plugin ) {
6262
$this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
6363
$this->_addFilter( 'visualizer_feedback_review_trigger', 'feedbackReviewTrigger' );
6464

65+
// revision support.
66+
$this->_addFilter( 'wp_revisions_to_keep', 'limitRevisions', null, 10, 2 );
67+
$this->_addAction( '_wp_put_post_revision', 'addRevision', null, 10, 1 );
68+
$this->_addAction( 'wp_restore_post_revision', 'restoreRevision', null, 10, 2 );
69+
6570
$this->_addAction( 'admin_init', 'init' );
6671
}
6772

73+
/**
74+
* No limits on revisions.
75+
*/
76+
public function limitRevisions( $num, $post ) {
77+
if ( Visualizer_Plugin::CPT_VISUALIZER === $post->post_type ) {
78+
return -1;
79+
}
80+
return $num;
81+
}
82+
83+
/**
84+
* Add a revision.
85+
*/
86+
public function addRevision( $revision_id ) {
87+
$parent_id = wp_is_post_revision( $revision_id );
88+
if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $parent_id ) ) {
89+
// add the meta data to this revision.
90+
$meta = get_post_meta( $parent_id, '', true );
91+
92+
if ( $meta ) {
93+
foreach ( $meta as $key => $value ) {
94+
if ( 0 === strpos( $key, 'visualizer' ) ) {
95+
add_metadata( 'post', $revision_id, $key, maybe_unserialize( $value[0] ) );
96+
}
97+
}
98+
}
99+
}
100+
}
101+
102+
/**
103+
* Restore a revision.
104+
*/
105+
public function restoreRevision( $post_id, $revision_id ) {
106+
if ( Visualizer_Plugin::CPT_VISUALIZER === get_post_type( $post_id ) ) {
107+
// get the meta information from the revision.
108+
$meta = get_metadata( 'post', $revision_id, '', true );
109+
110+
// delete all meta information from the post before adding.
111+
$post_meta = get_post_meta( $post_id, '', true );
112+
if ( $post_meta ) {
113+
foreach ( $meta as $key => $value ) {
114+
if ( 0 === strpos( $key, 'visualizer' ) ) {
115+
delete_post_meta( $post_id, $key );
116+
}
117+
}
118+
}
119+
120+
if ( $meta ) {
121+
foreach ( $meta as $key => $value ) {
122+
if ( 0 === strpos( $key, 'visualizer' ) ) {
123+
add_post_meta( $post_id, $key, maybe_unserialize( $value[0] ) );
124+
}
125+
}
126+
}
127+
}
128+
}
129+
68130
/**
69131
* Admin init.
70132
*
@@ -441,6 +503,10 @@ public function renderLibraryPage() {
441503
$query = new WP_Query( $query_args );
442504
while ( $query->have_posts() ) {
443505
$chart = $query->next_post();
506+
507+
// if the user has updated a chart and instead of saving it, has closed the modal. If the user refreshes, they should get the original chart.
508+
$chart = $this->handleExistingRevisions( $chart->ID, $chart );
509+
444510
// fetch and update settings
445511
$settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
446512
unset( $settings['height'], $settings['width'] );
@@ -469,6 +535,7 @@ public function renderLibraryPage() {
469535
array(
470536
'action' => Visualizer_Plugin::ACTION_CREATE_CHART,
471537
'library' => 'yes',
538+
'type' => isset( $_GET['type'] ) ? $_GET['type'] : '',
472539
), $ajaxurl
473540
),
474541
'edit' => add_query_arg(

classes/Visualizer/Module/Chart.php

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ public function __construct( Visualizer_Plugin $plugin ) {
5757
$this->_addAjaxAction( Visualizer_Plugin::ACTION_EDIT_CHART, 'renderChartPages' );
5858
$this->_addAjaxAction( Visualizer_Plugin::ACTION_UPLOAD_DATA, 'uploadData' );
5959
$this->_addAjaxAction( Visualizer_Plugin::ACTION_CLONE_CHART, 'cloneChart' );
60-
// Added by Ash/Upwork
6160
$this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' );
62-
// Added by Ash/Upwork
6361
}
6462

6563
/**
@@ -211,7 +209,7 @@ public function renderChartPages() {
211209
// check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
212210
$chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
213211
if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
214-
$default_type = 'line';
212+
$default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
215213
$source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
216214
$source->fetch();
217215
$chart_id = wp_insert_post(
@@ -269,10 +267,21 @@ public function renderChartPages() {
269267
$tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer';
270268

271269
// skip chart type pages only for existing charts.
272-
if ( VISUALIZER_SKIP_CHART_TYPE_PAGE && 'auto-draft' !== $this->_chart->post_status ) {
270+
if ( VISUALIZER_SKIP_CHART_TYPE_PAGE && 'auto-draft' !== $this->_chart->post_status && ( ! empty( $_GET['tab'] ) && 'visualizer' === $_GET['tab'] ) ) {
273271
$tab = 'settings';
274272
}
275273

274+
if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) {
275+
// if the cancel button is clicked.
276+
$this->undoRevisions( $chart_id, true );
277+
} elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
278+
// if the save button is clicked.
279+
$this->undoRevisions( $chart_id, false );
280+
} else {
281+
// if the edit button is clicked.
282+
$this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
283+
}
284+
276285
switch ( $tab ) {
277286
case 'settings':
278287
$this->_handleDataAndSettingsPage();
@@ -357,6 +366,9 @@ private function _handleDataAndSettingsPage() {
357366
$render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
358367
? esc_html__( 'Save Chart', 'visualizer' )
359368
: esc_html__( 'Create Chart', 'visualizer' );
369+
if ( filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART ) {
370+
$render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
371+
}
360372
} else {
361373
$render->button = esc_attr__( 'Insert Chart', 'visualizer' );
362374
}
@@ -426,18 +438,30 @@ public function renderFlattrScript() {
426438
* @access public
427439
*/
428440
public function uploadData() {
441+
// if this is being called internally from pro and VISUALIZER_DO_NOT_DIE is set.
442+
// otherwise, assume this is a normal web request.
443+
$can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE );
444+
429445
// validate nonce
430-
// do not use filter_input as it does not work for phpunit test cases, use filter_var instead
431446
if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) {
447+
if ( ! $can_die ) {
448+
return;
449+
}
432450
status_header( 403 );
433451
exit;
434452
}
453+
435454
// check chart, if chart exists
455+
// do not use filter_input as it does not work for phpunit test cases, use filter_var instead
436456
$chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
437457
if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
458+
if ( ! $can_die ) {
459+
return;
460+
}
438461
status_header( 400 );
439462
exit;
440463
}
464+
441465
if ( ! isset( $_POST['vz-import-time'] ) ) {
442466
apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
443467
}
@@ -456,10 +480,8 @@ public function uploadData() {
456480
}
457481
} elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
458482
$source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
459-
// Added by Ash/Upwork
460483
} elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
461484
$source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' );
462-
// Added by Ash/Upwork
463485
} else {
464486
$render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
465487
}
@@ -477,9 +499,10 @@ public function uploadData() {
477499
}
478500
}
479501
$render->render();
480-
if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
481-
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
502+
if ( ! $can_die ) {
503+
return;
482504
}
505+
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
483506
}
484507

485508
/**
@@ -599,4 +622,5 @@ private function _handleDataPage() {
599622
$this->_addAction( 'admin_head', 'renderFlattrScript' );
600623
wp_iframe( array( $render, 'render' ) );
601624
}
625+
602626
}

classes/Visualizer/Module/Frontend.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ public function renderChart( $atts ) {
197197
return '';
198198
}
199199

200+
// in case revisions exist.
201+
if ( true === ( $revisions = $this->undoRevisions( $chart->ID, true ) ) ) {
202+
$chart = get_post( $chart->ID );
203+
}
204+
200205
$id = 'visualizer-' . $atts['id'];
201206
$defaultClass = 'visualizer-front';
202207
$class = apply_filters( Visualizer_Plugin::FILTER_CHART_WRAPPER_CLASS, $atts['class'], $atts['id'] );
@@ -230,9 +235,12 @@ public function renderChart( $atts ) {
230235

231236
$id = $id . '-' . rand();
232237
$arguments = array( '', $id, $settings );
238+
$css = '';
233239
apply_filters_ref_array( 'visualizer_pro_inline_css', array( &$arguments ) );
234-
$css = $arguments[0];
235-
$settings = $arguments[2];
240+
if ( ! empty( $arguments ) ) {
241+
$css = $arguments[0];
242+
$settings = $arguments[2];
243+
}
236244

237245
// add chart to the array
238246
$this->_charts[ $id ] = array(

classes/Visualizer/Module/Setup.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ public function setupCustomPostTypes() {
110110
Visualizer_Plugin::CPT_VISUALIZER, array(
111111
'label' => 'Visualizer Charts',
112112
'public' => false,
113+
'supports' => array( 'revisions' ),
113114
)
114115
);
115116
}

classes/Visualizer/Plugin.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
class Visualizer_Plugin {
2929

3030
const NAME = 'visualizer';
31-
const VERSION = '3.0.7';
31+
const VERSION = '3.0.8';
3232

3333
// custom post types
3434
const CPT_VISUALIZER = 'visualizer';
@@ -62,6 +62,8 @@ class Visualizer_Plugin {
6262
const FILTER_GET_CHART_SERIES = 'visualizer-get-chart-series';
6363
const FILTER_GET_CHART_DATA = 'visualizer-get-chart-data';
6464
const FILTER_GET_CHART_SETTINGS = 'visualizer-get-chart-settings';
65+
const FILTER_UNDO_REVISIONS = 'visualizer-undo-revisions';
66+
const FILTER_HANDLE_REVISIONS = 'visualizer-handle-revisions';
6567

6668
const CF_CHART_URL = 'visualizer-chart-url';
6769
const CF_CHART_SCHEDULE = 'visualizer-chart-schedule';
@@ -97,6 +99,9 @@ class Visualizer_Plugin {
9799
* @access private
98100
*/
99101
private function __construct() {
102+
if ( VISUALIZER_DEBUG ) {
103+
add_action( 'themeisle_log_event', array( $this, 'themeisle_log_event_debug' ), 10, 5 );
104+
}
100105
}
101106

102107
/**
@@ -184,4 +189,14 @@ public function setModule( $class ) {
184189
private function __clone() {
185190
}
186191

192+
/**
193+
* For local testing, overrides the 'themeisle_log_event' hook and redirects to error.log.
194+
*/
195+
final function themeisle_log_event_debug( $name, $message, $type, $file, $line ) {
196+
if ( Visualizer_Plugin::NAME !== $name ) {
197+
return;
198+
}
199+
error_log( sprintf( '%s (%s): %s in %s:%s', $name, $type, $message, $file, $line ) );
200+
}
201+
187202
}

classes/Visualizer/Render/Page/Data.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ class="dashicons dashicons-lock"></span></h2>
254254
<form id="settings-form" action="<?php echo add_query_arg( 'nonce', wp_create_nonce() ); ?>"
255255
method="post">
256256
<?php echo $this->sidebar; ?>
257+
<input type="hidden" name="save" value="1">
258+
</form>
259+
<form id="cancel-form" action="<?php echo add_query_arg( 'nonce', wp_create_nonce() ); ?>" method="post">
260+
<input type="hidden" name="cancel" value="1">
257261
</form>
258262
</ul>
259263
</li>
@@ -310,6 +314,10 @@ private function getPermissionsLink( $id ) {
310314
* @access private
311315
*/
312316
private function permissionsSidebar() {
317+
// ignore for unit tests because Travis throws the error "Indirect modification of overloaded property Visualizer_Render_Page_Data::$permissions has no effect".
318+
if ( defined( 'WP_TESTS_DOMAIN' ) ) {
319+
return;
320+
}
313321
Visualizer_Render_Sidebar::_renderGroupStart(
314322
esc_html__( 'Who can see this chart?', 'visualizer' ) . '<span
315323
class="dashicons dashicons-lock"></span>', '', apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'chart-permissions' )
@@ -415,6 +423,9 @@ protected function _renderToolbar() {
415423
echo '</div>';
416424
}
417425
echo '<input type="submit" id="settings-button" class="button button-primary button-large push-right" value="', $this->button, '">';
426+
if ( isset( $this->cancel_button ) ) {
427+
echo '<input type="submit" id="cancel-button" class="button button-secondary button-large push-right" value="', $this->cancel_button, '">';
428+
}
418429
}
419430

420431
}

classes/Visualizer/Render/Sidebar/Type/Pie.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ protected function _renderPieSettings() {
102102
'percentage' => esc_html__( 'The percentage of the slice size out of the total', 'visualizer' ),
103103
'value' => esc_html__( 'The quantitative value of the slice', 'visualizer' ),
104104
'label' => esc_html__( 'The name of the slice', 'visualizer' ),
105+
// the below option is undocumented.
106+
'value-and-percentage' => esc_html__( 'The quantitative value and percentage of the slice', 'visualizer' ),
105107
'none' => esc_html__( 'No text is displayed', 'visualizer' ),
106108
),
107109
esc_html__( 'The content of the text displayed on the slice.', 'visualizer' )

0 commit comments

Comments
 (0)