Skip to content

Commit 3d50825

Browse files
Merge branch '3.4.0' of https://github.com/codeinwp/visualizer into issue-525
2 parents 1e2c7dd + 56db28a commit 3d50825

File tree

20 files changed

+266
-26
lines changed

20 files changed

+266
-26
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11

2+
### v3.3.2 - 2019-10-03
3+
**Changes:**
4+
* Add support for Dataset schema
5+
* Horizontal Axis formatting should apply to tooltips
6+
27
### v3.3.1 - 2019-09-28
38
**Changes:**
49
* Increase minimum requirement to PHP 5.6

classes/Visualizer/Gutenberg/Block.php

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public function enqueue_gutenberg_scripts() {
8787
if ( Visualizer_Module::is_pro() ) {
8888
$type = 'pro';
8989
if ( apply_filters( 'visualizer_is_business', false ) ) {
90-
$type = 'developer';
90+
$type = 'business';
9191
}
9292
}
9393

@@ -156,6 +156,9 @@ public function register_rest_endpoints() {
156156
'sanitize_callback' => 'absint',
157157
),
158158
),
159+
'permission_callback' => function () {
160+
return current_user_can( 'edit_posts' );
161+
},
159162
)
160163
);
161164

@@ -170,6 +173,9 @@ public function register_rest_endpoints() {
170173
'sanitize_callback' => 'esc_url_raw',
171174
),
172175
),
176+
'permission_callback' => function () {
177+
return current_user_can( 'edit_posts' );
178+
},
173179
)
174180
);
175181

@@ -184,6 +190,9 @@ public function register_rest_endpoints() {
184190
'sanitize_callback' => 'sanitize_text_field',
185191
),
186192
),
193+
'permission_callback' => function () {
194+
return current_user_can( 'edit_posts' );
195+
},
187196
)
188197
);
189198
}
@@ -249,15 +258,20 @@ public function update_chart_data( $data ) {
249258

250259
if ( $data['id'] && ! is_wp_error( $data['id'] ) ) {
251260

252-
update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_TYPE, $data['visualizer-chart-type'] );
253-
update_post_meta( $data['id'], Visualizer_Plugin::CF_SOURCE, $data['visualizer-source'] );
261+
$chart_type = sanitize_text_field( $data['visualizer-chart-type'] );
262+
$source_type = sanitize_text_field( $data['visualizer-source'] );
263+
264+
update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_TYPE, $chart_type );
265+
update_post_meta( $data['id'], Visualizer_Plugin::CF_SOURCE, $source_type );
254266
update_post_meta( $data['id'], Visualizer_Plugin::CF_DEFAULT_DATA, $data['visualizer-default-data'] );
255267
update_post_meta( $data['id'], Visualizer_Plugin::CF_SERIES, $data['visualizer-series'] );
256268
update_post_meta( $data['id'], Visualizer_Plugin::CF_SETTINGS, $data['visualizer-settings'] );
257269

258270
if ( $data['visualizer-chart-url'] && $data['visualizer-chart-schedule'] ) {
259-
update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_URL, $data['visualizer-chart-url'] );
260-
apply_filters( 'visualizer_pro_chart_schedule', $data['id'], $data['visualizer-chart-url'], $data['visualizer-chart-schedule'] );
271+
$chart_url = esc_url_raw( $data['visualizer-chart-url'] );
272+
$chart_schedule = intval( $data['visualizer-chart-schedule'] );
273+
update_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_URL, $chart_url );
274+
apply_filters( 'visualizer_pro_chart_schedule', $data['id'], $chart_url, $chart_schedule );
261275
} else {
262276
delete_post_meta( $data['id'], Visualizer_Plugin::CF_CHART_URL );
263277
apply_filters( 'visualizer_pro_remove_schedule', $data['id'] );
@@ -268,7 +282,8 @@ public function update_chart_data( $data ) {
268282
}
269283

270284
if ( $data['visualizer-chart-url'] ) {
271-
$content['source'] = $data['visualizer-chart-url'];
285+
$chart_url = esc_url_raw( $data['visualizer-chart-url'] );
286+
$content['source'] = $chart_url;
272287
$content['data'] = $this->format_chart_data( $data['visualizer-data'], $data['visualizer-series'] );
273288
} else {
274289
$content = $this->format_chart_data( $data['visualizer-data'], $data['visualizer-series'] );

classes/Visualizer/Module/Admin.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,9 @@ public function renderLibraryPage() {
784784
$settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
785785
}
786786

787-
unset( $settings['height'], $settings['width'], $settings['chartArea'] );
787+
if ( $settings ) {
788+
unset( $settings['height'], $settings['width'], $settings['chartArea'] );
789+
}
788790
$series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
789791
$data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( html_entity_decode( $chart->post_content ) ), $chart->ID, $type );
790792

classes/Visualizer/Module/Chart.php

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,8 @@ public function uploadData() {
934934
exit;
935935
}
936936

937+
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Uploading data for chart %d with POST = %s and GET = %s', $chart_id, print_r( $_POST, true ), print_r( $_GET, true ) ), 'debug', __FILE__, __LINE__ );
938+
937939
if ( ! isset( $_POST['vz-import-time'] ) ) {
938940
apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
939941
}
@@ -954,6 +956,9 @@ public function uploadData() {
954956
delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_ROOT );
955957
delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_PAGING );
956958

