Sindbad~EG File Manager
<?php
// +----------------------------------------------------------------------+
// | Copyright 2013 Madpixels (email : visualizer@madpixels.net) |
// +----------------------------------------------------------------------+
// | This program is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License, version 2, as |
// | published by the Free Software Foundation. |
// | |
// | This program is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with this program; if not, write to the Free Software |
// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
// | MA 02110-1301 USA |
// +----------------------------------------------------------------------+
// | Author: Eugene Manuilov <eugene@manuilov.org> |
// +----------------------------------------------------------------------+
/**
* The module for all stuff related to getting, editing, creating and deleting charts.
*
* @category Visualizer
* @package Module
*
* @since 1.0.0
*/
class Visualizer_Module_Chart extends Visualizer_Module {
const NAME = __CLASS__;
/**
* The chart object.
*
* @since 1.0.0
*
* @access private
* @var WP_Post
*/
private $_chart;
/**
* Constructor.
*
* @since 1.0.0
*
* @access public
*
* @param Visualizer_Plugin $plugin The instance of the plugin.
*/
public function __construct( Visualizer_Plugin $plugin ) {
parent::__construct( $plugin );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_GET_CHARTS, 'getCharts' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_DELETE_CHART, 'deleteChart' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_CREATE_CHART, 'renderChartPages' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_EDIT_CHART, 'renderChartPages' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_UPLOAD_DATA, 'uploadData' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_CLONE_CHART, 'cloneChart' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_FETCH_DB_DATA, 'getQueryData' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_DB_QUERY, 'saveQuery' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_GET_ROOTS, 'getJsonRoots' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_GET_DATA, 'getJsonData' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_SET_DATA, 'setJsonData' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE, 'setJsonSchedule' );
$this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY, 'saveFilter' );
$this->_addFilter( 'visualizer_get_sidebar', 'getSidebar', 10, 2 );
}
/**
* Generates the HTML of the sidebar for the chart.
*
* @since ?
*
* @access public
*/
public function getSidebar( $sidebar, $chart_id ) {
$chart = get_post( $chart_id );
$data = $this->_getChartArray( $chart );
$sidebar = '';
$sidebar_class = $this->load_chart_class_name( $chart_id );
if ( class_exists( $sidebar_class, true ) ) {
$sidebar = new $sidebar_class( $data['settings'] );
$sidebar->__series = $data['series'];
$sidebar->__data = $data['data'];
} else {
$sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
if ( $sidebar !== '' ) {
$sidebar->__series = $data['series'];
$sidebar->__data = $data['data'];
}
}
return str_replace( "'", '"', $sidebar->__toString() );
}
/**
* Sets the schedule for how JSON-endpoint charts should be updated.
*
* @since ?
*
* @access public
*/
public function setJsonSchedule() {
check_ajax_referer( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE . Visualizer_Plugin::VERSION, 'security' );
$chart_id = filter_input(
INPUT_POST,
'chart',
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => 1,
),
)
);
if ( ! $chart_id ) {
wp_send_json_error();
}
$time = filter_input(
INPUT_POST,
'time',
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => -1,
),
)
);
if ( Visualizer_Module::is_pro() ) {
$is_woocommerce_report = filter_input(
INPUT_POST,
'is_woocommerce_report',
FILTER_VALIDATE_BOOLEAN
);
if ( $is_woocommerce_report ) {
update_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE, true );
} else {
delete_post_meta( $chart_id, Visualizer_Plugin::CF_IS_WOOCOMMERCE_SOURCE );
}
}
delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE );
if ( -1 < $time ) {
add_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, $time );
// Update schedules.
$schedules = get_option( Visualizer_Plugin::CF_JSON_SCHEDULE, array() );
$schedules[ $chart_id ] = time() + $time * HOUR_IN_SECONDS;
update_option( Visualizer_Plugin::CF_JSON_SCHEDULE, $schedules );
}
wp_send_json_success();
}
/**
* Get the root elements for JSON-endpoint.
*
* @since ?
*
* @access public
*/
public function getJsonRoots() {
check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_ROOTS . Visualizer_Plugin::VERSION, 'security' );
$params = wp_parse_args( $_POST['params'] );
$source = new Visualizer_Source_Json( $params );
$roots = $source->fetchRoots();
if ( empty( $roots ) ) {
wp_send_json_error( array( 'msg' => $source->get_error() ) );
}
wp_send_json_success( array( 'url' => $params['url'], 'roots' => $roots ) );
}
/**
* Get the data for the JSON-endpoint corresponding to the chosen root.
*
* @since ?
*
* @access public
*/
public function getJsonData() {
check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_DATA . Visualizer_Plugin::VERSION, 'security' );
$params = wp_parse_args( $_POST['params'] );
$chart_id = $params['chart'];
if ( empty( $chart_id ) ) {
wp_die();
}
$source = new Visualizer_Source_Json( $params );
$source->fetch();
$data = $source->getRawData();
if ( empty( $data ) ) {
wp_send_json_error( array( 'msg' => esc_html__( 'Unable to fetch data from the endpoint. Please try again.', 'visualizer' ) ) );
}
$data = Visualizer_Render_Layout::show( 'editor-table', $data, $chart_id, 'viz-json-table', false, false );
wp_send_json_success( array( 'table' => $data, 'root' => $params['root'], 'url' => $params['url'], 'paging' => $source->getPaginationElements() ) );
}
/**
* Updates the database with the correct post parameters for JSON-endpoint charts.
*
* @since ?
*
* @access public
*/
public function setJsonData() {
check_ajax_referer( Visualizer_Plugin::ACTION_JSON_SET_DATA . Visualizer_Plugin::VERSION, 'security' );
$params = $_POST;
$chart_id = $_GET['chart'];
if ( empty( $chart_id ) ) {
wp_die();
}
$chart = get_post( $chart_id );
$source = new Visualizer_Source_Json( $params );
update_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true );
$source->fetchFromEditableTable();
$content = $source->getData( get_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
$chart->post_content = $content;
wp_update_post( $chart->to_array() );
update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_URL, $params['url'] );
update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_ROOT, $params['root'] );
delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_HEADERS );
$headers = array( 'method' => $params['method'] );
if ( ! empty( $params['auth'] ) ) {
$headers['auth'] = $params['auth'];
} elseif ( ! empty( $params['username'] ) && ! empty( $params['password'] ) ) {
$headers['auth'] = array( 'username' => $params['username'], 'password' => $params['password'] );
}
add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_HEADERS, $headers );
delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING );
if ( ! empty( $params['paging'] ) ) {
add_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_PAGING, $params['paging'] );
}
if ( Visualizer_Module::is_pro() ) {
if ( ! empty( $params['vz_woo_source'] ) ) {
update_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE, $params['vz_woo_source'] );
} else {
delete_post_meta( $chart->ID, Visualizer_Plugin::CF_JSON_WOOCOMMERCE_SOURCE );
}
}
$time = filter_input(
INPUT_POST,
'time',
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => -1,
),
)
);
delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE );
if ( -1 < $time ) {
add_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_SCHEDULE, $time );
}
// delete other source specific parameters.
delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY );
delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE );
delete_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_URL );
delete_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_SCHEDULE );
$render = new Visualizer_Render_Page_Update();
$render->id = $chart->ID;
$render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
$render->series = json_encode( $source->getSeries() );
$render->render();
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
}
/**
* Fetches charts from database.
*
* This method is also called from the media pop-up (classic editor: create a post and add chart from insert content).
*
* @since 1.0.0
*
* @access public
*/
public function getCharts() {
$query_args = array(
'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
'posts_per_page' => 9,
'paged' => filter_input(
INPUT_GET,
'page',
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => 1,
'default' => 1,
),
)
),
);
$filter = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
if ( empty( $filter ) ) {
// 'filter' is from the modal from the add media button.
$filter = filter_input( INPUT_GET, 'filter', FILTER_SANITIZE_STRING );
}
if ( $filter && in_array( $filter, Visualizer_Plugin::getChartTypes(), true ) ) {
$query_args['meta_query'] = array(
array(
'key' => Visualizer_Plugin::CF_CHART_TYPE,
'value' => $filter,
'compare' => '=',
),
);
}
$query = new WP_Query( $query_args );
$charts = array();
while ( $query->have_posts() ) {
$chart = $query->next_post();
$chart_data = $this->_getChartArray( $chart );
$chart_data['id'] = $chart->ID;
$chart_data['library'] = $this->load_chart_type( $chart->ID );
$css = '';
$settings = $chart_data['settings'];
$arguments = $this->get_inline_custom_css( 'visualizer-chart-' . $chart->ID, $settings );
if ( ! empty( $arguments ) ) {
$css = $arguments[0];
$settings = $arguments[1];
}
$chart_data['settings'] = $settings;
$chart_data['css'] = $css;
$charts[] = $chart_data;
}
self::_sendResponse(
array(
'success' => true,
'data' => $charts,
'total' => $query->max_num_pages,
)
);
}
/**
* Returns chart data required for rendering.
*
* @since 1.0.0
*
* @access private
*
* @param WP_Post $chart The chart object.
*
* @return array The array of chart data.
*/
private function _getChartArray( WP_Post $chart = null ) {
if ( is_null( $chart ) ) {
$chart = $this->_chart;
}
$type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
$series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
$data = self::get_chart_data( $chart, $type );
$library = $this->load_chart_type( $chart->ID );
$settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
$settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
if ( ! empty( $atts['settings'] ) ) {
$settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
}
$css = '';
$arguments = $this->get_inline_custom_css( 'visualizer-' . $chart->ID, $settings );
if ( ! empty( $arguments ) ) {
$css = $arguments[0];
$settings = $arguments[1];
}
$date_formats = Visualizer_Source::get_date_formats_if_exists( $series, $data );
return array(
'type' => $type,
'series' => $series,
'settings' => $settings,
'data' => $data,
'library' => $library,
'css' => $css,
'date_formats' => $date_formats,
);
}
/**
* Sends json response.
*
* @since 1.0.0
*
* @access private
*
* @param array $results The response array.
*/
public static function _sendResponse( $results ) {
header( 'Content-type: application/json' );
nocache_headers();
echo json_encode( $results );
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
}
/**
* Deletes a chart from database.
*
* @since 1.0.0
* @uses wp_delete_post() To delete a chart.
*
* @access public
*/
public function deleteChart() {
$is_post = $_SERVER['REQUEST_METHOD'] === 'POST';
$input_method = $is_post ? INPUT_POST : INPUT_GET;
$chart_id = $success = false;
$nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
$capable = current_user_can( 'delete_posts' );
if ( $nonce && $capable ) {
$chart_id = filter_input(
$input_method,
'chart',
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => 1,
),
)
);
if ( $chart_id ) {
$chart = get_post( $chart_id );
$success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
}
}
if ( $success ) {
global $sitepress;
if ( Visualizer_Module::is_pro() && ( function_exists( 'icl_get_languages' ) && $sitepress instanceof \SitePress ) ) {
$trid = $sitepress->get_element_trid( $chart_id, 'post_' . Visualizer_Plugin::CPT_VISUALIZER );
$translations = $sitepress->get_element_translations( $trid );
if ( ! empty( $translations ) ) {
foreach ( $translations as $translated_post ) {
wp_delete_post( $translated_post->element_id, true );
}
} else {
wp_delete_post( $chart_id, true );
}
} else {
wp_delete_post( $chart_id, true );
}
}
if ( $is_post ) {
self::_sendResponse(
array(
'success' => $success,
)
);
}
wp_redirect( remove_query_arg( 'vaction', wp_get_referer() ) );
exit;
}
/**
* Delete charts that are still in auto-draft mode.
*/
private function deleteOldCharts() {
$query = new WP_Query(
array(
'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
'post_status' => 'auto-draft',
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'posts_per_page' => 50,
'date_query' => array(
array(
'before' => 'today',
),
),
)
);
if ( $query->have_posts() ) {
$ids = array();
while ( $query->have_posts() ) {
wp_delete_post( $query->next_post(), true );
}
}
}
/**
* Renders appropriate page for chart builder. Creates new auto draft chart
* if no chart has been specified.
*
* @since 1.0.0
*
* @access public
*/
public function renderChartPages() {
defined( 'IFRAME_REQUEST' ) || define( 'IFRAME_REQUEST', 1 );
if ( ! defined( 'ET_BUILDER_PRODUCT_VERSION' ) && function_exists( 'et_get_theme_version' ) ) {
define( 'ET_BUILDER_PRODUCT_VERSION', et_get_theme_version() );
}
// Set current screen for the render chart.
set_current_screen( 'visualizer_render_chart' );
// check chart, if chart not exists, will create new one and redirects to the same page with proper chart id
$chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
if ( ! empty( $_POST ) ) {
$_POST = map_deep( $_POST, 'wp_strip_all_tags' );
}
if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
if ( empty( $_GET['lang'] ) || empty( $_GET['parent_chart_id'] ) ) {
$this->deleteOldCharts();
$default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
$chart_status = Visualizer_Module_Admin::checkChartStatus( $default_type );
if ( ! $chart_status ) {
$default_type = 'line';
}
$source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' );
$source->fetch();
$chart_id = wp_insert_post(
array(
'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
'post_title' => 'Visualization',
'post_author' => get_current_user_id(),
'post_status' => 'auto-draft',
'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
)
);
if ( $chart_id && ! is_wp_error( $chart_id ) ) {
add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, $default_type );
add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 );
add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
add_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_LIBRARY, '' );
add_post_meta(
$chart_id,
Visualizer_Plugin::CF_SETTINGS,
array(
'focusTarget' => 'datum',
)
);
do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
}
} else {
if ( current_user_can( 'edit_posts' ) ) {
$parent_chart_id = isset( $_GET['parent_chart_id'] ) ? filter_var( $_GET['parent_chart_id'], FILTER_VALIDATE_INT ) : '';
$success = false;
if ( $parent_chart_id ) {
$parent_chart = get_post( $parent_chart_id );
$success = $parent_chart && $parent_chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
}
if ( $success ) {
$new_chart_id = wp_insert_post(
array(
'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
'post_title' => 'Visualization',
'post_author' => get_current_user_id(),
'post_status' => $parent_chart->post_status,
'post_content' => $parent_chart->post_content,
)
);
if ( is_wp_error( $new_chart_id ) ) {
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__ );
} else {
$post_meta = get_post_meta( $parent_chart_id );
$chart_id = $new_chart_id;
foreach ( $post_meta as $key => $value ) {
if ( strpos( $key, 'visualizer-' ) !== false ) {
add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
}
}
}
}
}
do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
}
wp_redirect( esc_url_raw( add_query_arg( 'chart', (int) $chart_id ) ) );
if ( defined( 'WP_TESTS_DOMAIN' ) ) {
wp_die();
}
exit();
}
$_POST['save_chart_image'] = isset( $_POST['save_chart_image'] ) && 'yes' === $_POST['save_chart_image'] ? true : false;
$_POST['lazy_load_chart'] = isset( $_POST['lazy_load_chart'] ) && 'yes' === $_POST['lazy_load_chart'] ? true : false;
if ( isset( $_POST['chart-img'] ) && ! empty( $_POST['chart-img'] ) ) {
$attachment_id = $this->save_chart_image( $_POST['chart-img'], $chart_id, $_POST['save_chart_image'] );
if ( $attachment_id ) {
update_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, $attachment_id );
}
}
$lib = $this->load_chart_type( $chart_id );
// the alpha color picker (RGBA) is not supported by google.
$color_picker_dep = 'wp-color-picker';
if ( in_array( $lib, array( 'chartjs', 'datatables' ), true ) && ! wp_script_is( 'wp-color-picker-alpha', 'registered' ) ) {
wp_register_script( 'wp-color-picker-alpha', VISUALIZER_ABSURL . 'js/lib/wp-color-picker-alpha.min.js', array( 'wp-color-picker' ), Visualizer_Plugin::VERSION );
$color_picker_dep = 'wp-color-picker-alpha';
}
// enqueue and register scripts and styles
wp_register_script( 'visualizer-chosen', VISUALIZER_ABSURL . 'js/lib/chosen.jquery.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
wp_register_style( 'visualizer-chosen', VISUALIZER_ABSURL . 'css/lib/chosen.min.css', array(), Visualizer_Plugin::VERSION );
wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION );
wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen', 'jquery-ui-accordion', 'jquery-ui-tabs' ), Visualizer_Plugin::VERSION, true );
wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
wp_register_script(
'visualizer-render',
VISUALIZER_ABSURL . 'js/render-facade.js',
apply_filters( 'visualizer_assets_render', array( 'visualizer-frame', 'visualizer-customization' ), false ),
Visualizer_Plugin::VERSION,
true
);
wp_register_script(
'visualizer-preview',
VISUALIZER_ABSURL . 'js/preview.js',
array(
$color_picker_dep,
'visualizer-render',
),
Visualizer_Plugin::VERSION,
true
);
wp_register_script( 'visualizer-editor-simple', VISUALIZER_ABSURL . 'js/simple-editor.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
do_action( 'visualizer_add_scripts' );
if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
global $Visualizer_Pro;
$Visualizer_Pro->_addScriptsAndStyles();
}
// dispatch pages
$this->_chart = get_post( $chart_id );
$tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer';
// skip chart type pages only for existing charts.
if ( VISUALIZER_SKIP_CHART_TYPE_PAGE && 'auto-draft' !== $this->_chart->post_status && ( ! empty( $_GET['tab'] ) && 'visualizer' === $_GET['tab'] ) ) {
$tab = 'settings';
}
if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) {
// if the cancel button is clicked.
$this->undoRevisions( $chart_id, true );
} elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
$this->handlePermissions();
// if the save button is clicked.
$this->undoRevisions( $chart_id, false );
} else {
// if the edit button is clicked.
$this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart );
}
// Clear existing chart cache.
if ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) {
$cache_key = Visualizer_Plugin::CF_CHART_CACHE . '_' . $chart_id;
if ( get_transient( $cache_key ) ) {
delete_transient( $cache_key );
}
}
switch ( $tab ) {
case 'settings':
$this->_handleDataAndSettingsPage();
break;
case 'type': // fall through.
case 'visualizer': // fall through.
$this->_handleTypesPage();
break;
default:
// this should never happen.
break;
}
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
}
/**
* Load code editor assets.
*/
private function loadCodeEditorAssets( $chart_id ) {
global $wp_version;
$wp_scripts = wp_scripts();
// data tables assets.
wp_register_script( 'visualizer-datatables', VISUALIZER_ABSURL . 'js/lib/datatables.min.js', array( 'jquery-ui-core' ), Visualizer_Plugin::VERSION );
wp_register_style( 'visualizer-datatables', VISUALIZER_ABSURL . 'css/lib/datatables.min.css', array(), Visualizer_Plugin::VERSION );
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 );
wp_enqueue_script( 'visualizer-datatables' );
wp_enqueue_style( 'visualizer-jquery-ui' );
if ( ! Visualizer_Module::is_pro() ) {
return;
}
$table_col_mapping = Visualizer_Source_Query_Params::get_all_db_tables_column_mapping( $chart_id );
if ( version_compare( $wp_version, '4.9.0', '<' ) ) {
// code mirror assets.
wp_register_script( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.js', array( 'jquery' ), Visualizer_Plugin::VERSION );
wp_register_script( 'visualizer-codemirror-placeholder', '//codemirror.net/addon/display/placeholder.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
wp_register_script( 'visualizer-codemirror-matchbrackets', '//codemirror.net/addon/edit/matchbrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
wp_register_script( 'visualizer-codemirror-closebrackets', '//codemirror.net/addon/edit/closebrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
wp_register_script( 'visualizer-codemirror-sql', '//codemirror.net/mode/sql/sql.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
wp_register_script( 'visualizer-codemirror-sql-hint', '//codemirror.net/addon/hint/sql-hint.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
wp_register_script( 'visualizer-codemirror-hint', '//codemirror.net/addon/hint/show-hint.js', array( 'visualizer-codemirror-sql', 'visualizer-codemirror-sql-hint', 'visualizer-codemirror-placeholder', 'visualizer-codemirror-matchbrackets', 'visualizer-codemirror-closebrackets' ), Visualizer_Plugin::VERSION );
wp_register_style( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.css', array(), Visualizer_Plugin::VERSION );
wp_register_style( 'visualizer-codemirror-hint', '//codemirror.net/addon/hint/show-hint.css', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION );
wp_enqueue_script( 'visualizer-codemirror-hint' );
wp_enqueue_style( 'visualizer-codemirror-hint' );
} else {
wp_enqueue_code_editor(
array(
'type' => 'sql',
'codemirror' => array(
'autofocus' => true,
'lineWrapping' => true,
'dragDrop' => false,
'matchBrackets' => true,
'autoCloseBrackets' => true,
'extraKeys' => array( 'Shift-Space' => 'autocomplete' ),
'hintOptions' => array( 'tables' => $table_col_mapping ),
),
)
);
}
return $table_col_mapping;
}
/**
* Handle permissions from the new conslidated settings sidebar.
*/
private function handlePermissions() {
if ( ! Visualizer_Module::is_pro() ) {
return;
}
// we will not support old free and new pro.
// handling new free and old pro.
if ( has_action( 'visualizer_pro_handle_tab' ) ) {
do_action( 'visualizer_pro_handle_tab', 'permissions', $this->_chart );
} else {
do_action( 'visualizer_handle_permissions', $this->_chart );
}
}
/**
* Handle data and settings page
*/
private function _handleDataAndSettingsPage() {
if ( isset( $_POST['map_api_key'] ) ) {
update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
}
if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
$is_canceled = isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] );
$is_newly_created = $this->_chart->post_status === 'auto-draft';
if ( $is_newly_created && ! $is_canceled ) {
$this->_chart->post_status = 'publish';
// 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.
// we do not want any difference in data so disable revisions temporarily.
$this->disableRevisionsTemporarily();
wp_update_post( $this->_chart->to_array() );
}
// save meta data only when it is NOT being canceled.
if ( ! $is_canceled ) {
update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST );
// we will keep a parameter called 'internal_title' that will be set to the given title or, if empty, the chart ID
// this will help in searching with the chart id.
$settings = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
$title = null;
if ( isset( $settings['title'] ) && ! empty( $settings['title'] ) ) {
$title = $settings['title'];
if ( is_array( $title ) ) {
$title = $settings['title']['text'];
}
}
if ( empty( $title ) ) {
$title = $this->_chart->ID;
}
$settings['internal_title'] = $title;
$settings_label = isset( $settings['pieResidueSliceLabel'] ) ? $settings['pieResidueSliceLabel'] : '';
if ( empty( $settings_label ) ) {
$settings['pieResidueSliceLabel'] = esc_html__( 'Other', 'visualizer' );
} else {
$settings['pieResidueSliceLabel'] = $settings_label;
}
update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
}
$render = new Visualizer_Render_Page_Send();
$render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID );
wp_iframe( array( $render, 'render' ) );
return;
}
$data = $this->_getChartArray();
$sidebar = '';
$sidebar_class = $this->load_chart_class_name( $this->_chart->ID );
if ( class_exists( $sidebar_class, true ) ) {
$sidebar = new $sidebar_class( $data['settings'] );
$sidebar->__series = $data['series'];
$sidebar->__data = $data['data'];
} else {
$sidebar = apply_filters( 'visualizer_pro_chart_type_sidebar', '', $data );
if ( $sidebar !== '' ) {
$sidebar->__series = $data['series'];
$sidebar->__data = $data['data'];
}
}
unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_style( 'visualizer-frame' );
wp_enqueue_script( 'visualizer-preview' );
wp_enqueue_script( 'visualizer-chosen' );
wp_enqueue_script( 'visualizer-render' );
if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) {
wp_enqueue_script( 'visualizer-editor-simple' );
wp_localize_script(
'visualizer-editor-simple',
'visualizer1',
array(
'ajax' => array(
'url' => admin_url( 'admin-ajax.php' ),
'nonces' => array(
),
'actions' => array(
),
),
)
);
}
$table_col_mapping = $this->loadCodeEditorAssets( $this->_chart->ID );
wp_localize_script(
'visualizer-render',
'visualizer',
array(
'l10n' => array(
'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
'loading' => esc_html__( 'Loading...', 'visualizer' ),
'json_error' => esc_html__( 'An error occured in fetching data.', 'visualizer' ),
'select_columns' => esc_html__( 'Please select a few columns to include in the chart.', 'visualizer' ),
'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' ),
'copied' => __( 'The data has been copied to your clipboard. Hit Ctrl-V/Cmd-V in your spreadsheet editor to paste the data.', 'visualizer' ),
),
'charts' => array(
'canvas' => $data,
'id' => $this->_chart->ID,
),
'language' => $this->get_language(),
'map_api_key' => get_option( 'visualizer-map-api-key' ),
'ajax' => array(
'url' => admin_url( 'admin-ajax.php' ),
'nonces' => array(
'permissions' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA ),
'db_get_data' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION ),
'json_get_roots' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_GET_ROOTS . Visualizer_Plugin::VERSION ),
'json_get_data' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_GET_DATA . Visualizer_Plugin::VERSION ),
'json_set_schedule' => wp_create_nonce( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE . Visualizer_Plugin::VERSION ),
),
'actions' => array(
'permissions' => Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA,
'db_get_data' => Visualizer_Plugin::ACTION_FETCH_DB_DATA,
'json_get_roots' => Visualizer_Plugin::ACTION_JSON_GET_ROOTS,
'json_get_data' => Visualizer_Plugin::ACTION_JSON_GET_DATA,
'json_set_schedule' => Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE,
),
),
'db_query' => array(
'tables' => $table_col_mapping,
),
'is_pro' => Visualizer_Module::is_pro(),
'page_type' => 'chart',
'json_tag_separator' => Visualizer_Source_Json::TAG_SEPARATOR,
'json_tag_separator_view' => Visualizer_Source_Json::TAG_SEPARATOR_VIEW,
'is_front' => false,
'rest_base' => get_rest_url( null, 'wc/v3/reports/' ),
)
);
$render = new Visualizer_Render_Page_Data();
$render->chart = $this->_chart;
$render->type = $data['type'];
$render->custom_css = $data['css'];
$render->sidebar = $sidebar;
if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
$render->button = filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART
? esc_html__( 'Save Chart', 'visualizer' )
: esc_html__( 'Create Chart', 'visualizer' );
$render->cancel_button = esc_html__( 'Cancel', 'visualizer' );
} else {
$render->button = esc_attr__( 'Insert Chart', 'visualizer' );
}
do_action( 'visualizer_enqueue_scripts_and_styles', $data, $this->_chart->ID );
if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
global $Visualizer_Pro;
$Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
}
$this->_addAction( 'admin_head', 'renderFlattrScript' );
wp_iframe( array( $render, 'render' ) );
}
/**
* Handles chart type selection page.
*
* @since 1.0.0
*
* @access private
*/
private function _handleTypesPage() {
// process post request
if ( $_SERVER['REQUEST_METHOD'] === 'POST' && wp_verify_nonce( filter_input( INPUT_POST, 'nonce' ) ) ) {
$type = filter_input( INPUT_POST, 'type' );
$library = filter_input( INPUT_POST, 'chart-library' );
if ( Visualizer_Module_Admin::checkChartStatus( $type ) ) {
if ( empty( $library ) ) {
// library cannot be empty.
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, 'Chart library empty while creating the chart! Aborting...', 'error', __FILE__, __LINE__ );
return;
}
// save new chart type
update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, $type );
update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_LIBRARY, $library );
// if the chart has default data, update it with appropriate default data for new type
if ( filter_var( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, true ), FILTER_VALIDATE_BOOLEAN ) ) {
$source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $type . '.csv' );
$source->fetch();
$this->_chart->post_content = $source->getData( get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
wp_update_post( $this->_chart->to_array() );
update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
}
Visualizer_Module_Utility::set_defaults( $this->_chart );
// redirect to next tab
// changed by Ash/Upwork
wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );
return;
}
}
$render = new Visualizer_Render_Page_Types();
$render->type = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
$render->types = Visualizer_Module_Admin::_getChartTypesLocalized( false, false, false, 'types' );
$render->chart = $this->_chart;
wp_enqueue_style( 'visualizer-frame' );
wp_enqueue_script( 'visualizer-frame' );
wp_iframe( array( $render, 'render' ) );
}
/**
* Renders flattr script in the iframe <head>
*
* @since 1.4.2
* @action admin_head
*
* @access public
*/
public function renderFlattrScript() {
echo '';
}
/**
* Processes the CSV that is sent in the request as a string.
*
* @since 3.2.0
*/
private function handleCSVasString( $data, $editor_type ) {
$source = null;
switch ( $editor_type ) {
case 'text':
// data coming in from the text editor.
$tmpfile = tempnam( get_temp_dir(), Visualizer_Plugin::NAME );
$handle = fopen( $tmpfile, 'w' );
$values = preg_split( '/[\n\r]+/', stripslashes( trim( $data ) ) );
if ( $values ) {
foreach ( $values as $row ) {
if ( empty( $row ) ) {
continue;
}
$row = explode( ',', $row );
$row = array_map(
function( $r ) {
return '' === $r ? ' ' : $r;
},
$row
);
$row = implode( ',', $row );
// don't use fpucsv here because we need to just dump the data
// minus the empty rows
// because fputcsv needs to tokenize
// we can standardize the CSV enclosure here and replace all ' with "
// we can assume that if there are an even number of ' they should be changed to "
// but that will screw up words like fo'c'sle
// so here let's just assume ' will NOT be used for enclosures
fwrite( $handle, $row );
fwrite( $handle, PHP_EOL );
}
}
$source = new Visualizer_Source_Csv( $tmpfile );
fclose( $handle );
break;
case 'table':
// Import from Chart
// fall-through.
case 'excel':
// data coming in from the excel editor.
$source = apply_filters( 'visualizer_pro_handle_chart_data', $data, '' );
break;
}
return $source;
}
/**
* Parses the data uploaded as an HTML table.
*
* @since 3.2.0
*
* @access private
*/
private function handleTabularData() {
$csv = array();
// the datatable mentions the headers twice, so lets remove the duplicates.
$headers = array_unique( array_filter( $_POST['header'] ) );
$types = $_POST['type'];
// capture all the indexes that correspond to excluded columns.
$exclude = array();
$index = 0;
foreach ( $types as $type ) {
if ( empty( $type ) ) {
$exclude[] = $index;
}
$index++;
}
// when N headers are being renamed, the number of headers increases by N
// because of the way datatable duplicates header information
// so unset the headers that have been renamed.
if ( count( $headers ) !== count( $types ) ) {
$to = count( $headers );
for ( $i = count( $types ); $i < $to; $i++ ) {
unset( $headers[ $i + 1 ] );
}
}
$columns = array();
for ( $i = 0; $i < count( $headers ); $i++ ) {
if ( ! isset( $_POST[ 'data' . $i ] ) ) {
continue;
}
$columns[ $i ] = $_POST[ 'data' . $i ];
}
$csv[] = $headers;
$csv[] = $types;
for ( $j = 0; $j < count( $columns[0] ); $j++ ) {
$row = array();
for ( $i = 0; $i < count( $headers ); $i++ ) {
$row[] = sanitize_text_field( $columns[ $i ][ $j ] );
}
$csv[] = $row;
}
$tmpfile = tempnam( get_temp_dir(), Visualizer_Plugin::NAME );
$handle = fopen( $tmpfile, 'w' );
if ( $csv ) {
$index = 0;
foreach ( $csv as $row ) {
// remove all the cells corresponding to the excluded headers.
foreach ( $exclude as $j ) {
unset( $row[ $j ] );
}
fputcsv( $handle, $row );
}
}
$source = new Visualizer_Source_Csv( $tmpfile );
fclose( $handle );
return $source;
}
/**
* Parses uploaded CSV file and saves new data for the chart.
*
* @since 1.0.0
*
* @access public
*/
public function uploadData() {
// if this is being called internally from pro and VISUALIZER_DO_NOT_DIE is set.
// otherwise, assume this is a normal web request.
$can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE );
// validate nonce
if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) {
if ( ! $can_die ) {
return;
}
status_header( 403 );
exit;
}
// check chart, if chart exists
// do not use filter_input as it does not work for phpunit test cases, use filter_var instead
$chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
if ( ! $can_die ) {
return;
}
status_header( 400 );
exit;
}
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__ );
if ( ! isset( $_POST['vz-import-time'] ) ) {
apply_filters( 'visualizer_pro_remove_schedule', $chart_id );
}
if ( ! isset( $_POST['chart_data_src'] ) || Visualizer_Plugin::CF_SOURCE_FILTER !== $_POST['chart_data_src'] ) {
// delete the filters in case this chart is being uploaded from other data sources
delete_post_meta( $chart_id, Visualizer_Plugin::CF_FILTER_CONFIG );
delete_post_meta( $chart_id, '__transient-' . Visualizer_Plugin::CF_FILTER_CONFIG );
delete_post_meta( $chart_id, '__transient-' . Visualizer_Plugin::CF_DB_QUERY );
// delete "import from db" specific parameters.
delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY );
delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE );
delete_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS );
}
// delete json related data.
delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_URL );
delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_ROOT );
delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_PAGING );
delete_post_meta( $chart_id, Visualizer_Plugin::CF_JSON_HEADERS );
// delete last error
delete_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR );
// delete editor related data.
delete_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR );
// delete this so that a JSON import can be later edited manually without a problem.
delete_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE );
$source = null;
$render = new Visualizer_Render_Page_Update();
$remote_data = false;
if ( isset( $_POST['remote_data'] ) && function_exists( 'wp_http_validate_url' ) ) {
$remote_data = wp_http_validate_url( $_POST['remote_data'] );
}
if ( false !== $remote_data ) {
$source = new Visualizer_Source_Csv_Remote( $remote_data );
if ( isset( $_POST['vz-import-time'] ) ) {
apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $remote_data, $_POST['vz-import-time'] );
}
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
} elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) {
$source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] );
} elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) {
$source = $this->handleCSVasString( $_POST['chart_data'], $_POST['editor-type'] );
update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
} elseif ( isset( $_POST['table_data'] ) && 'yes' === $_POST['table_data'] ) {
$source = $this->handleTabularData();
update_post_meta( $chart_id, Visualizer_Plugin::CF_EDITOR, $_POST['editor-type'] );
} else {
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__ );
$render->message = esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' );
update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, esc_html__( 'CSV file with chart data was not uploaded. Please try again.', 'visualizer' ) );
}
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__ );
if ( $source ) {
if ( $source->fetch() ) {
$content = $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
$populate = true;
if ( is_string( $content ) && is_array( unserialize( $content ) ) ) {
$json = unserialize( $content );
// if source exists, so should data. if source exists but data is blank, do not populate the chart.
// if we populate the data even if it is empty, the chart will show "Table has no columns".
if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
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__ );
update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, sprintf( 'Not populating chart data as source exists (%s) but data is empty!', $json['source'] ) );
$populate = false;
}
}
if ( $populate ) {
$chart->post_content = $content;
}
wp_update_post( $chart->to_array() );
update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Updated post for chart %d', $chart_id ), 'debug', __FILE__, __LINE__ );
Visualizer_Module_Utility::set_defaults( $chart, null );
$settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
if ( isset( $settings['series'] ) && ! ( count( $settings['series'] ) - count( $source->getSeries() ) > 1 ) ) {
$diff_total_series = abs( count( $settings['series'] ) - count( $source->getSeries() ) );
if ( $diff_total_series ) {
foreach ( range( 1, $diff_total_series ) as $k => $diff_series ) {
$settings['series'][] = end( $settings['series'] );
}
update_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, $settings );
}
}
$render->id = $chart->ID;
$render->data = json_encode( $source->getRawData( get_post_meta( $chart->ID, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
$render->series = json_encode( $source->getSeries() );
$render->settings = json_encode( $settings );
} else {
$error = $source->get_error();
if ( empty( $error ) ) {
$error = esc_html__( 'CSV file is broken or invalid. Please try again.', 'visualizer' );
}
$render->message = $error;
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( '%s for chart %d.', $error, $chart_id ), 'error', __FILE__, __LINE__ );
update_post_meta( $chart_id, Visualizer_Plugin::CF_ERROR, $error );
}
} else {
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unknown internal error for chart %d.', $chart_id ), 'error', __FILE__, __LINE__ );
}
$render->render();
if ( ! $can_die ) {
return;
}
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
}
/**
* Clones the chart.
*
* @since 1.0.0
*
* @access public
*/
public function cloneChart() {
$chart_id = $success = false;
$nonce = isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], Visualizer_Plugin::ACTION_CLONE_CHART );
$capable = current_user_can( 'edit_posts' );
if ( $nonce && $capable ) {
$chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
if ( $chart_id ) {
$chart = get_post( $chart_id );
$success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
}
}
$redirect = remove_query_arg( 'vaction', wp_get_referer() );
if ( $success ) {
$new_chart_id = wp_insert_post(
array(
'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
'post_title' => 'Visualization',
'post_author' => get_current_user_id(),
'post_status' => $chart->post_status,
'post_content' => $chart->post_content,
)
);
if ( is_wp_error( $new_chart_id ) ) {
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__ );
} else {
$post_meta = get_post_meta( $chart_id );
foreach ( $post_meta as $key => $value ) {
if ( strpos( $key, 'visualizer-' ) !== false ) {
add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
}
}
$redirect = esc_url(
add_query_arg(
array(
'page' => 'visualizer',
'type' => filter_input( INPUT_GET, 'type' ),
'vaction' => false,
),
admin_url( 'admin.php' )
),
null,
'db'
);
}
}
if ( defined( 'WP_TESTS_DOMAIN' ) ) {
wp_die();
}
wp_redirect( $redirect );
exit;
}
/**
* Exports the chart data
*
* @since 1.0.0
*
* @access public
*/
public function exportData() {
check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
$capable = current_user_can( 'edit_posts' );
if ( $capable ) {
$chart_id = isset( $_GET['chart'] ) ? filter_var(
$_GET['chart'],
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => 1,
),
)
) : '';
if ( $chart_id ) {
$data = $this->_getDataAs( $chart_id, 'csv' );
if ( $data ) {
echo wp_send_json_success( $data );
}
}
}
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
}
/**
* Handles chart data page.
*
* @since 1.0.0
*
* @access private
*/
private function _handleDataPage() {
$data = $this->_getChartArray();
$render = new Visualizer_Render_Page_Data();
$render->chart = $this->_chart;
$render->type = $data['type'];
if ( $data && $data['settings'] ) {
unset( $data['settings']['width'], $data['settings']['height'], $data['settings']['chartArea'] );
}
wp_enqueue_style( 'visualizer-frame' );
wp_enqueue_script( 'visualizer-render' );
wp_localize_script(
'visualizer-render',
'visualizer',
array(
'l10n' => array(
'invalid_source' => esc_html__( 'You have entered an invalid URL. Please provide a valid URL.', 'visualizer' ),
'loading' => esc_html__( 'Loading...', 'visualizer' ),
),
'charts' => array(
'canvas' => $data,
),
)
);
do_action( 'visualizer_enqueue_scripts_and_styles', $data, $this->_chart->ID );
if ( Visualizer_Module::is_pro() && Visualizer_Module::is_pro_older_than( '1.9.0' ) ) {
global $Visualizer_Pro;
$Visualizer_Pro->_enqueueScriptsAndStyles( $data, $this->_chart->ID );
}
// Added by Ash/Upwork
$this->_addAction( 'admin_head', 'renderFlattrScript' );
wp_iframe( array( $render, 'render' ) );
}
/**
* Returns the data for the query.
*
* @access public
*/
public function getQueryData() {
check_ajax_referer( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION, 'security' );
if ( ! current_user_can( 'administrator' ) ) {
wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
}
if ( ! is_super_admin() ) {
wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
}
if ( ! Visualizer_Module::is_pro() ) {
wp_send_json_error( array( 'msg' => __( 'Feature is not available.', 'visualizer' ) ) );
}
$params = wp_parse_args( $_POST['params'] );
$chart_id = filter_var( $params['chart_id'], FILTER_VALIDATE_INT );
$query = trim( $params['query'], ';' );
$source = new Visualizer_Source_Query( stripslashes( $query ), $chart_id, $params );
$html = $source->fetch( true );
$error = $source->get_error();
if ( ! empty( $error ) ) {
wp_send_json_error( array( 'msg' => $error ) );
}
wp_send_json_success( array( 'table' => $html ) );
}
/**
* Saves the query and the schedule.
*
* @access public
*/
public function saveQuery() {
check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION, 'security' );
if ( ! current_user_can( 'administrator' ) ) {
wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
}
if ( ! is_super_admin() ) {
wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
}
if ( ! Visualizer_Module::is_pro() ) {
wp_send_json_error( array( 'msg' => __( 'Feature is not available.', 'visualizer' ) ) );
}
$chart_id = filter_input(
INPUT_GET,
'chart',
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => 1,
),
)
);
$hours = filter_input(
INPUT_POST,
'refresh',
FILTER_VALIDATE_FLOAT,
array(
'options' => array(
'min_range' => -1,
'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
),
)
);
if ( ! is_numeric( $hours ) ) {
$hours = -1;
}
$render = new Visualizer_Render_Page_Update();
if ( $chart_id ) {
$params = wp_parse_args( $_POST['params'] );
$query = trim( $params['query'], ';' );
$source = new Visualizer_Source_Query( stripslashes( $query ), $chart_id, $params );
$source->fetch( false );
$error = $source->get_error();
if ( empty( $error ) ) {
update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, stripslashes( $query ) );
update_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() );
update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() );
update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, $hours );
update_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 0 );
if ( isset( $params['db_type'] ) && $params['db_type'] !== Visualizer_Plugin::WP_DB_NAME ) {
$remote_db_params = $params;
unset( $remote_db_params['query'] );
unset( $remote_db_params['chart_id'] );
update_post_meta( $chart_id, Visualizer_Plugin::CF_REMOTE_DB_PARAMS, $remote_db_params );
}
$schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() );
$schedules[ $chart_id ] = time() + $hours * HOUR_IN_SECONDS;
update_option( Visualizer_Plugin::CF_DB_SCHEDULE, $schedules );
wp_update_post(
array(
'ID' => $chart_id,
'post_content' => $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ),
)
);
$render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
$render->series = json_encode( $source->getSeries() );
$render->id = $chart_id;
} else {
$render->message = $error;
}
}
$render->render();
if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
}
}
/**
* Saves the filter query and the schedule.
*
* @access public
*/
public function saveFilter() {
check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY . Visualizer_Plugin::VERSION, 'security' );
$chart_id = filter_input(
INPUT_GET,
'chart',
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => 1,
),
)
);
$hours = filter_input(
INPUT_POST,
'refresh',
FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => -1,
'max_range' => apply_filters( 'visualizer_is_business', false ) ? PHP_INT_MAX : -1,
),
)
);
if ( 0 !== $hours && empty( $hours ) ) {
$hours = -1;
}
do_action( 'visualizer_save_filter', $chart_id, $hours );
if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
}
}
/**
* Save chart image.
*
* @param string $base64_img Chart image.
* @param int $chart_id Chart ID.
* @param bool $save_attachment Save attachment.
* @return attachment ID
*/
public function save_chart_image( $base64_img, $chart_id, $save_attachment = true ) {
// Delete old chart image.
$old_attachment_id = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, true );
if ( $old_attachment_id ) {
wp_delete_attachment( $old_attachment_id, true );
}
if ( ! $save_attachment ) {
return 0;
}
// Upload dir.
$upload_dir = wp_upload_dir();
$upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
$img = str_replace( 'data:image/png;base64,', '', $base64_img );
$img = str_replace( ' ', '+', $img );
$decoded = base64_decode( $img );
$filename = 'visualization-' . $chart_id . '.png';
$file_type = 'image/png';
$hashed_filename = $filename;
// Save the image in the uploads directory.
require_once ABSPATH . '/wp-admin/includes/file.php';
\WP_Filesystem();
global $wp_filesystem;
if ( ! is_a( $wp_filesystem, 'WP_Filesystem_Base' ) ) {
$creds = request_filesystem_credentials( site_url() );
wp_filesystem( $creds );
}
$upload_file = $wp_filesystem->put_contents( $upload_path . $hashed_filename, $decoded );
// Insert new chart image.
$attachment = array(
'post_mime_type' => $file_type,
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $hashed_filename ) ),
'post_content' => '',
'post_status' => 'inherit',
'guid' => $upload_dir['url'] . '/' . basename( $hashed_filename ),
);
$attach_id = wp_insert_attachment( $attachment, $upload_dir['path'] . '/' . $hashed_filename );
return $attach_id;
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists