_plugin_constants = $dependencies[ 'ASS_Constants' ];
}
/**
* Ensure that only one instance of ASS_Survey_Report is loaded or can be loaded (Singleton Pattern).
*
* @since 1.0.0
* @access public
*
* @param array $dependencies Array of instance objects of all dependencies of ASS_Survey_Report model.
* @return ASS_Survey_Report
*/
public static function instance( $dependencies ) {
if ( !self::$_instance instanceof self )
self::$_instance = new self( $dependencies );
return self::$_instance;
}
/**
* Integrate after sale survey's plugin reporting to WooCommerce reports.
*
* @since 1.0.0
* @access public
*
* @param $reports
* @return mixed
*/
public function after_sale_survey_report( $reports ) {
$report_sections = array(
"general" => array(
'title' => __( 'General' , 'after-sale-surveys' ),
'description' => '',
'hide_title' => true,
'callback' => array( $this , 'render_general_report' )
)
);
$report_sections = apply_filters( 'as_survey_report_sections' , $report_sections );
$reports[ 'as_survey_responses' ] = array(
'title' => __( 'Survey Responses' , 'after-sale-surveys' ),
'reports' => $report_sections
);
return $reports;
}
/*
|--------------------------------------------------------------------------
| Views
|--------------------------------------------------------------------------
*/
/**
* Render the general report.
*
* @since 1.0.0
* @access public
*/
public function render_general_report() {
$surveys = ASS_Helper::get_all_surveys( apply_filters( 'as_survey_surveys_to_view_report' , 1 ) );
include_once ( $this->_plugin_constants->VIEWS_ROOT_PATH() . 'survey/report/survey-general-report.php' );
}
/*
|--------------------------------------------------------------------------
| Record Survey Stats
|--------------------------------------------------------------------------
*/
/**
* Record an attempt to offer the survey to a customer. Survey CTA is shown.
*
* @since 1.0.1
* @since 1.1.0 Records data to plugin custom table.
* @access public
*
* @param int $survey_id Survey Id.
* @param int $order_id Order Id that triggered the survey.
* @return int ID of last entry.
*/
public function record_survey_offer_attempt( $survey_id , $order_id ) {
global $wpdb;
if ( $wpdb->get_var( "SHOW TABLES LIKE '" . $this->_plugin_constants->CUSTOM_TABLE_SURVEY_OFFER_ATTEMPTS() . "'" ) ) {
$current_user = wp_get_current_user();
$wpdb->insert(
$this->_plugin_constants->CUSTOM_TABLE_SURVEY_OFFER_ATTEMPTS(),
array(
'survey_id' => $survey_id,
'customer_email' => $current_user->ID ? $current_user->user_email : '',
'record_datetime' => current_time( 'mysql' ),
'order_id' => $order_id,
'client_ip' => ASS_Helper::get_client_ip(),
'user_agent' => $_SERVER[ 'HTTP_USER_AGENT' ]
)
);
return $wpdb->insert_id; // Latest id inserted. Auto-increment field.
} else
return new WP_Error( 'as-survey-record_survey_offer_attempt-missing-survey-offer-attempts-table' , __( "Missing required plugin table for survey offer attempts." , "after-sale-surveys" ) , array( 'survey_id' => $survey_id , 'order_id' => $order_id ) );
}
/**
* Record survey uptake event. The customer accepted to participate the survey so the survey questions are then shown.
*
* @since 1.0.1
* @since 1.1.0 Records data to plugin custom table.
* @access public
*
* @param int $survey_id Survey Id.
* @param int $order_id Order Id that triggered the survey.
* @return int ID of last entry.
*/
public function record_survey_uptake( $survey_id , $order_id ) {
global $wpdb;
if ( $wpdb->get_var( "SHOW TABLES LIKE '" . $this->_plugin_constants->CUSTOM_TABLE_SURVEY_UPTAKES() . "'" ) ) {
$current_user = wp_get_current_user();
$wpdb->insert(
$this->_plugin_constants->CUSTOM_TABLE_SURVEY_UPTAKES(),
array(
'survey_id' => $survey_id,
'customer_email' => $current_user->ID ? $current_user->user_email : '',
'record_datetime' => current_time( 'mysql' ),
'order_id' => $order_id,
'client_ip' => ASS_Helper::get_client_ip(),
'user_agent' => $_SERVER[ 'HTTP_USER_AGENT' ]
)
);
return $wpdb->insert_id; // Latest id inserted. Auto-increment field.
} else
return new WP_Error( 'as-survey-record_survey_uptake-missing-survey-offer-uptake-table' , __( "Missing required plugin table for survey uptakes." , "after-sale-surveys" ) , array( 'survey_id' => $survey_id , 'order_id' => $order_id ) );
}
/**
* Record survey completion. The customer completed the survey.
*
* @since 1.0.1
* @since 1.1.0 Records data to plugin custom table.
* @access public
*
* @param int $survey_id Survey Id.
* @param int $order_id Order Id that triggered the survey.
* @param int $response_id Response Id.
* @return int ID of last entry.
*/
public function record_survey_completion( $survey_id , $order_id , $response_id ) {
global $wpdb;
if ( $wpdb->get_var( "SHOW TABLES LIKE '" . $this->_plugin_constants->CUSTOM_TABLE_SURVEY_COMPLETIONS() . "'" ) ) {
$current_user = wp_get_current_user();
$wpdb->insert(
$this->_plugin_constants->CUSTOM_TABLE_SURVEY_COMPLETIONS(),
array(
'survey_id' => $survey_id,
'customer_email' => $current_user->ID ? $current_user->user_email : '',
'record_datetime' => current_time( 'mysql' ),
'order_id' => $order_id,
'response_id' => $response_id,
'client_ip' => ASS_Helper::get_client_ip(),
'user_agent' => $_SERVER[ 'HTTP_USER_AGENT' ]
)
);
return $wpdb->insert_id; // Latest id inserted. Auto-increment field.
} else
return new WP_Error( 'as-survey-record_survey_completion-missing-survey-offer-uptake-table' , __( "Missing required plugin table for survey completions." , "after-sale-surveys" ) , array( 'survey_id' => $survey_id , 'order_id' => $order_id , 'response_id' => $response_id ) );
}
/*
|--------------------------------------------------------------------------
| AJAX Interfaces
|--------------------------------------------------------------------------
*/
/**
* Get survey response report data.
*
* @since 1.0.0
* @access public
*
* @param null $survey_id
* @param null $filters
* @param bool|true $ajax_call
* @return array
*/
public function as_survey_get_survey_responses_report( $survey_id = null , $filters = null , $ajax_call = true ) {
if ( $ajax_call === true ) {
$survey_id = $_POST[ 'survey_id' ];
$filters = $_POST[ 'filters' ];
}
if ( get_post_status( $survey_id ) === false ) {
$response = array(
'status' => 'fail',
'error_message' => __( 'Specified survey does not exist' , 'after-sale-surveys' )
);
} elseif ( get_post_type( $survey_id ) != $this->_plugin_constants->SURVEY_CPT_NAME() ) {
$response = array(
'status' => 'fail',
'error_message' => __( 'Specified survey id does not represent a survey post type' , 'after-sale-surveys' )
);
} else {
$survey_questions = get_post_meta( $survey_id , $this->_plugin_constants->POST_META_SURVEY_QUESTIONS() , true );
if ( !is_array( $survey_questions ) )
$survey_questions = array();
$survey_responses = ASS_Helper::get_survey_responses( $survey_id , $filters );
if ( !is_array( $survey_responses ) )
$survey_responses = array();
if ( array_key_exists( 'error_filters' , $survey_responses ) ) {
$err_msg = __( 'There are errors on the survey report filters' , 'after-sale-surveys' ) . "
";
foreach ( $survey_responses[ 'error_filters' ] as $err )
$err_msg .= $err . "
";
$response = array(
'status' => 'fail',
'error_message' => $err_msg
);
} else {
if ( empty( $survey_questions ) ) {
$response = array(
'status' => 'fail',
'error_message' => __( 'Specified survey does not have any questions' , 'after-sale-surveys' )
);
} elseif ( empty( $survey_responses ) ) {
if ( !empty( $filters ) ) {
$response = array(
'status' => 'fail',
'error_message' => __( 'No survey responses data for the specified filter/s' , 'after-sale-surveys' )
);
} else {
$response = array(
'status' => 'fail',
'error_message' => __( 'Specified survey does not have any responses' , 'after-sale-surveys' )
);
}
} else {
// Construct response data report
$survey_response_report = array();
foreach ( $survey_questions as $page_number => $questions_data ) {
foreach ( $questions_data as $order_number => $question ) {
$question_response_report = $this->construct_question_response_report( $survey_id , $question , $survey_responses , $page_number , $order_number );
$survey_response_report[] = $question_response_report;
}
}
$response = array(
'status' => 'success',
'total_responses' => count( $survey_responses ),
'response_data_report' => $survey_response_report
);
}
}
}
if ( $ajax_call === true ) {
header( "Content-Type: application/json" );
echo json_encode( $response );
die();
} else
return $response;
}
/**
* Construct the report data for the responses of a specific question.
*
* @since 1.0.0
* @access public
*
* @param $survey_id
* @param $question
* @param $survey_responses
* @param $page_number
* @param $order_number
* @return mixed
*/
public function construct_question_response_report( $survey_id , $question , $survey_responses , $page_number , $order_number ) {
if ( $question[ 'question-type' ] == 'multiple-choice-single-answer' ) {
$responses_data_arr = array();
foreach ( $survey_responses as $response_obj ) {
$response_data = get_post_meta( $response_obj->ID , $this->_plugin_constants->POST_META_SURVEY_RESPONSES() , true );
if ( isset( $response_data[ $page_number ][ $order_number ][ 'answer' ] ) && !in_array( $response_data[ $page_number ][ $order_number ][ 'answer' ] , array( '' , false , null ) ) )
$responses_data_arr[] = $response_data[ $page_number ][ $order_number ][ 'answer' ];
}
// TODO: Important: Here is the tricky part. check if answer has special characters, this is gonna be an issue.
$counted_responses_data_arr = array_count_values( $responses_data_arr );
foreach ( $question[ 'responses' ][ 'multiple-choices' ] as $choice )
if ( !array_key_exists( $choice , $counted_responses_data_arr ) )
$counted_responses_data_arr[ $choice ] = 0;
$question_response_report = array(
'page-number' => $page_number,
'order-number' => $order_number,
'question-type' => $question[ 'question-type' ],
'question-text' => $question[ 'question-text' ],
'multiple-choices' => $counted_responses_data_arr
);
} else
$question_response_report = array();
return apply_filters( 'as_survey_' . $question[ 'question-type' ] . '_question_response_report' , $question_response_report , $survey_id , $question , $survey_responses , $page_number , $order_number );
}
/**
* Retrieve list of responses of a given survey. Each responses item list contains information about each specific response.
*
* @since 1.0.0
* @access public
*
* @param null $survey_id
* @param null $filters
* @param bool|true $ajax_call
* @return array
*/
public function as_survey_get_survey_responses_list( $survey_id = null , $filters = null , $ajax_call = true ) {
if ( $ajax_call === true ) {
$survey_id = $_POST[ 'survey_id' ];
$filters = $_POST[ 'filters' ];
}
if ( get_post_status( $survey_id ) === false ) {
$response = array(
'status' => 'fail',
'error_message' => __( 'Specified survey does not exist' , 'after-sale-surveys' )
);
} elseif ( get_post_type( $survey_id ) != $this->_plugin_constants->SURVEY_CPT_NAME() ) {
$response = array(
'status' => 'fail',
'error_message' => __( 'Specified survey id does not represent a survey post type' , 'after-sale-surveys' )
);
} else {
$survey_responses = ASS_Helper::get_survey_responses( $survey_id , $filters );
if ( !is_array( $survey_responses ) )
$survey_responses = array();
if ( empty( $survey_responses ) ) {
$response = array(
'status' => 'fail',
'error_message' => __( 'Specified survey does not have any responses' , 'after-sale-surveys' )
);
} else {
// Construct table report data
$table_report_data = array();
foreach ( $survey_responses as $survey_response ) {
$order_id = get_post_meta( $survey_response->ID , $this->_plugin_constants->POST_META_RESPONSE_ORDER_ID() , true );
$user_id = get_post_meta( $survey_response->ID , $this->_plugin_constants->POST_META_RESPONSE_USER_ID() , true );
$order_url = get_admin_url() . "post.php?post=" . $order_id . "&action=edit";
$response_url = get_admin_url() . "post.php?post=" . $survey_response->ID . "&action=edit";
if ( $user_id ) {
$user_data = get_userdata( $user_id );
$user_fullname = $user_data->first_name . " " . $user_data->last_name;
$user_url = get_admin_url() . "user-edit.php?user_id=" . $user_id;
} else {
$order_obj = new WC_Order( $order_id );
$user_fullname = $order_obj->get_formatted_billing_full_name();
$user_url = "";
}
$table_report_data[] = apply_filters( 'as_survey_table_report_data_item' , array(
'order_id' => $order_id,
'order_url' => $order_url,
'response_date' => $survey_response->post_date,
'user_fullname' => $user_fullname,
'user_url' => $user_url,
'response_url' => $response_url
) , $survey_response->ID , $survey_id , $order_id , $user_id );
}
$response = array(
'status' => 'success',
'total_responses' => count( $survey_responses ),
'table_report_data' => $table_report_data
);
}
}
if ( $ajax_call === true ) {
header( "Content-Type: application/json" );
echo json_encode( $response );
die();
} else
return $response;
}
}
}