959+
// delete last error
960+
delete_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR );
961+
957962
$source = null;
958963
$render = new Visualizer_Render_Page_Update();
959964
if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
@@ -969,8 +974,13 @@ public function uploadData() {
969974
} elseif ( isset( $_POST['table_data'] ) && 'yes' === $_POST['table_data'] ) {
970975
$source = $this->handleTabularData();
971976
} else {
977+
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'CSV file with chart data was not uploaded for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
972978
$render->message = esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' );
979+
update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' ) );
973980
}
981+
982+
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Uploaded data for chart %d with source %s', $chart_id, print_r( $source, true ) ), 'debug', __FILE__, __LINE__ );
983+
974984
if ( $source ) {
975985
if ( $source->fetch() ) {
976986
$content = $source->getData();
@@ -981,6 +991,7 @@ public function uploadData() {
981991
// if we populate the data even if it is empty, the chart will show "Table has no columns".
982992
if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
983993
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Not populating chart data as source exists (%s) but data is empty!', $json['source'] ), 'warn', __FILE__, __LINE__ );
994+
update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, sprintf( 'Not populating chart data as source exists (%s) but data is empty!', $json['source'] ) );
984995
$populate = false;
985996
}
986997
}
@@ -992,6 +1003,8 @@ public function uploadData() {
9921003
update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
9931004
update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
9941005

1006+
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Updated post for chart %d', $chart_id ), 'debug', __FILE__, __LINE__ );
1007+
9951008
Visualizer_Module_Utility::set_defaults( $chart, null );
9961009

9971010
$settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
@@ -1001,11 +1014,16 @@ public function uploadData() {
10011014
$render->series = json_encode( $source->getSeries() );
10021015
$render->settings = json_encode( $settings );
10031016
} else {
1004-
$render->message = $source->get_error();
1005-
if ( empty( $render->message ) ) {
1006-
$render->message = esc_html__( 'CSV file is broken or invalid. Please try again.', 'visualizer' );
1017+
$error = $source->get_error();
1018+
if ( empty( $error ) ) {
1019+
$error = esc_html__( 'CSV file is broken or invalid. Please try again.', 'visualizer' );
10071020
}
1021+
$render->message = $error;
1022+
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( '%s for chart %d.', $error, $chart_id ), 'error', __FILE__, __LINE__ );
1023+
update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, $error );
10081024
}
1025+
} else {
1026+
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
10091027
}
10101028
$render->render();
10111029
if ( ! $can_die ) {
@@ -1114,7 +1132,10 @@ private function _handleDataPage() {
11141132
$render = new Visualizer_Render_Page_Data();
11151133
$render->chart = $this->_chart;
11161134
$render->type = $data['type'];
1117-
unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1135+
1136+
if ( $data && $data['settings'] ) {
1137+
unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1138+
}
11181139
wp_enqueue_style( 'visualizer-frame' );
11191140
wp_enqueue_script( 'visualizer-render' );
11201141
wp_localize_script(

classes/Visualizer/Module/Frontend.php

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,55 @@ public function renderChart( $atts ) {
344344
}
345345

346346
// return placeholder div
347-
return $actions_div . '<div id="' . $id . '"' . $class . '></div>';
347+
return $actions_div . '<div id="' . $id . '"' . $class . '></div>' . $this->addSchema( $chart->ID );
348+
}
349+
350+
/**
351+
* Adds the schema corresponding to the dataset.
352+
*
353+
* @since 3.3.2
354+
*
355+
* @access private
356+
*/
357+
private function addSchema( $id ) {
358+
$settings = get_post_meta( $id, Visualizer_Plugin::CF_SETTINGS, true );
359+
$title = '';
360+
if ( isset( $settings['title'] ) && ! empty( $settings['title'] ) ) {
361+
$title = $settings['title'];
362+
if ( is_array( $title ) ) {
363+
$title = $settings['title']['text'];
364+
}
365+
}
366+
$title = apply_filters( 'visualizer_schema_name', $title, $id );
367+
if ( empty( $title ) ) {
368+
return '';
369+
}
370+
371+
$desc = '';
372+
if ( isset( $settings['description'] ) && ! empty( $settings['description'] ) ) {
373+
$desc = $settings['description'];
374+
}
375+
$desc = apply_filters( 'visualizer_schema_description', $desc, $id );
376+
// descriptions below 50 chars are not allowed.
377+
if ( empty( $desc ) || strlen( $desc ) < 50 ) {
378+
return '';
379+
}
380+
381+
$schema = apply_filters(
382+
'visualizer_schema',
383+
'{
384+
"@context":"https://schema.org/",
385+
"@type":"Dataset",
386+
"name":"' . esc_html( $title ) . '",
387+
"description":"' . esc_html( $desc ) . '"
388+
}',
389+
$id
390+
);
391+
392+
if ( empty( $schema ) ) {
393+
return '';
394+
}
395+
396+
return '<script type="application/ld+json">' . $schema . '</script>';
348397
}
349398
}

