File: /var/www/html/wp-content/plugins/chart-builder/includes/class-chart-builder-actions.php
<?php
if( ! class_exists( 'Chart_Builder_Actions' ) ){
/**
* Class Chart_Builder_Actions
* Class contains chart data filtering and hooks related to chart
*
* Main functionality belong to chart source and source type
* Also chart settings and options
*
* Hooks used in the class
*
* @hooks @actions ays_chart_get_chart_data
*
* @filters ays_chart_source_type
* ays_chart_source
* ays_chart_source_{source_type}
* ays_chart_get_settings
* ays_chart_get_options
* ays_chart_get_title
* ays_chart_get_type
* ays_chart_get_status
*
* @param $plugin_name
*
* @since 1.0.0
* @package Chart_Builder
* @subpackage Chart_Builder/includes
* @author Chart Builder Team <info@ays-pro.com>
*/
class Chart_Builder_Actions {
/**
* The ID of this plugin.
*
* @since 1.0.0
* @access private
* @var string $plugin_name The ID of this plugin.
*/
private $plugin_name;
/**
* The object of the database.
*
* @since 1.0.0
* @access private
* @var string $db_obj The database object of the chart.
*/
private $db_obj;
/**
* The constructor of the class
*
* @since 1.0.0
*
* @param $plugin_name
*/
public function __construct( $plugin_name ) {
/**
* Assigning $plugin_name to the @plugin_name property
*/
$this->plugin_name = $plugin_name;
/**
* Assigning database object to the @db_obj property
*
* Creating instance of Chart_Builder_DB_Actions class
*/
$this->db_obj = new Chart_Builder_DB_Actions( $this->plugin_name );
}
/**
* Get instance of this class
*
* @since 1.0.0
* @access public
*
* @param $plugin_name
*
* @return Chart_Builder_Actions
*/
public static function get_instance( $plugin_name ){
return new self( $plugin_name );
}
/**
* Get chart data by id
*
* @since 1.0.0
* @access public
*
* @param $id
*
* @return null|non-empty-array
*/
public function get_chart_data( $id ){
/**
* Checking if given valid @id
*
* @return null if not valid
*/
if( is_null( $id ) || intval( $id ) === 0 ){
return null;
}
/**
* Retrieving chart row from database
*
* Passing @id as a parameter
*/
$chart = $this->db_obj->get_item( $id );
if ( !$chart ) {
return null;
}
/**
* Validate chart general data by calling validation function
*
* Function must @return array
*/
$chart = $this->validate_item_data( $chart );
/**
* Getting source chart type from @chart object
*/
$source_chart_type = $chart['source_chart_type'];
$source_chart_type = apply_filters( 'ays_chart_source_chart_type', $source_chart_type );
/**
* Getting source type from @chart object
*/
$source_type = $chart['source_type'];
/**
* Applying filter to source type for development purposes
*
* @accept manual, custom, etc.
*/
$source_type = apply_filters( 'ays_chart_source_type', $source_type );
/**
* Getting source from @chart object
*/
$source = $chart['source'];
/**
* Getting chart author id
*/
$author_id = $chart['author_id'];
/**
* Defining filter function name that will filter source data
*/
$filter_function = 'chart_data_' . $source_type;
/**
* Calling filter function
*
* Before calling checking if the function exists and is callable
*
* Passing @source as a parameter
* Expecting an array which must be returned after filter
*/
$source_type_data = array();
if( method_exists( $this , $filter_function ) && is_callable( array( $this, $filter_function ) ) ) {
$source_type_data = $this->$filter_function( $source, $id );
}
/**
* Checking that returning data was array
*/
if( ! is_array( $source_type_data ) ){
$source_type_data = array();
}
/**
* Checking availability of data in the returned value from filter function
*/
if( empty( $source_type_data ) ){
$source_type_data = array();
}
/**
* Final source after validations and filters
* And final filter that applies to the source for giving access to change the data after all
*
* Applying filter to @source for development purposes
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* Please don't use this filter often when you need to change the source
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
$final_source = apply_filters( 'ays_chart_source', $source_type_data, $source_type );
/**
* Getting @settings data from database by calling get_metadata function from db object
*
* get_metadata function must return an array that contains chart @settings
*/
$chart_settings = $this->db_obj->get_metadata( $id );
/**
* Settings mustn't be empty or not array type data
* So checking is array and not empty
*
* If validation not passed assigning empty array
*/
if( ! is_array( $chart_settings ) || empty( $chart_settings ) ){
$chart_settings = array();
}
/**
* Converting @settings data to usable format
*
* convert_metadata function must return an array that contains formatted chart @settings
*/
$chart_settings = $this->db_obj->convert_metadata( $chart_settings );
/**
* Applying defaults to @settings
*
* apply_default_metadata function must return an array
* Expecting @settings with default values applied
*/
$chart_settings = $this->db_obj->apply_default_metadata( $chart_settings );
/**
* Applying filter to @settings data for development purposes
*/
$chart_settings = apply_filters( 'ays_chart_get_settings', $chart_settings );
/**
* Getting @options from @chart object
*/
$chart_options = $chart['options'];
/**
* After getting @options from @chart object
*/
unset( $chart['options'] );
/**
* Applying filter to @options for development purposes
*/
$chart_options = apply_filters( 'ays_chart_get_options', $chart_options );
/**
* Getting quiz data
*/
$quiz_query = $chart['quiz_query'];
$quiz_id = $chart['quiz_id'];
/**
* Collecting chart whole data into one variable
*
* @array $chart_data
*/
$chart_data = array(
'chart' => $chart,
'author_id' => $author_id,
'source_chart_type' => $source_chart_type,
'source_type' => $source_type,
'source' => $final_source,
'settings' => $chart_settings,
'options' => $chart_options,
'quiz_query' => $quiz_query,
'quiz_id' => $quiz_id,
);
/**
* Action for get chart data function
*/
do_action( 'ays_chart_get_chart_data', $chart_data );
/**
* Returning chart whole data
*
* @return $chart_data
*/
return $chart_data;
}
/**
* Chart data type manual
* Validating the data and returning validated array
*
* Returning applied filter to array for development purposes
*
* @since 1.0.0
* @access protected
*
* @accept JSON, empty string
* @param $source
*
* @return array
*/
protected function chart_data_manual( $source, $chart_id ){
/**
* Defining an empty array that will return after validation
*/
$filtered_data = array();
/**
* @source mustn't be empty or not string type data
* So checking is string and not empty
*
* If validation not passed function will return an empty array
*/
if( is_string( $source ) && trim( $source ) !== '' ){
/**
* Data are expected to be of type JSON
* Trying to parse the data
*/
$decoded_data = json_decode( $source, true );
/**
* @decoded_data mustn't be empty or not array type data
* So checking is array and not empty
*/
if( is_array( $decoded_data ) && ! empty( $decoded_data ) ){
/**
* Assigning parsed data to the @filtered_data variable
*/
$filtered_data = $decoded_data;
}
}
/**
* Returning the data that has passed the validation
* Returning applied filter to array for development purposes
*
* @return array
*/
return apply_filters( 'ays_chart_source_manual', $filtered_data );
}
/**
* Chart data type quiz_maker
* Validating the data and returning validated array
*
* Returning applied filter to array for development purposes
*
* @since 1.0.0
* @access protected
*
* @accept JSON, empty string
* @param $source
*
* @return array
*/
protected function chart_data_quiz_maker( $source, $chart_id ){
/**
* Defining an empty array that will return after validation
*/
$filtered_data = array();
/**
* @source mustn't be empty or not string type data
* So checking is string and not empty
*
* If validation not passed function will return an empty array
*/
if( is_string( $source ) && trim( $source ) !== '' ){
/**
* Data are expected to be of type array
* Trying to parse the data
*/
// $quiz_maker_data_option_name = 'ays_chart_quiz_maker_results_' . $chart_id;
// $quiz_maker_data = get_option( $quiz_maker_data_option_name, array() );
// $decoded_data = isset( $quiz_maker_data['source'] ) && $quiz_maker_data['source'] !== '' ? $quiz_maker_data['source'] : '';
$quiz_maker_data_option_name = 'ays_chart_quiz_maker_quiz_data_' . $chart_id;
$quiz_query_data = get_option( $quiz_maker_data_option_name );
$quiz_query = isset( $quiz_query_data['quiz_query'] ) && $quiz_query_data['quiz_query'] !== '' ? $quiz_query_data['quiz_query'] : '';
/**
* @quiz_query mustn't be empty or not array type data
* So checking is array and not empty
*/
if( $quiz_query !== '' ){
$quiz_id = isset( $quiz_query_data['quiz_id'] ) && $quiz_query_data['quiz_id'] !== '' ? $quiz_query_data['quiz_id'] : 0;
$return_results = CBFunctions()->get_quiz_query( $quiz_query, $quiz_id, get_current_user_id() );
$result_values = $return_results['result'];
$results = array();
if ( !empty($result_values) ) {
if (count($return_results['result'][0]) != 1 ) {
$results = array();
$headers = array();
if ( $result_values ) {
$row_num = 0;
foreach ( $result_values as $row ) {
$result = array();
$col_num = 0;
foreach ( $row as $k => $v ) {
$result[] = $v;
if ( $row_num === 0 ) {
$headers[] = $k;
}
}
$results[] = $result;
$row_num++;
}
}
} else if (count($return_results['result'][0]) == 1) {
$results = array();
$headers = array();
if ( $result_values ) {
$row_num = 0;
foreach ( $result_values as $index => $row ) {
$result = array();
foreach ( $row as $k => $v ) {
$result[] = strval($index) + 1;
$result[] = $v;
if ( $row_num === 0 ) {
$headers[] = 'Quiz';
$headers[] = $k;
}
}
$results[] = $result;
$row_num++;
}
}
}
array_unshift($results, $headers);
}
$filtered_data = $results;
}
}
/**
* Returning the data that has passed the validation
* Returning applied filter to array for development purposes
*
* @return array
*/
return apply_filters( 'ays_chart_source_quiz_maker', $filtered_data );
}
/**
* Chart data type custom
* For developers
* Returning data must be an array
*
* @since 1.0.0
* @access protected
*
* @accept mixed
* @param $source
*
* @return array
*/
protected function chart_data_custom( $source, $chart_id ){
/**
* Getting the data that will some developers pass via this filter
*/
$filtered_data = apply_filters( 'ays_chart_source_custom', array(), $chart_id );
/**
* Checking that returning data was array
*/
if( ! is_array( $filtered_data ) ){
return array();
}
/**
* Checking availability of data in array
*/
if( empty( $filtered_data ) ){
return array();
}
/**
* Returning the data that has passed the validation
*
* @return array
*/
return $filtered_data;
}
/**
* Validation function for chart general data
*
* Validating title, description, type, status, etc.
*
* @since 1.0.0
* @access protected
*
* @param $chart
*
* @return array
*/
protected function validate_item_data( $chart ){
/**
* @chart mustn't be empty or not array type data
* So checking is array and not empty
*
* If validation not passed returning an empty array
*/
if( ! is_array( $chart ) || empty( $chart ) ){
return array();
}
/**
* Defining an empty array that will return after validation
*
* During validation array will be filled with valid data
*/
$chart_data = array();
/**
* Validating the @title
*
* Title mustn't be empty
*
* Applying esc_html filtering function to escape HTML from the title
* Then applying filter to @title for development purposes
*
* @default "Chart example"
*/
$chart_title = __( 'Chart example', "chart-builder" );
if( isset( $chart['title'] ) && $chart['title'] !== '' ) {
$chart_title = esc_html( $chart['title'] );
}
$chart_data['title'] = apply_filters( 'ays_chart_get_title', $chart_title );
/**
* Validating the @description
*
* Description is optional, so it can be empty
* Applying stripslashes function to escape unnecessary slashes
*
* @default empty string
*/
$chart_data['description'] = '';
if( isset( $chart['description'] ) && $chart['description'] !== '' ){
$chart_data['description'] = stripslashes( $chart['description'] );
}
/**
* Validating the @author_id
*/
$chart_data['author_id'] = ( isset( $chart['author_id'] ) && $chart['author_id'] !== '' ) ? esc_html( intval($chart['author_id']) ) : get_current_user_id();
/**
* Validating the @type
*
* Type is required, it can't be empty
* Applying esc_html filtering function to escape HTML from the type
*
* Then applying filter to @type for development purposes
*
* @accept values are google-charts, etc.
* @default google-charts
*/
$chart_type = 'google-charts';
if( isset( $chart['type'] ) && $chart['type'] !== '' ){
$chart_type = esc_html( $chart['type'] );
}
$chart_data['type'] = apply_filters( 'ays_chart_get_type', $chart_type );
/**
* Validating the @source_chart_type
*
* Source chart type is required, it can't be empty
* Applying esc_html filtering function to escape HTML from the @source_type
*
* @accept values are manual, file, WordPress, database, etc.
* @default manual
*/
$chart_data['source_chart_type'] = ( isset( $chart['source_chart_type'] ) && $chart['source_chart_type'] !== '' ) ? esc_html( $chart['source_chart_type'] ) : 'pie_chart';
/**
* Validating the @source_type
*
* Source type is required, it can't be empty
* Applying esc_html filtering function to escape HTML from the @source_type
*
* @accept values are manual, file, WordPress, database, etc.
* @default manual
*/
$chart_data['source_type'] = 'manual';
if( isset( $chart['source_type'] ) && $chart['source_type'] !== '' ){
$chart_data['source_type'] = esc_html( $chart['source_type'] );
}
$chart_data['quiz_query'] = isset($chart['quiz_query']) && $chart['quiz_query'] != '' ? sanitize_text_field($chart['quiz_query']) : '';
$chart_data['quiz_id'] = isset( $chart['quiz_id'] ) && $chart['quiz_id'] != '' ? intval( $chart['quiz_id'] ) : 0;
/**
* Validating the @source
*
* Source is required, but it can be empty
* Applying esc_html filtering function to escape HTML from the @source
*
* @accept values are JSON, CSV, serialized data, etc.
* @default empty string
*/
$chart_data['source'] = '';
if( isset( $chart['source'] ) && $chart['source'] !== '' ){
$chart_data['source'] = $chart['source'] ;
}
/**
* Validating the @status
*
* Status is required, it can't be empty
* Applying esc_html filtering function to escape HTML from the @status
*
* Then applying filter to type for development purposes
*
* @accept values are published and draft
* @default draft
*/
$chart_status = 'draft';
if( isset( $chart['status'] ) && $chart['status'] !== '' ){
$chart_status = esc_html( $chart['status'] );
}
$chart_data['status'] = apply_filters( 'ays_chart_get_status', $chart_status );
/**
* Validating the @options
* Options is optional, it can be empty
*
* @accept JSON
* @default empty string
* @return array
*/
$chart_data['options'] = array();
if( isset( $chart['options'] ) && $chart['options'] !== '' ){
/**
* Data are expected to be of type JSON
* Trying to parse the data
*/
$chart_options = json_decode( $chart['options'], true );
/**
* Options mustn't be empty or not array type data
* So checking is array and not empty
*
* If validation not passed assigning empty array
*/
if( ! is_array( $chart_options ) || empty( $chart_options ) ){
$chart_options = array();
}
/**
* Pushing the result to the returning variable
*/
$chart_data['options'] = $chart_options;
}
/**
* Returning validated data
* Returning an array
*
* @return array
*/
return $chart_data;
}
/**
* Returns default array for google charts
*/
public function get_charts_default_data_google(){
return array(
"commonTypeCharts" => array(
'0' => array(
'Country',
'Population',
),
'1' => array(
'United States',
'189',
),
'2' => array(
'China',
'43',
),
'3' => array(
'Egypt',
'256',
),
'4' => array(
'France',
'123',
),
'5' => array(
'Australia',
'88',
)
),
"orgTypeChart" => array(
'0' => array(
'Name',
'Description',
'Image',
'Parent name',
'Tooltip',
'Url',
'Parent id',
'Level'
),
'1' => array(
'Mike',
'President',
'',
'',
'The President',
'',
'',
'1'
),
'2' => array(
'Jim',
'Vice President',
'',
'Mike',
'VP',
'',
'1',
'2'
),
'3' => array(
'Bob',
'',
'',
'Jim',
'Bob Sponge',
'',
'2',
'3'
),
'4' => array(
'Carol',
'',
'',
'Bob',
'',
'',
'3',
'4'
),
'5' => array(
'Alice',
'',
'',
'Mike',
'',
'',
'1',
'2'
),
)
);
}
/**
* Returns default array for chart.js charts
*/
public function get_charts_default_data_chartjs(){
return array(
'0' => array(
'Country',
'Population'
),
'1' => array(
'United States',
'189'
),
'2' => array(
'China',
'43'
),
'3' => array(
'Egypt',
'256'
),
'4' => array(
'France',
'123'
),
'5' => array(
'Australia',
'88'
)
);
}
public function get_charts($ordering = ''){
global $wpdb;
$charts_table = esc_sql( $wpdb->prefix . CHART_BUILDER_DB_PREFIX ) . "charts";
$sql = "SELECT id, title FROM {$charts_table} WHERE `status` IN (%s, %s)";
$params = array('published', 'draft');
if ( $ordering != '' ) {
$sql .= " ORDER BY id {$ordering}";
}
// phpcs:ignore
$charts = $wpdb->get_results( $wpdb->prepare( $sql, ...$params ), 'ARRAY_A' );
return $charts;
}
}
}
if( ! function_exists( 'CBActions' ) ){
/**
* Function for quick access to Chart_Builder_Actions class
*
* @since 1.0.0
* @return Chart_Builder_Actions
*/
function CBActions(){
static $instance = null;
if( $instance === null ){
$instance = Chart_Builder_Actions::get_instance( CHART_BUILDER_NAME );
}
if( $instance instanceof Chart_Builder_Actions ){
return $instance;
}
return Chart_Builder_Actions::get_instance( CHART_BUILDER_NAME );
}
}