PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.1.3
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.1.3
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | classes/Visualizer/Module/Chart.php +115 -817 3.10.143.1.3 View file →
@@ -60,249 +60,12 @@
60 60 $this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' );
61 61
62 62 $this->_addAjaxAction( Visualizer_Plugin::ACTION_FETCH_DB_DATA, 'getQueryData' );
63 63 $this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_DB_QUERY, 'saveQuery' );
64 -
65 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_GET_ROOTS, 'getJsonRoots' );
66 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_GET_DATA, 'getJsonData' );
67 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_SET_DATA, 'setJsonData' );
68 - $this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE, 'setJsonSchedule' );
69 -
70 64 $this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY, 'saveFilter' );
71 -
72 - $this->_addFilter( 'visualizer_get_sidebar', 'getSidebar', 10, 2 );
73 -
74 65 }
75 66
76 67 /**
77 - * Generates the HTML of the sidebar for the chart.
78 - *
79 - * @since ?
80 - *
81 - * @access public
82 - */
83 - public function getSidebar( $sidebar, $chart_id ) {
84 - $chart = get_post( $chart_id );
85 - $data = $this->_getChartArray( $chart );
86 - $sidebar = '';
87 - $sidebar_class = $this->load_chart_class_name( $chart_id );
88 - if ( class_exists( $sidebar_class, true ) ) {
89 - $sidebar = new $sidebar_class( $data['settings'] );
90 - $sidebar->__series = $data['series'];
91 - $sidebar->__data = $data['data'];
92 - } else {
93 - $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
94 - if ( $sidebar !== '' ) {
95 - $sidebar->__series = $data['series'];
96 - $sidebar->__data = $data['data'];
97 - }
98 - }
99 - return str_replace( "'", '"', $sidebar->__toString() );
100 - }
101 -
102 - /**
103 - * Sets the schedule for how JSON-endpoint charts should be updated.
104 - *
105 - * @since ?
106 - *
107 - * @access public
108 - */
109 - public function setJsonSchedule() {
110 - check_ajax_referer( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE . Visualizer_Plugin::VERSION, 'security' );
111 -
112 - $chart_id = filter_input(
113 - INPUT_POST,
114 - 'chart',
115 - FILTER_VALIDATE_INT,
116 - array(
117 - 'options' => array(
118 - 'min_range' => 1,
119 - ),
120 - )
121 - );
122 -
123 - if ( ! $chart_id ) {
124 - wp_send_json_error();
125 - }
126 -
127 - $time = filter_input(
128 - INPUT_POST,
129 - 'time',
130 - FILTER_VALIDATE_INT,
131 - array(
132 - 'options' => array(
133 - 'min_range' => -1,
134 - ),
135 - )
136 - );
137 -
138 - if ( Visualizer_Module::is_pro() ) {
139 - $is_woocommerce_report = filter_input(
140 - INPUT_POST,
141 - 'is_woocommerce_report',
142 - FILTER_VALIDATE_BOOLEAN
143 - );
144 -
145 - if ( $is_woocommerce_report ) {
146 - update_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE, true );
147 - } else {
148 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE );
149 - }
150 - }
151 -
152 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE );
153 -
154 - if ( -1 < $time ) {
155 - add_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, $time );
156 - // Update schedules.
157 - $schedules = get_option( Visualizer_Plugin::CF_JSON_SCHEDULE, array() );
158 - $schedules[ $chart_id ] = time() + $time * HOUR_IN_SECONDS;
159 - update_option( Visualizer_Plugin::CF_JSON_SCHEDULE, $schedules );
160 - }
161 - wp_send_json_success();
162 - }
163 -
164 - /**
165 - * Get the root elements for JSON-endpoint.
166 - *
167 - * @since ?
168 - *
169 - * @access public
170 - */
171 - public function getJsonRoots() {
172 - check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_ROOTS . Visualizer_Plugin::VERSION, 'security' );
173 -
174 - $params = wp_parse_args( $_POST['params'] );
175 -
176 - $source = new Visualizer_Source_Json( $params );
177 -
178 - $roots = $source->fetchRoots();
179 - if ( empty( $roots ) ) {
180 - wp_send_json_error( array( 'msg' => $source->get_error() ) );
181 - }
182 -
183 - wp_send_json_success( array( 'url' => $params['url'], 'roots' => $roots ) );
184 - }
185 -
186 - /**
187 - * Get the data for the JSON-endpoint corresponding to the chosen root.
188 - *
189 - * @since ?
190 - *
191 - * @access public
192 - */
193 - public function getJsonData() {
194 - check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_DATA . Visualizer_Plugin::VERSION, 'security' );
195 -
196 - $params = wp_parse_args( $_POST['params'] );
197 -
198 - $chart_id = $params['chart'];
199 -
200 - if ( empty( $chart_id ) ) {
201 - wp_die();
202 - }
203 -
204 - $source = new Visualizer_Source_Json( $params );
205 - $source->fetch();
206 - $data = $source->getRawData();
207 -
208 - if ( empty( $data ) ) {
209 - wp_send_json_error( array( 'msg' => esc_html__( 'Unable to fetch data from the endpoint. Please try again.', 'visualizer' ) ) );
210 - }
211 -
212 - $data = Visualizer_Render_Layout::show( 'editor-table', $data, $chart_id, 'viz-json-table', false, false );
213 - wp_send_json_success( array( 'table' => $data, 'root' => $params['root'], 'url' => $params['url'], 'paging' => $source->getPaginationElements() ) );
214 - }
215 -
216 - /**
217 - * Updates the database with the correct post parameters for JSON-endpoint charts.
218 - *
219 - * @since ?
220 - *
221 - * @access public
222 - */
223 - public function setJsonData() {
224 - check_ajax_referer( Visualizer_Plugin::ACTION_JSON_SET_DATA . Visualizer_Plugin::VERSION, 'security' );
225 -
226 - $params = $_POST;
227 - $chart_id = $_GET['chart'];
228 -
229 - if ( empty( $chart_id ) ) {
230 - wp_die();
231 - }
232 -
233 - $chart = get_post( $chart_id );
234 -
235 - $source = new Visualizer_Source_Json( $params );
236 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true );
237 - $source->fetchFromEditableTable();
238 -
239 - $content = $source->getData( get_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
240 - $chart->post_content = $content;
241 - wp_update_post( $chart->to_array() );
242 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
243 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
244 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
245 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_URL, $params['url'] );
246 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_ROOT, $params['root'] );
247 -
248 - delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_HEADERS );
249 - $headers = array( 'method' => $params['method'] );
250 - if ( ! empty( $params['auth'] ) ) {
251 - $headers['auth'] = $params['auth'];
252 - } elseif ( ! empty( $params['username'] ) && ! empty( $params['password'] ) ) {
253 - $headers['auth'] = array( 'username' => $params['username'], 'password' => $params['password'] );
254 - }
255 -
256 - add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_HEADERS, $headers );
257 -
258 - delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING );
259 - if ( ! empty( $params['paging'] ) ) {
260 - add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING, $params['paging'] );
261 - }
262 -
263 - if ( Visualizer_Module::is_pro() ) {
264 - if ( ! empty( $params['vz_woo_source'] ) ) {
265 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE, $params['vz_woo_source'] );
266 - } else {
267 - delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE );
268 - }
269 - }
270 -
271 - $time = filter_input(
272 - INPUT_POST,
273 - 'time',
274 - FILTER_VALIDATE_INT,
275 - array(
276 - 'options' => array(
277 - 'min_range' => -1,
278 - ),
279 - )
280 - );
281 -
282 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE );
283 -
284 - if ( -1 < $time ) {
285 - add_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, $time );
286 - }
287 -
288 - // delete other source specific parameters.
289 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY );
290 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE );
291 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_URL );
292 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE );
293 -
294 - $render = new Visualizer_Render_Page_Update();
295 - $render->id = $chart->ID;
296 - $render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
297 - $render->series = json_encode( $source->getSeries() );
298 - $render->render();
299 -
300 - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
301 - }
302 -
303 -
304 - /**
305 68 * Fetches charts from database.
306 69 *
307 70 * This method is also called from the media pop-up (classic editor: create a post and add chart from insert content).
308 71 *
@@ -331,9 +94,9 @@
331 94 // 'filter' is from the modal from the add media button.
332 95 $filter = filter_input( INPUT_GET, 'filter', FILTER_SANITIZE_STRING );
333 96 }
334 97
335 - if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
98 + if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes() ) ) {
336 99 $query_args['meta_query'] = array(
337 100 array(
338 101 'key' => Visualizer_Plugin::CF_CHART_TYPE,
339 102 'value' => $filter,
@@ -384,9 +147,9 @@
384 147 $chart = $this->_chart;
385 148 }
386 149 $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
387 150 $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
388 - $data = self::get_chart_data( $chart, $type );
151 + $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
389 152 $library = $this->load_chart_type( $chart->ID );
390 153
391 154 $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
392 155 $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
@@ -438,9 +201,9 @@
438 201 *
439 202 * @access public
440 203 */
441 204 public function deleteChart() {
442 - $is_post = $_SERVER['REQUEST_METHOD'] === 'POST';
205 + $is_post = $_SERVER['REQUEST_METHOD'] == 'POST';
443 206 $input_method = $is_post ? INPUT_POST : INPUT_GET;
444 207 $chart_id = $success = false;
445 208 $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
446 209 $capable = current_user_can( 'delete_posts' );
@@ -456,26 +219,13 @@
456 219 )
457 220 );
458 221 if ( $chart_id ) {
459 222 $chart = get_post( $chart_id );
460 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
223 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
461 224 }
462 225 }
463 226 if ( $success ) {
464 - global $sitepress;
465 - if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
466 - $trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
467 - $translations = $sitepress->get_element_translations( $trid );
468 - if ( ! empty( $translations ) ) {
469 - foreach ( $translations as $translated_post ) {
470 - wp_delete_post( $translated_post->element_id, true );
471 - }
472 - } else {
473 - wp_delete_post( $chart_id, true );
474 - }
475 - } else {
476 - wp_delete_post( $chart_id, true );
477 - }
227 + wp_delete_post( $chart_id, true );
478 228 }
479 229 if ( $is_post ) {
480 230 self::_sendResponse(
481 231 array(
@@ -482,9 +232,9 @@
482 232 'success' => $success,
483 233 )
484 234 );
485 235 }
486 - wp_redirect( remove_query_arg( 'vaction', wp_get_referer() ) );
236 + wp_redirect( wp_get_referer() );
487 237 exit;
488 238 }
489 239
490 240 /**
@@ -524,119 +274,50 @@
524 274 * @access public
525 275 */
526 276 public function renderChartPages() {
527 277 defined( 'IFRAME_REQUEST' ) || define( 'IFRAME_REQUEST', 1 );
528 - if ( ! defined( 'ET_BUILDER_PRODUCT_VERSION' ) && function_exists( 'et_get_theme_version' ) ) {
529 - define( 'ET_BUILDER_PRODUCT_VERSION', et_get_theme_version() );
530 - }
531 - // Set current screen for the render chart.
532 - set_current_screen( 'visualizer_render_chart' );
533 278 // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
534 279 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
535 - if ( ! empty( $_POST ) ) {
536 - $_POST = map_deep( $_POST, 'wp_strip_all_tags' );
537 - }
538 - if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
539 - if ( empty( $_GET['lang'] ) || empty( $_GET['parent_chart_id'] ) ) {
540 - $this->deleteOldCharts();
541 - $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
542 - $chart_status = Visualizer_Module_Admin::checkChartStatus( $default_type );
543 - if ( ! $chart_status ) {
544 - $default_type = 'line';
545 - }
546 - $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
547 - $source->fetch();
548 - $chart_id = wp_insert_post(
280 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
281 + $this->deleteOldCharts();
282 + $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
283 + $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
284 + $source->fetch();
285 + $chart_id = wp_insert_post(
286 + array(
287 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
288 + 'post_title' => 'Visualization',
289 + 'post_author' => get_current_user_id(),
290 + 'post_status' => 'auto-draft',
291 + 'post_content' => $source->getData(),
292 + )
293 + );
294 + if ( $chart_id && ! is_wp_error( $chart_id ) ) {
295 + add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
296 + add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
297 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
298 + add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
299 + add_post_meta(
300 + $chart_id,
301 + Visualizer_Plugin::CF_SETTINGS,
549 302 array(
550 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
551 - 'post_title' => 'Visualization',
552 - 'post_author' => get_current_user_id(),
553 - 'post_status' => 'auto-draft',
554 - 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
303 + 'focusTarget' => 'datum',
555 304 )
556 305 );
557 - if ( $chart_id && ! is_wp_error( $chart_id ) ) {
558 - add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
559 - add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
560 - add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
561 - add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
562 - add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, '' );
563 - add_post_meta(
564 - $chart_id,
565 - Visualizer_Plugin::CF_SETTINGS,
566 - array(
567 - 'focusTarget' => 'datum',
568 - )
569 - );
570 -
571 - do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
572 - }
573 - } else {
574 - if ( current_user_can( 'edit_posts' ) ) {
575 - $parent_chart_id = isset( $_GET['parent_chart_id'] ) ? filter_var( $_GET['parent_chart_id'], FILTER_VALIDATE_INT ) : '';
576 - $success = false;
577 - if ( $parent_chart_id ) {
578 - $parent_chart = get_post( $parent_chart_id );
579 - $success = $parent_chart && $parent_chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
580 - }
581 - if ( $success ) {
582 - $new_chart_id = wp_insert_post(
583 - array(
584 - 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
585 - 'post_title' => 'Visualization',
586 - 'post_author' => get_current_user_id(),
587 - 'post_status' => $parent_chart->post_status,
588 - 'post_content' => $parent_chart->post_content,
589 - )
590 - );
591 -
592 - if ( is_wp_error( $new_chart_id ) ) {
593 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Error while cloning chart %d = %s', $parent_chart_id, print_r( $new_chart_id, true ) ), 'error', __FILE__, __LINE__ );
594 - } else {
595 - $post_meta = get_post_meta( $parent_chart_id );
596 - $chart_id = $new_chart_id;
597 - foreach ( $post_meta as $key => $value ) {
598 - if ( strpos( $key, 'visualizer-' ) !== false ) {
599 - add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
600 - }
601 - }
602 - }
603 - }
604 - }
605 306 do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
606 307 }
607 - wp_redirect( esc_url_raw( add_query_arg( 'chart', (int) $chart_id ) ) );
608 -
609 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
610 - wp_die();
611 - }
612 - exit();
308 + wp_redirect( add_query_arg( 'chart', (int) $chart_id ) );
309 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
613 310 }
614 311
615 - $_POST['save_chart_image'] = isset( $_POST['save_chart_image'] ) && 'yes' === $_POST['save_chart_image'] ? true : false;
616 - $_POST['lazy_load_chart'] = isset( $_POST['lazy_load_chart'] ) && 'yes' === $_POST['lazy_load_chart'] ? true : false;
312 + $this->load_chart_type( $chart_id );
617 313
618 - if ( isset( $_POST['chart-img'] ) && ! empty( $_POST['chart-img'] ) ) {
619 - $attachment_id = $this->save_chart_image( $_POST['chart-img'], $chart_id, $_POST['save_chart_image'] );
620 - if ( $attachment_id ) {
621 - update_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, $attachment_id );
622 - }
623 - }
624 - $lib = $this->load_chart_type( $chart_id );
625 -
626 - // the alpha color picker (RGBA) is not supported by google.
627 - $color_picker_dep = 'wp-color-picker';
628 - if ( in_array( $lib, array( 'chartjs', 'datatables' ), true ) && ! wp_script_is( 'wp-color-picker-alpha', 'registered' ) ) {
629 - wp_register_script( 'wp-color-picker-alpha', VISUALIZER_ABSURL . 'js/lib/wp-color-picker-alpha.min.js', array( 'wp-color-picker' ), Visualizer_Plugin::VERSION );
630 - $color_picker_dep = 'wp-color-picker-alpha';
631 - }
632 -
633 314 // enqueue and register scripts and styles
634 315 wp_register_script( 'visualizer-chosen', VISUALIZER_ABSURL . 'js/lib/chosen.jquery.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
635 316 wp_register_style( 'visualizer-chosen', VISUALIZER_ABSURL . 'css/lib/chosen.min.css', array(), Visualizer_Plugin::VERSION );
636 317
637 318 wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION );
638 - wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen', 'jquery-ui-accordion', 'jquery-ui-tabs' ), Visualizer_Plugin::VERSION, true );
319 + wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION, true );
639 320 wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
640 321 wp_register_script(
641 322 'visualizer-render',
642 323 VISUALIZER_ABSURL . 'js/render-facade.js',
@@ -647,23 +328,19 @@
647 328 wp_register_script(
648 329 'visualizer-preview',
649 330 VISUALIZER_ABSURL . 'js/preview.js',
650 331 array(
651 - $color_picker_dep,
332 + 'wp-color-picker',
652 333 'visualizer-render',
653 334 ),
654 335 Visualizer_Plugin::VERSION,
655 336 true
656 337 );
657 - wp_register_script( 'visualizer-editor-simple', VISUALIZER_ABSURL . 'js/simple-editor.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
658 -
659 - do_action( 'visualizer_add_scripts' );
660 -
661 - if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
338 + // added by Ash/Upwork
339 + if ( VISUALIZER_PRO ) {
662 340 global $Visualizer_Pro;
663 341 $Visualizer_Pro->_addScriptsAndStyles();
664 342 }
665 -
666 343 // dispatch pages
667 344 $this->_chart = get_post( $chart_id );
668 345 $tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer';
669 346
@@ -675,9 +352,8 @@
675 352 if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) {
676 353 // if the cancel button is clicked.
677 354 $this->undoRevisions( $chart_id, true );
678 355 } elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
679 - $this->handlePermissions();
680 356 // if the save button is clicked.
681 357 $this->undoRevisions( $chart_id, false );
682 358 } else {
683 359 // if the edit button is clicked.
@@ -683,16 +359,8 @@
683 359 // if the edit button is clicked.
684 360 $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
685 361 }
686 362
687 - // Clear existing chart cache.
688 - if ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
689 - $cache_key = Visualizer_Plugin::CF_CHART_CACHE . '_' . $chart_id;
690 - if ( get_transient( $cache_key ) ) {
691 - delete_transient( $cache_key );
692 - }
693 - }
694 -
695 363 switch ( $tab ) {
696 364 case 'settings':
697 365 $this->_handleDataAndSettingsPage();
698 366 break;
@@ -700,9 +368,9 @@
700 368 case 'visualizer': // fall through.
701 369 $this->_handleTypesPage();
702 370 break;
703 371 default:
704 - // this should never happen.
372 + do_action( 'visualizer_pro_handle_tab', $tab, $this->_chart );
705 373 break;
706 374 }
707 375 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
708 376 }
@@ -709,26 +377,25 @@
709 377
710 378 /**
711 379 * Load code editor assets.
712 380 */
713 - private function loadCodeEditorAssets( $chart_id ) {
381 + private function loadCodeEditorAssets() {
714 382 global $wp_version;
715 383
716 - $wp_scripts = wp_scripts();
384 + if ( ! VISUALIZER_PRO ) {
385 + return;
386 + }
717 387
388 + $table_col_mapping = Visualizer_Source_Query_Params::get_all_db_tables_column_mapping();
389 +
718 390 // data tables assets.
719 - wp_register_script( 'visualizer-datatables', VISUALIZER_ABSURL . 'js/lib/datatables.min.js', array( 'jquery-ui-core' ), Visualizer_Plugin::VERSION );
720 - wp_register_style( 'visualizer-datatables', VISUALIZER_ABSURL . 'css/lib/datatables.min.css', array(), Visualizer_Plugin::VERSION );
721 - wp_register_style( 'visualizer-jquery-ui', sprintf( '//code.jquery.com/ui/%s/themes/smoothness/jquery-ui.css', $wp_scripts->registered['jquery-ui-core']->ver ), array( 'visualizer-datatables' ), Visualizer_Plugin::VERSION );
391 + wp_register_script( 'visualizer-datatables', '//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js', array( 'jquery-ui-core' ), Visualizer_Plugin::VERSION );
392 + wp_register_style( 'visualizer-datatables', '//cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css', array(), Visualizer_Plugin::VERSION );
393 + wp_register_style( 'visualizer-datatables-ui', '//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css', array( 'visualizer-datatables' ), Visualizer_Plugin::VERSION );
394 +
722 395 wp_enqueue_script( 'visualizer-datatables' );
723 - wp_enqueue_style( 'visualizer-jquery-ui' );
396 + wp_enqueue_style( 'visualizer-datatables-ui' );
724 397
725 - if ( ! Visualizer_Module::is_pro() ) {
726 - return;
727 - }
728 -
729 - $table_col_mapping = Visualizer_Source_Query_Params::get_all_db_tables_column_mapping( $chart_id );
730 -
731 398 if ( version_compare( $wp_version, '4.9.0', '<' ) ) {
732 399 // code mirror assets.
733 400 wp_register_script( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
734 401 wp_register_script( 'visualizer-codemirror-placeholder', '//codemirror.net/addon/display/placeholder.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
@@ -762,25 +429,8 @@
762 429 return $table_col_mapping;
763 430 }
764 431
765 432 /**
766 - * Handle permissions from the new conslidated settings sidebar.
767 - */
768 - private function handlePermissions() {
769 - if ( ! Visualizer_Module::is_pro() ) {
770 - return;
771 - }
772 -
773 - // we will not support old free and new pro.
774 - // handling new free and old pro.
775 - if ( has_action( 'visualizer_pro_handle_tab' ) ) {
776 - do_action( 'visualizer_pro_handle_tab', 'permissions', $this->_chart );
777 - } else {
778 - do_action( 'visualizer_handle_permissions', $this->_chart );
779 - }
780 - }
781 -
782 - /**
783 433 * Handle data and settings page
784 434 */
785 435 private function _handleDataAndSettingsPage() {
786 436 if ( isset( $_POST['map_api_key'] ) ) {
@@ -785,53 +435,30 @@
785 435 private function _handleDataAndSettingsPage() {
786 436 if ( isset( $_POST['map_api_key'] ) ) {
787 437 update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
788 438 }
789 -
790 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
791 - if ( $this->_chart->post_status === 'auto-draft' ) {
439 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
440 + if ( $this->_chart->post_status == 'auto-draft' ) {
792 441 $this->_chart->post_status = 'publish';
793 442
794 443 // ensure that a revision is not created. If a revision is created it will have the proper data and the parent of the revision will have default data.
795 444 // we do not want any difference in data so disable revisions temporarily.
796 - $this->disableRevisionsTemporarily();
797 -
445 + add_filter( 'wp_revisions_to_keep', '__return_false' );
798 446 wp_update_post( $this->_chart->to_array() );
799 447 }
800 448 // save meta data only when it is NOT being canceled.
801 449 if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) {
802 450 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
803 -
804 - // we will keep a parameter called 'internal_title' that will be set to the given title or, if empty, the chart ID
805 - // this will help in searching with the chart id.
806 - $settings = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
807 - $title = null;
808 - if ( isset( $settings['title'] ) && ! empty( $settings['title'] ) ) {
809 - $title = $settings['title'];
810 - if ( is_array( $title ) ) {
811 - $title = $settings['title']['text'];
812 - }
813 - }
814 - if ( empty( $title ) ) {
815 - $title = $this->_chart->ID;
816 - }
817 - $settings['internal_title'] = $title;
818 - $settings_label = isset( $settings['pieResidueSliceLabel'] ) ? $settings['pieResidueSliceLabel'] : '';
819 - if ( empty( $settings_label ) ) {
820 - $settings['pieResidueSliceLabel'] = esc_html__( 'Other', 'visualizer' );
821 - } else {
822 - $settings['pieResidueSliceLabel'] = $settings_label;
823 - }
824 - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
825 451 }
826 452 $render = new Visualizer_Render_Page_Send();
827 453 $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
828 454 wp_iframe( array( $render, 'render' ) );
455 +
829 456 return;
830 457 }
831 458 $data = $this->_getChartArray();
832 459 $sidebar = '';
833 - $sidebar_class = $this->load_chart_class_name( $this->_chart->ID );
460 + $sidebar_class = 'Visualizer_Render_Sidebar_Type_' . ucfirst( $data['type'] );
834 461 if ( class_exists( $sidebar_class, true ) ) {
835 462 $sidebar = new $sidebar_class( $data['settings'] );
836 463 $sidebar->__series = $data['series'];
837 464 $sidebar->__data = $data['data'];
@@ -836,14 +463,14 @@
836 463 $sidebar->__series = $data['series'];
837 464 $sidebar->__data = $data['data'];
838 465 } else {
839 466 $sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
840 - if ( $sidebar !== '' ) {
467 + if ( $sidebar != '' ) {
841 468 $sidebar->__series = $data['series'];
842 469 $sidebar->__data = $data['data'];
843 470 }
844 471 }
845 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
472 + unset( $data['settings']['width'], $data['settings']['height'] );
846 473 wp_enqueue_style( 'wp-color-picker' );
847 474 wp_enqueue_style( 'visualizer-frame' );
848 475 wp_enqueue_script( 'visualizer-preview' );
849 476 wp_enqueue_script( 'visualizer-chosen' );
@@ -848,37 +475,17 @@
848 475 wp_enqueue_script( 'visualizer-preview' );
849 476 wp_enqueue_script( 'visualizer-chosen' );
850 477 wp_enqueue_script( 'visualizer-render' );
851 478
852 - if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) {
853 - wp_enqueue_script( 'visualizer-editor-simple' );
854 - wp_localize_script(
855 - 'visualizer-editor-simple',
856 - 'visualizer1',
857 - array(
858 - 'ajax' => array(
859 - 'url' => admin_url( 'admin-ajax.php' ),
860 - 'nonces' => array(
861 - ),
862 - 'actions' => array(
863 - ),
864 - ),
865 - )
866 - );
867 - }
479 + $table_col_mapping = $this->loadCodeEditorAssets();
868 480
869 - $table_col_mapping = $this->loadCodeEditorAssets( $this->_chart->ID );
870 -
871 481 wp_localize_script(
872 482 'visualizer-render',
873 483 'visualizer',
874 484 array(
875 485 'l10n' => array(
876 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
486 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
877 487 'loading' => esc_html__( 'Loading...', 'visualizer' ),
878 - 'json_error' => esc_html__( 'An error occured in fetching data.', 'visualizer' ),
879 - 'select_columns' => esc_html__( 'Please select a few columns to include in the chart.', 'visualizer' ),
880 - 'save_settings' => __( 'You have modified the chart\'s settings. To modify the source/data again, you must save this chart and reopen it for editing. If you continue without saving the chart, you may lose your changes.', 'visualizer' ),
881 488 ),
882 489 'charts' => array(
883 490 'canvas' => $data,
884 491 'id' => $this->_chart->ID,
@@ -889,29 +496,19 @@
889 496 'url' => admin_url( 'admin-ajax.php' ),
890 497 'nonces' => array(
891 498 'permissions' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA ),
892 499 'db_get_data' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION ),
893 - 'json_get_roots' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_GET_ROOTS . Visualizer_Plugin::VERSION ),
894 - 'json_get_data' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_GET_DATA . Visualizer_Plugin::VERSION ),
895 - 'json_set_schedule' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE . Visualizer_Plugin::VERSION ),
896 500 ),
897 501 'actions' => array(
898 502 'permissions' => Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA,
899 503 'db_get_data' => Visualizer_Plugin::ACTION_FETCH_DB_DATA,
900 - 'json_get_roots' => Visualizer_Plugin::ACTION_JSON_GET_ROOTS,
901 - 'json_get_data' => Visualizer_Plugin::ACTION_JSON_GET_DATA,
902 - 'json_set_schedule' => Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE,
903 504 ),
904 505 ),
905 506 'db_query' => array(
906 507 'tables' => $table_col_mapping,
907 508 ),
908 - 'is_pro' => Visualizer_Module::is_pro(),
509 + 'is_pro' => VISUALIZER_PRO,
909 510 'page_type' => 'chart',
910 - 'json_tag_separator' => Visualizer_Source_Json::TAG_SEPARATOR,
911 - 'json_tag_separator_view' => Visualizer_Source_Json::TAG_SEPARATOR_VIEW,
912 - 'is_front' => false,
913 - 'rest_base' => get_rest_url( null, 'wc/v3/reports/' ),
914 511 )
915 512 );
916 513
917 514 $render = new Visualizer_Render_Page_Data();
@@ -919,25 +516,21 @@
919 516 $render->type = $data['type'];
920 517 $render->custom_css = $data['css'];
921 518 $render->sidebar = $sidebar;
922 519 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
923 - $render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
520 + $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART
924 521 ? esc_html__( 'Save Chart', 'visualizer' )
925 522 : esc_html__( 'Create Chart', 'visualizer' );
926 - if ( filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART ) {
523 + if ( filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART ) {
927 524 $render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
928 525 }
929 526 } else {
930 527 $render->button = esc_attr__( 'Insert Chart', 'visualizer' );
931 528 }
932 -
933 - do_action( 'visualizer_enqueue_scripts_and_styles', $data, $this->_chart->ID );
934 -
935 - if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
529 + if ( VISUALIZER_PRO ) {
936 530 global $Visualizer_Pro;
937 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
531 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
938 532 }
939 -
940 533 $this->_addAction( 'admin_head', 'renderFlattrScript' );
941 534 wp_iframe( array( $render, 'render' ) );
942 535 }
943 536
@@ -949,35 +542,24 @@
949 542 * @access private
950 543 */
951 544 private function _handleTypesPage() {
952 545 // process post request
953 - if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
546 + if ( $_SERVER['REQUEST_METHOD'] == 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
954 547 $type = filter_input( INPUT_POST, 'type' );
955 - $library = filter_input( INPUT_POST, 'chart-library' );
956 - if ( Visualizer_Module_Admin::checkChartStatus( $type ) ) {
957 - if ( empty( $library ) ) {
958 - // library cannot be empty.
959 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, 'Chart library empty while creating the chart! Aborting...', 'error', __FILE__, __LINE__ );
960 - return;
961 - }
962 -
548 + if ( in_array( $type, Visualizer_Plugin::getChartTypes() ) ) {
963 549 // save new chart type
964 550 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, $type );
965 - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_LIBRARY, $library );
966 551 // if the chart has default data, update it with appropriate default data for new type
967 552 if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
968 553 $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
969 554 $source->fetch();
970 - $this->_chart->post_content = $source->getData( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
555 + $this->_chart->post_content = $source->getData();
971 556 wp_update_post( $this->_chart->to_array() );
972 557 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
973 558 }
974 -
975 - Visualizer_Module_Utility::set_defaults( $this->_chart );
976 -
977 559 // redirect to next tab
978 560 // changed by Ash/Upwork
979 - wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
561 + wp_redirect( add_query_arg( 'tab', 'settings' ) );
980 562
981 563 return;
982 564 }
983 565 }
@@ -982,9 +564,9 @@
982 564 }
983 565 }
984 566 $render = new Visualizer_Render_Page_Types();
985 567 $render->type = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
986 - $render->types = Visualizer_Module_Admin::_getChartTypesLocalized( false, false, false, 'types' );
568 + $render->types = Visualizer_Module_Admin::_getChartTypesLocalized();
987 569 $render->chart = $this->_chart;
988 570 wp_enqueue_style( 'visualizer-frame' );
989 571 wp_enqueue_script( 'visualizer-frame' );
990 572 wp_iframe( array( $render, 'render' ) );
@@ -1000,131 +582,10 @@
1000 582 */
1001 583 public function renderFlattrScript() {
1002 584 echo '';
1003 585 }
1004 -
586 + // changed by Ash/Upwork
1005 587 /**
1006 - * Processes the CSV that is sent in the request as a string.
1007 - *
1008 - * @since 3.2.0
1009 - */
1010 - private function handleCSVasString( $data, $editor_type ) {
1011 - $source = null;
1012 -
1013 - switch ( $editor_type ) {
1014 - case 'text':
1015 - // data coming in from the text editor.
1016 - $tmpfile = tempnam( get_temp_dir(), Visualizer_Plugin::NAME );
1017 - $handle = fopen( $tmpfile, 'w' );
1018 - $values = preg_split( '/[\n\r]+/', stripslashes( trim( $data ) ) );
1019 - if ( $values ) {
1020 - foreach ( $values as $row ) {
1021 - if ( empty( $row ) ) {
1022 - continue;
1023 - }
1024 - $row = explode( ',', $row );
1025 - $row = array_map(
1026 - function( $r ) {
1027 - return '' === $r ? ' ' : $r;
1028 - },
1029 - $row
1030 - );
1031 - $row = implode( ',', $row );
1032 - // don't use fpucsv here because we need to just dump the data
1033 - // minus the empty rows
1034 - // because fputcsv needs to tokenize
1035 - // we can standardize the CSV enclosure here and replace all ' with "
1036 - // we can assume that if there are an even number of ' they should be changed to "
1037 - // but that will screw up words like fo'c'sle
1038 - // so here let's just assume ' will NOT be used for enclosures
1039 - fwrite( $handle, $row );
1040 - fwrite( $handle, PHP_EOL );
1041 - }
1042 - }
1043 - $source = new Visualizer_Source_Csv( $tmpfile );
1044 - fclose( $handle );
1045 - break;
1046 - case 'table':
1047 - // Import from Chart
1048 - // fall-through.
1049 - case 'excel':
1050 - // data coming in from the excel editor.
1051 - $source = apply_filters( 'visualizer_pro_handle_chart_data', $data, '' );
1052 - break;
1053 - }
1054 - return $source;
1055 - }
1056 -
1057 - /**
1058 - * Parses the data uploaded as an HTML table.
1059 - *
1060 - * @since 3.2.0
1061 - *
1062 - * @access private
1063 - */
1064 - private function handleTabularData() {
1065 - $csv = array();
1066 - // the datatable mentions the headers twice, so lets remove the duplicates.
1067 - $headers = array_unique( array_filter( $_POST['header'] ) );
1068 - $types = $_POST['type'];
1069 -
1070 - // capture all the indexes that correspond to excluded columns.
1071 - $exclude = array();
1072 - $index = 0;
1073 - foreach ( $types as $type ) {
1074 - if ( empty( $type ) ) {
1075 - $exclude[] = $index;
1076 - }
1077 - $index++;
1078 - }
1079 -
1080 - // when N headers are being renamed, the number of headers increases by N
1081 - // because of the way datatable duplicates header information
1082 - // so unset the headers that have been renamed.
1083 - if ( count( $headers ) !== count( $types ) ) {
1084 - $to = count( $headers );
1085 - for ( $i = count( $types ); $i < $to; $i++ ) {
1086 - unset( $headers[ $i + 1 ] );
1087 - }
1088 - }
1089 -
1090 - $columns = array();
1091 - for ( $i = 0; $i < count( $headers ); $i++ ) {
1092 - if ( ! isset( $_POST[ 'data' . $i ] ) ) {
1093 - continue;
1094 - }
1095 - $columns[ $i ] = $_POST[ 'data' . $i ];
1096 - }
1097 -
1098 - $csv[] = $headers;
1099 - $csv[] = $types;
1100 - for ( $j = 0; $j < count( $columns[0] ); $j++ ) {
1101 - $row = array();
1102 - for ( $i = 0; $i < count( $headers ); $i++ ) {
1103 - $row[] = sanitize_text_field( $columns[ $i ][ $j ] );
1104 - }
1105 - $csv[] = $row;
1106 - }
1107 -
1108 - $tmpfile = tempnam( get_temp_dir(), Visualizer_Plugin::NAME );
1109 - $handle = fopen( $tmpfile, 'w' );
1110 -
1111 - if ( $csv ) {
1112 - $index = 0;
1113 - foreach ( $csv as $row ) {
1114 - // remove all the cells corresponding to the excluded headers.
1115 - foreach ( $exclude as $j ) {
1116 - unset( $row[ $j ] );
1117 - }
1118 - fputcsv( $handle, $row );
1119 - }
1120 - }
1121 - $source = new Visualizer_Source_Csv( $tmpfile );
1122 - fclose( $handle );
1123 - return $source;
1124 - }
1125 -
1126 - /**
1127 588 * Parses uploaded CSV file and saves new data for the chart.
1128 589 *
1129 590 * @since 1.0.0
1130 591 *
@@ -1146,9 +607,9 @@
1146 607
1147 608 // check chart, if chart exists
1148 609 // do not use filter_input as it does not work for phpunit test cases, use filter_var instead
1149 610 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
1150 - if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
611 + if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
1151 612 if ( ! $can_die ) {
1152 613 return;
1153 614 }
1154 615 status_header( 400 );
@@ -1154,10 +615,8 @@
1154 615 status_header( 400 );
1155 616 exit;
1156 617 }
1157 618
1158 - 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__ );
1159 -
1160 619 if ( ! isset( $_POST['vz-import-time'] ) ) {
1161 620 apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
1162 621 }
1163 622
@@ -1169,58 +628,27 @@
1169 628
1170 629 // delete "import from db" specific parameters.
1171 630 delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY );
1172 631 delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE );
1173 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS );
1174 632 }
1175 633
1176 - // delete json related data.
1177 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_URL );
1178 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_ROOT );
1179 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_PAGING );
1180 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_HEADERS );
1181 -
1182 - // delete last error
1183 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR );
1184 -
1185 - // delete editor related data.
1186 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR );
1187 -
1188 - // delete this so that a JSON import can be later edited manually without a problem.
1189 - delete_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE );
1190 -
1191 634 $source = null;
1192 635 $render = new Visualizer_Render_Page_Update();
1193 -
1194 - $remote_data = false;
1195 - if ( isset( $_POST['remote_data'] ) && function_exists( 'wp_http_validate_url' ) ) {
1196 - $remote_data = wp_http_validate_url( $_POST['remote_data'] );
1197 - }
1198 - if ( false !== $remote_data ) {
1199 - $source = new Visualizer_Source_Csv_Remote( $remote_data );
636 + if ( isset( $_POST['remote_data'] ) && filter_var( $_POST['remote_data'], FILTER_VALIDATE_URL ) ) {
637 + $source = new Visualizer_Source_Csv_Remote( $_POST['remote_data'] );
1200 638 if ( isset( $_POST['vz-import-time'] ) ) {
1201 - apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $remote_data, $_POST['vz-import-time'] );
639 + apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] );
1202 640 }
1203 - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
1204 641 } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
1205 642 $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
1206 643 } elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
1207 - $source = $this->handleCSVasString( $_POST['chart_data'], $_POST['editor-type'] );
1208 - update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
1209 - } elseif ( isset( $_POST['table_data'] ) && 'yes' === $_POST['table_data'] ) {
1210 - $source = $this->handleTabularData();
1211 - update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
644 + $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '', $chart_id, $_POST );
1212 645 } else {
1213 - 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__ );
1214 - $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' );
1215 - update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' ) );
646 + $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' );
1216 647 }
1217 -
1218 - 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__ );
1219 -
1220 648 if ( $source ) {
1221 649 if ( $source->fetch() ) {
1222 - $content = $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
650 + $content = $source->getData();
1223 651 $populate = true;
1224 652 if ( is_string( $content ) && is_array( unserialize( $content ) ) ) {
1225 653 $json = unserialize( $content );
1226 654 // if source exists, so should data. if source exists but data is blank, do not populate the chart.
@@ -1226,9 +654,8 @@
1226 654 // if source exists, so should data. if source exists but data is blank, do not populate the chart.
1227 655 // if we populate the data even if it is empty, the chart will show "Table has no columns".
1228 656 if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
1229 657 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__ );
1230 - update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, sprintf( 'Not populating chart data as source exists (%s) but data is empty!', $json['source'] ) );
1231 658 $populate = false;
1232 659 }
1233 660 }
1234 661 if ( $populate ) {
@@ -1234,43 +661,17 @@
1234 661 if ( $populate ) {
1235 662 $chart->post_content = $content;
1236 663 }
1237 664 wp_update_post( $chart->to_array() );
1238 -
1239 665 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1240 666 update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1241 667 update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
1242 -
1243 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Updated post for chart %d', $chart_id ), 'debug', __FILE__, __LINE__ );
1244 -
1245 - Visualizer_Module_Utility::set_defaults( $chart, null );
1246 -
1247 - $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
1248 - if ( isset( $settings['series'] ) && ! ( count( $settings['series'] ) - count( $source->getSeries() ) > 1 ) ) {
1249 - $diff_total_series = abs( count( $settings['series'] ) - count( $source->getSeries() ) );
1250 - if ( $diff_total_series ) {
1251 - foreach ( range( 1, $diff_total_series ) as $k => $diff_series ) {
1252 - $settings['series'][] = end( $settings['series'] );
1253 - }
1254 - update_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
1255 - }
1256 - }
1257 -
1258 668 $render->id = $chart->ID;
1259 - $render->data = json_encode( $source->getRawData( get_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
669 + $render->data = json_encode( $source->getRawData() );
1260 670 $render->series = json_encode( $source->getSeries() );
1261 - $render->settings = json_encode( $settings );
1262 671 } else {
1263 - $error = $source->get_error();
1264 - if ( empty( $error ) ) {
1265 - $error = esc_html__( 'CSV file is broken or invalid. Please try again.', 'visualizer' );
1266 - }
1267 - $render->message = $error;
1268 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( '%s for chart %d.', $error, $chart_id ), 'error', __FILE__, __LINE__ );
1269 - update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, $error );
672 + $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' );
1270 673 }
1271 - } else {
1272 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
1273 674 }
1274 675 $render->render();
1275 676 if ( ! $can_die ) {
1276 677 return;
@@ -1286,18 +687,27 @@
1286 687 * @access public
1287 688 */
1288 689 public function cloneChart() {
1289 690 $chart_id = $success = false;
1290 - $nonce = isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], Visualizer_Plugin::ACTION_CLONE_CHART );
691 + $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART );
1291 692 $capable = current_user_can( 'edit_posts' );
1292 693 if ( $nonce && $capable ) {
1293 - $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
694 + $chart_id = filter_input(
695 + INPUT_GET,
696 + 'chart',
697 + FILTER_VALIDATE_INT,
698 + array(
699 + 'options' => array(
700 + 'min_range' => 1,
701 + ),
702 + )
703 + );
1294 704 if ( $chart_id ) {
1295 705 $chart = get_post( $chart_id );
1296 - $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
706 + $success = $chart && $chart->post_type == Visualizer_Plugin::CPT_VISUALIZER;
1297 707 }
1298 708 }
1299 - $redirect = remove_query_arg( 'vaction', wp_get_referer() );
709 + $redirect = wp_get_referer();
1300 710 if ( $success ) {
1301 711 $new_chart_id = wp_insert_post(
1302 712 array(
1303 713 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
@@ -1306,35 +716,23 @@
1306 716 'post_status' => $chart->post_status,
1307 717 'post_content' => $chart->post_content,
1308 718 )
1309 719 );
1310 - if ( is_wp_error( $new_chart_id ) ) {
1311 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Error while cloning chart %d = %s', $chart_id, print_r( $new_chart_id, true ) ), 'error', __FILE__, __LINE__ );
1312 - } else {
1313 - $post_meta = get_post_meta( $chart_id );
1314 - foreach ( $post_meta as $key => $value ) {
1315 - if ( strpos( $key, 'visualizer-' ) !== false ) {
1316 - add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
1317 - }
1318 - }
1319 - $redirect = esc_url(
1320 - add_query_arg(
1321 - array(
1322 - 'page' => 'visualizer',
1323 - 'type' => filter_input( INPUT_GET, 'type' ),
1324 - 'vaction' => false,
1325 - ),
1326 - admin_url( 'admin.php' )
720 + if ( $new_chart_id && ! is_wp_error( $new_chart_id ) ) {
721 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_CHART_TYPE, get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true ) );
722 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, get_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, true ) );
723 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SOURCE, get_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, true ) );
724 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SERIES, get_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, true ) );
725 + add_post_meta( $new_chart_id, Visualizer_Plugin::CF_SETTINGS, get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) );
726 + $redirect = add_query_arg(
727 + array(
728 + 'page' => 'visualizer',
729 + 'type' => filter_input( INPUT_GET, 'type' ),
1327 730 ),
1328 - null,
1329 - 'db'
731 + admin_url( 'upload.php' )
1330 732 );
1331 733 }
1332 734 }
1333 -
1334 - if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1335 - wp_die();
1336 - }
1337 735 wp_redirect( $redirect );
1338 736 exit;
1339 737 }
1340 738
@@ -1380,12 +778,9 @@
1380 778 $data = $this->_getChartArray();
1381 779 $render = new Visualizer_Render_Page_Data();
1382 780 $render->chart = $this->_chart;
1383 781 $render->type = $data['type'];
1384 -
1385 - if ( $data && $data['settings'] ) {
1386 - unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
1387 - }
782 + unset( $data['settings']['width'], $data['settings']['height'] );
1388 783 wp_enqueue_style( 'visualizer-frame' );
1389 784 wp_enqueue_script( 'visualizer-render' );
1390 785 wp_localize_script(
1391 786 'visualizer-render',
@@ -1391,9 +786,9 @@
1391 786 'visualizer-render',
1392 787 'visualizer',
1393 788 array(
1394 789 'l10n' => array(
1395 - 'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
790 + 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ),
1396 791 'loading' => esc_html__( 'Loading...', 'visualizer' ),
1397 792 ),
1398 793 'charts' => array(
1399 794 'canvas' => $data,
@@ -1399,16 +794,13 @@
1399 794 'canvas' => $data,
1400 795 ),
1401 796 )
1402 797 );
1403 -
1404 - do_action( 'visualizer_enqueue_scripts_and_styles', $data, $this->_chart->ID );
1405 -
1406 - if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
798 + // Added by Ash/Upwork
799 + if ( VISUALIZER_PRO ) {
1407 800 global $Visualizer_Pro;
1408 - $Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
801 + $Visualizer_Pro->_enqueueScriptsAndStyles( $data );
1409 802 }
1410 -
1411 803 // Added by Ash/Upwork
1412 804 $this->_addAction( 'admin_head', 'renderFlattrScript' );
1413 805 wp_iframe( array( $render, 'render' ) );
1414 806 }
@@ -1420,19 +812,14 @@
1420 812 */
1421 813 public function getQueryData() {
1422 814 check_ajax_referer( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION, 'security' );
1423 815
1424 - if ( ! current_user_can( 'administrator' ) ) {
1425 - wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1426 - }
1427 -
1428 816 $params = wp_parse_args( $_POST['params'] );
1429 - $chart_id = filter_var( $params['chart_id'], FILTER_VALIDATE_INT );
1430 -
1431 - $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
817 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ) );
1432 818 $html = $source->fetch( true );
1433 - $error = $source->get_error();
1434 - if ( ! empty( $error ) ) {
819 + $error = '';
820 + if ( empty( $html ) ) {
821 + $error = $source->get_error();
1435 822 wp_send_json_error( array( 'msg' => $error ) );
1436 823 }
1437 824 wp_send_json_success( array( 'table' => $html ) );
1438 825 }
@@ -1455,42 +842,21 @@
1455 842 ),
1456 843 )
1457 844 );
1458 845
1459 - $hours = filter_input(
1460 - INPUT_POST,
1461 - 'refresh',
1462 - FILTER_VALIDATE_FLOAT,
1463 - array(
1464 - 'options' => array(
1465 - 'min_range' => -1,
1466 - 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
1467 - ),
1468 - )
1469 - );
1470 -
1471 - if ( ! is_numeric( $hours ) ) {
1472 - $hours = -1;
1473 - }
1474 -
1475 846 $render = new Visualizer_Render_Page_Update();
1476 847 if ( $chart_id ) {
1477 848 $params = wp_parse_args( $_POST['params'] );
1478 - $source = new Visualizer_Source_Query( stripslashes( $params['query'] ), $chart_id, $params );
849 + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ) );
1479 850 $source->fetch( false );
1480 851 $error = $source->get_error();
1481 852 if ( empty( $error ) ) {
853 + $hours = $_POST['refresh'];
1482 854 update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, stripslashes( $params['query'] ) );
1483 855 update_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
1484 856 update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
1485 857 update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, $hours );
1486 858 update_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
1487 - if ( isset( $params['db_type'] ) && $params['db_type'] !== Visualizer_Plugin::WP_DB_NAME ) {
1488 - $remote_db_params = $params;
1489 - unset( $remote_db_params['query'] );
1490 - unset( $remote_db_params['chart_id'] );
1491 - update_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS, $remote_db_params );
1492 - }
1493 859
1494 860 $schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() );
1495 861 $schedules[ $chart_id ] = time() + $hours * HOUR_IN_SECONDS;
1496 862 update_option( Visualizer_Plugin::CF_DB_SCHEDULE, $schedules );
@@ -1497,14 +863,13 @@
1497 863
1498 864 wp_update_post(
1499 865 array(
1500 866 'ID' => $chart_id,
1501 - 'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
867 + 'post_content' => $source->getData(),
1502 868 )
1503 869 );
1504 - $render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
870 + $render->data = json_encode( $source->getRawData() );
1505 871 $render->series = json_encode( $source->getSeries() );
1506 - $render->id = $chart_id;
1507 872 } else {
1508 873 $render->message = $error;
1509 874 }
1510 875 }
@@ -1533,80 +898,13 @@
1533 898 ),
1534 899 )
1535 900 );
1536 901
1537 - $hours = filter_input(
1538 - INPUT_POST,
1539 - 'refresh',
1540 - FILTER_VALIDATE_INT,
1541 - array(
1542 - 'options' => array(
1543 - 'min_range' => -1,
1544 - 'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
1545 - ),
1546 - )
1547 - );
902 + $hours = $_POST['refresh'];
1548 903
1549 - if ( 0 !== $hours && empty( $hours ) ) {
1550 - $hours = -1;
1551 - }
1552 -
1553 904 do_action( 'visualizer_save_filter', $chart_id, $hours );
1554 905
1555 906 if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1556 907 defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1557 908 }
1558 - }
1559 -
1560 - /**
1561 - * Save chart image.
1562 - *
1563 - * @param string $base64_img Chart image.
1564 - * @param int $chart_id Chart ID.
1565 - * @param bool $save_attachment Save attachment.
1566 - * @return attachment ID
1567 - */
1568 - public function save_chart_image( $base64_img, $chart_id, $save_attachment = true ) {
1569 - // Delete old chart image.
1570 - $old_attachment_id = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, true );
1571 - if ( $old_attachment_id ) {
1572 - wp_delete_attachment( $old_attachment_id, true );
1573 - }
1574 -
1575 - if ( ! $save_attachment ) {
1576 - return 0;
1577 - }
1578 -
1579 - // Upload dir.
1580 - $upload_dir = wp_upload_dir();
1581 - $upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
1582 -
1583 - $img = str_replace( 'data:image/png;base64,', '', $base64_img );
1584 - $img = str_replace( ' ', '+', $img );
1585 - $decoded = base64_decode( $img );
1586 - $filename = 'visualization-' . $chart_id . '.png';
1587 - $file_type = 'image/png';
1588 - $hashed_filename = $filename;
1589 -
1590 - // Save the image in the uploads directory.
1591 - require_once ABSPATH . '/wp-admin/includes/file.php';
1592 - \WP_Filesystem();
1593 - global $wp_filesystem;
1594 - if ( ! is_a( $wp_filesystem, 'WP_Filesystem_Base' ) ) {
1595 - $creds = request_filesystem_credentials( site_url() );
1596 - wp_filesystem( $creds );
1597 - }
1598 - $upload_file = $wp_filesystem->put_contents( $upload_path . $hashed_filename, $decoded );
1599 -
1600 - // Insert new chart image.
1601 - $attachment = array(
1602 - 'post_mime_type' => $file_type,
1603 - 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $hashed_filename ) ),
1604 - 'post_content' => '',
1605 - 'post_status' => 'inherit',
1606 - 'guid' => $upload_dir['url'] . '/' . basename( $hashed_filename ),
1607 - );
1608 -
1609 - $attach_id = wp_insert_attachment( $attachment, $upload_dir['path'] . '/' . $hashed_filename );
1610 - return $attach_id;
1611 909 }
1612 910 }