classes/Visualizer/Module/Setup.php

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ public function __construct( Visualizer_Plugin $plugin ) {
5151
$this->_addAction( 'init', 'setupCustomPostTypes' );
5252
$this->_addAction( 'plugins_loaded', 'loadTextDomain' );
5353
$this->_addFilter( 'visualizer_logger_data', 'getLoggerData' );
54-
$this->_addFilter( 'visualizer_get_chart_counts', 'getChartCountsByTypeAndMeta' );
54+
$this->_addFilter( 'visualizer_get_chart_counts', 'getUsage', 10, 2 );
5555

56+
// only for testing
57+
// $this->_addAction( 'admin_init', 'getUsage' );
5658
}
5759
/**
5860
* Fetches the SDK logger data.
@@ -62,34 +64,80 @@ public function __construct( Visualizer_Plugin $plugin ) {
6264
* @access public
6365
*/
6466
public function getLoggerData( $data ) {
65-
return $this->getChartCountsByTypeAndMeta();
67+
return $this->getUsage( $data );
6668
}
6769

6870
/**
69-
* Fetches the types of charts created and their counts.
71+
* Fetches the usage of charts.
7072
*
73+
* @param array $data The default data that needs to be sent.
7174
* @param array $meta_keys An array of name vs. meta keys - to return how many charts have these keys.
72-
* @access private
75+
*
76+
* @access public
7377
*/
74-
public function getChartCountsByTypeAndMeta( $meta_keys = array() ) {
75-
$charts = array();
76-
$charts['chart_types'] = array();
77-
// the initial query arguments to fetch charts
78+
public function getUsage( $data, $meta_keys = array() ) {
79+
$charts = array( 'types' => array(), 'sources' => array(), 'library' => array(), 'permissions' => 0, 'manual_config' => 0, 'scheduled' => 0 );
7880
$query_args = array(
7981
'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
8082
'posts_per_page' => 300,
83+
'post_status' => 'publish',
8184
'fields' => 'ids',
8285
'no_rows_found' => false,
8386
'update_post_meta_cache' => false,
8487
'update_post_term_cache' => false,
88+
);
8589

90+
// default permissions.
91+
$default_perms = array(
92+
'read' => 'all',
93+
'read-specific' => null,
94+
'edit' => 'roles',
95+
'edit-specific' => array( 'administrator' ),
8696
);
8797

98+
// collect all schedules chart ids.
99+
$scheduled = array_merge(
100+
array_keys( get_option( Visualizer_Plugin::CF_CHART_SCHEDULE, array() ) ),
101+
array_keys( get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() ) )
102+
);
88103
$query = new WP_Query( $query_args );
89104
while ( $query->have_posts() ) {
90105
$chart_id = $query->next_post();
91106
$type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
92-
$charts['chart_types'][ $type ] = isset( $charts['chart_types'][ $type ] ) ? $charts['chart_types'][ $type ] + 1 : 1;
107+
$charts['types'][ $type ] = isset( $charts['types'][ $type ] ) ? $charts['types'][ $type ] + 1 : 1;
108+
$source = get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true );
109+
$charts['sources'][ $source ] = isset( $charts['sources'][ $source ] ) ? $charts['sources'][ $source ] + 1 : 1;
110+
$lib = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, true );
111+
$charts['library'][ $lib ] = isset( $charts['library'][ $lib ] ) ? $charts['library'][ $lib ] + 1 : 1;
112+
$settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
113+
if ( array_key_exists( 'manual', $settings ) && ! empty( $settings['manual'] ) ) {
114+
$charts['manual_config'] = $charts['manual_config'] + 1;
115+
}
116+
117+
// phpcs:ignore WordPress.PHP.StrictInArray.FoundNonStrictFalse
118+
if ( in_array( $chart_id, $scheduled, false ) ) {
119+
$charts['scheduled'] = $charts['scheduled'] + 1;
120+
}
121+
122+
if ( Visualizer_Module::is_pro() ) {
123+
$permissions = get_post_meta( $chart_id, Visualizer_PRO::CF_PERMISSIONS, true );
124+
if ( empty( $permissions ) ) {
125+
continue;
126+
}
127+
$permissions = $permissions['permissions'];
128+
$customized = false;
129+
foreach ( $default_perms as $key => $val ) {
130+
if ( ! is_array( $val ) && ! is_null( $val ) && isset( $permissions[ $key ] ) && $permissions[ $key ] !== $val ) {
131+
$customized = true;
132+
} elseif ( is_array( $val ) && ! is_null( $val ) && isset( $permissions[ $key ] ) && count( $permissions[ $key ] ) !== count( $val ) ) {
133+
$customized = true;
134+
}
135+
}
136+
if ( $customized ) {
137+
$charts['permissions'] = $charts['permissions'] + 1;
138+
}
139+
}
140+
93141
if ( ! empty( $meta_keys ) ) {
94142
foreach ( $meta_keys as $name => $key ) {
95143
$data = get_post_meta( $chart_id, $key, true );
@@ -101,6 +149,7 @@ public function getChartCountsByTypeAndMeta( $meta_keys = array() ) {
101149
}
102150
}
103151
}
152+
104153
return $charts;
105154
}
106155

