render_template( 'questionnaires.php', array( 'blueprints' => self::blueprint_rows(), 'health' => self::health_rows(), 'surfaces' => self::surface_rows(), 'worklist' => self::worklist_rows(), 'hooks' => AIEO_Survey_Placement::hooks(), 'statuses' => self::order_statuses(), 'pages' => self::page_options(), ) ); } public static function order_statuses() { if ( ! function_exists( 'wc_get_order_statuses' ) ) { return array(); } $out = array(); foreach ( (array) wc_get_order_statuses() as $slug => $label ) { $out[ preg_replace( '/^wc-/', '', (string) $slug ) ] = (string) $label; } return $out; } public static function page_options() { $out = array(); foreach ( (array) get_posts( array( 'post_type' => 'page', 'numberposts' => 200, 'post_status' => 'publish', 'orderby' => 'title', 'order' => 'ASC' ) ) as $p ) { $out[ (int) $p->ID ] = (string) $p->post_title; } return $out; } public function ajax_make_page() { AIEO_DMM::verify_ajax_request(); $blueprint = isset( $_POST['blueprint'] ) ? sanitize_key( wp_unslash( $_POST['blueprint'] ) ) : ''; $bp = AIEO_Survey_Blueprint::get( $blueprint ); if ( ! $bp ) { wp_send_json_error( array( 'message' => __( 'Unknown survey.', 'ai-eshop-optimizer' ) ) ); } $shortcode = '[aieo_survey blueprint="' . $blueprint . '"]'; $existing = get_posts( array( 'post_type' => 'page', 'post_status' => array( 'publish', 'draft' ), 'numberposts' => 1, 's' => $shortcode, ) ); $page_id = $existing ? (int) $existing[0]->ID : (int) wp_insert_post( array( 'post_type' => 'page', 'post_status' => 'publish', 'post_title' => $bp['label'], 'post_content' => $shortcode, ) ); if ( $page_id <= 0 ) { wp_send_json_error( array( 'message' => __( 'The page could not be created.', 'ai-eshop-optimizer' ) ) ); } AIEO_Survey_Placement::save( $blueprint, array( 'page_id' => $page_id ) ); wp_send_json_success( array( 'page_id' => $page_id, 'title' => get_the_title( $page_id ), 'url' => get_permalink( $page_id ), 'message' => __( 'Page ready.', 'ai-eshop-optimizer' ), ) ); } public static function blueprint_rows() { $out = array(); foreach ( AIEO_Survey_Blueprint::all()['blueprints'] as $id => $bp ) { $summary = AIEO_Survey_Health::summary( $id, 30 ); $place = $summary['placement']; $hooks = AIEO_Survey_Placement::hooks(); $out[] = array( 'id' => $id, 'label' => $bp['label'], 'description' => isset( $bp['description'] ) ? (string) $bp['description'] : '', 'questions' => count( AIEO_Survey_Blueprint::question_codes( $id ) ), 'enabled' => ! empty( $place['enabled'] ), 'hook_key' => (string) $place['hook'], 'priority' => (int) $place['priority'], 'statuses' => (array) $place['statuses'], 'once' => ! empty( $place['once_per_order'] ), 'expires' => (int) $place['expires_days'], 'hook' => '' !== $place['hook'] && isset( $hooks[ $place['hook'] ] ) ? $hooks[ $place['hook'] ] : '', 'page_id' => (int) $place['page_id'], 'title' => (string) $place['title'], 'intro' => (string) $place['intro'], 'title_ph' => (string) $bp['title'], 'intro_ph' => (string) $bp['intro'], 'thanks' => (string) $place['thanks'], 'thanks_ph' => (string) $bp['thanks'], 'section_size' => (int) $place['section_size'], 'question_size' => (int) $place['question_size'], 'option_size' => (int) $place['option_size'], 'help_size' => (int) $place['help_size'], 'page_title' => $place['page_id'] > 0 ? (string) get_the_title( (int) $place['page_id'] ) : '', 'responses' => (int) $summary['coverage']['responses'], 'resolved' => (int) $summary['coverage']['resolved'], 'orders' => (int) $summary['coverage']['orders'], 'rate' => (float) $summary['coverage']['rate'], 'asked' => isset( $summary['asking']['asked'] ) ? (int) $summary['asking']['asked'] : 0, 'answered' => isset( $summary['asking']['responded'] ) ? (int) $summary['asking']['responded'] : 0, 'silent' => count( $summary['silent_questions'] ), 'problem' => ( ! empty( $place['enabled'] ) && (int) $place['page_id'] <= 0 ) ? __( 'No page hosts it, so no link can be sent', 'ai-eshop-optimizer' ) : '', ); } return $out; } public static function health_rows() { $out = array(); foreach ( array_keys( AIEO_Survey_Blueprint::all()['blueprints'] ) as $id ) { foreach ( AIEO_Survey_Health::questions( $id ) as $q ) { $out[] = array( 'blueprint' => $id, 'code' => $q['code'], 'label' => $q['label'], 'answered' => $q['answered'], 'skipped' => $q['skipped'], 'not_shown' => $q['not_shown'], 'state' => $q['silent'] ? 'silent' : 'collecting', ); } } return $out; } public static function surface_rows() { $out = array(); foreach ( AIEO_Survey_Health::adapter_surfaces() as $surface => $blueprint ) { $map = AIEO_Survey_Mapping::get( $surface ); $unmapped = AIEO_Survey_Health::unmapped_fields( $surface ); $missing = AIEO_Survey_Mapping::unmapped_questions( $surface ); $out[] = array( 'surface' => $surface, 'blueprint' => $blueprint, 'mapped' => count( AIEO_Survey_Mapping::resolved( $surface ) ), 'unmapped_fields' => count( $unmapped ), 'unmapped_questions' => count( $missing ), 'context' => implode( ', ', array_filter( $map['context'] ) ), 'problem' => '' === implode( '', $map['context'] ) ? __( 'No field identifies who answered', 'ai-eshop-optimizer' ) : '', ); } return $out; } public static function worklist_rows() { $out = array(); foreach ( array_keys( AIEO_Survey_Health::adapter_surfaces() ) as $surface ) { foreach ( AIEO_Survey_Value_Stage::unresolved( $surface, 100 ) as $row ) { $out[] = array( 'surface' => $surface, 'field' => (string) $row['field_key'], 'question' => AIEO_Survey_Mapping::question_for( $surface, $row['field_key'] ), 'value' => (string) $row['observed_value'], 'hits' => (int) $row['hits'], ); } } return $out; } public function ajax_save_placement() { AIEO_DMM::verify_ajax_request(); $blueprint = isset( $_POST['blueprint'] ) ? sanitize_key( wp_unslash( $_POST['blueprint'] ) ) : ''; if ( '' === $blueprint || ! AIEO_Survey_Blueprint::get( $blueprint ) ) { wp_send_json_error( array( 'message' => __( 'Unknown survey.', 'ai-eshop-optimizer' ) ) ); } $statuses = isset( $_POST['statuses'] ) ? (array) wp_unslash( $_POST['statuses'] ) : array(); AIEO_Survey_Placement::save( $blueprint, array( 'enabled' => ! empty( $_POST['enabled'] ), 'hook' => isset( $_POST['hook'] ) ? sanitize_text_field( wp_unslash( $_POST['hook'] ) ) : '', 'priority' => isset( $_POST['priority'] ) ? (int) $_POST['priority'] : 20, 'page_id' => isset( $_POST['page_id'] ) ? (int) $_POST['page_id'] : 0, 'expires_days' => isset( $_POST['expires_days'] ) ? (int) $_POST['expires_days'] : 30, 'once_per_order' => ! empty( $_POST['once_per_order'] ), 'statuses' => array_map( 'sanitize_key', $statuses ), 'title' => isset( $_POST['title'] ) ? sanitize_text_field( wp_unslash( $_POST['title'] ) ) : '', 'intro' => isset( $_POST['intro'] ) ? sanitize_textarea_field( wp_unslash( $_POST['intro'] ) ) : '', 'thanks' => isset( $_POST['thanks'] ) ? sanitize_textarea_field( wp_unslash( $_POST['thanks'] ) ) : '', 'section_size' => AIEO_Survey_Placement::size( isset( $_POST['section_size'] ) ? $_POST['section_size'] : 0 ), 'question_size' => AIEO_Survey_Placement::size( isset( $_POST['question_size'] ) ? $_POST['question_size'] : 0 ), 'option_size' => AIEO_Survey_Placement::size( isset( $_POST['option_size'] ) ? $_POST['option_size'] : 0 ), 'help_size' => AIEO_Survey_Placement::size( isset( $_POST['help_size'] ) ? $_POST['help_size'] : 0 ), ) ); wp_send_json_success( array( 'message' => __( 'Saved.', 'ai-eshop-optimizer' ) ) ); } public function ajax_infer() { AIEO_DMM::verify_ajax_request(); $surface = isset( $_POST['surface'] ) ? sanitize_text_field( wp_unslash( $_POST['surface'] ) ) : ''; $parsed = AIEO_Form_Registry::parse_surface( $surface ); if ( ! $parsed || 'gravity' !== $parsed['provider'] ) { wp_send_json_error( array( 'message' => __( 'That is not a form this can read.', 'ai-eshop-optimizer' ) ) ); } $blueprint = isset( $_POST['blueprint'] ) ? sanitize_key( wp_unslash( $_POST['blueprint'] ) ) : ''; $source = new AIEO_Survey_Source_Gravity( (int) $parsed['form_id'], true ); if ( ! $source->available() ) { wp_send_json_error( array( 'message' => __( 'That form cannot be read right now.', 'ai-eshop-optimizer' ) ) ); } $staged = $source->harvest(); $res = AIEO_Survey_Mapping::infer( $source, $blueprint ); wp_send_json_success( array( 'message' => sprintf( __( '%1$d suggested, %2$d of your own decisions left alone, %3$d answers staged.', 'ai-eshop-optimizer' ), (int) $res['suggested'], (int) $res['kept'], (int) $staged ), ) ); } public function ajax_rule() { AIEO_DMM::verify_ajax_request(); $value = isset( $_POST['value'] ) ? sanitize_text_field( wp_unslash( $_POST['value'] ) ) : ''; $code = isset( $_POST['code'] ) ? sanitize_key( wp_unslash( $_POST['code'] ) ) : ''; if ( '' === $value ) { wp_send_json_error( array( 'message' => __( 'Nothing to rule on.', 'ai-eshop-optimizer' ) ) ); } if ( '' === $code ) { AIEO_Survey_Choice_Register::forget( $value ); wp_send_json_success( array( 'message' => __( 'Forgotten.', 'ai-eshop-optimizer' ) ) ); } $question = isset( $_POST['question'] ) ? sanitize_key( wp_unslash( $_POST['question'] ) ) : ''; $q = AIEO_Survey_Blueprint::question( $question ); $label = ( $q && isset( $q['choices'][ $code ] ) ) ? $q['choices'][ $code ] : $code; AIEO_Survey_Choice_Register::learn( $value, $code, $label, 'confirmed', $question ); wp_send_json_success( array( 'message' => __( 'Learned. It applies to every form on this site.', 'ai-eshop-optimizer' ) ) ); } }