@@ -249,6 +298,8 @@ public function refresh_db_for_chart( $chart, $chart_id, $force = false ) {
249298
);
250299

251300
$chart = get_post( $chart_id );
301+
} else {
302+
update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, sprintf( 'Error while updating chart: %s', $error ) );
252303
}
253304

254305
return $chart;

classes/Visualizer/Plugin.php

Lines changed: 2 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.3.1';
31+
const VERSION = '3.3.2';
3232

3333
// custom post types
3434
const CPT_VISUALIZER = 'visualizer';
@@ -40,6 +40,7 @@ class Visualizer_Plugin {
4040
const CF_DEFAULT_DATA = 'visualizer-default-data';
4141
const CF_SETTINGS = 'visualizer-settings';
4242
const CF_CHART_LIBRARY = 'visualizer-chart-library';
43+
const CF_ERROR = 'visualizer-error';
4344

4445
const CF_SOURCE_FILTER = 'visualizer-source-filter';
4546
const CF_FILTER_CONFIG = 'visualizer-filter-config';

classes/Visualizer/Render/Library.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ private function _renderChartBox( $placeholder_id, $chart_id ) {
220220
),
221221
admin_url( 'admin-ajax.php' )
222222
);
223+
224+
$chart_status = array( 'date' => get_the_modified_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $chart_id ), 'error' => get_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, true ), 'icon' => 'dashicons-yes-alt', 'title' => '' );
225+
if ( ! empty( $chart_status['error'] ) ) {
226+
$chart_status['icon'] = 'error dashicons-dismiss';
227+
$chart_status['title'] = __( 'Click to view the error', 'visualizer' );
228+
}
229+
223230
echo '<div class="visualizer-chart"><div class="visualizer-chart-title">', esc_html( $title ), '</div>';
224231
echo '<div id="', $placeholder_id, '" class="visualizer-chart-canvas">';
225232
echo '<img src="', VISUALIZER_ABSURL, 'images/ajax-loader.gif" class="loader">';
@@ -232,6 +239,7 @@ private function _renderChartBox( $placeholder_id, $chart_id ) {
232239
echo '<span class="visualizer-chart-shortcode" title="', esc_attr__( 'Click to select', 'visualizer' ), '">';
233240
echo '&nbsp;[visualizer id=&quot;', $chart_id, '&quot;]&nbsp;';
234241
echo '</span>';
242+
echo '<hr><div class="visualizer-chart-status"><span class="visualizer-date" title="' . __( 'Last Updated', 'visualizer' ) . '">' . $chart_status['date'] . '</span><span class="visualizer-error"><i class="dashicons ' . $chart_status['icon'] . '" data-viz-error="' . esc_attr( str_replace( '"', "'", $chart_status['error'] ) ) . '" title="' . esc_attr( $chart_status['title'] ) . '"></i></span></div>';
235243
echo '</div>';
236244
echo '</div>';
237245
}

0 commit comments

Comments
 (0)