Current Path : /proc/5208/cwd/wp-content/plugins/ninja-forms/includes/Database/Models/ |
Current File : //proc/5208/cwd/wp-content/plugins/ninja-forms/includes/Database/Models/Submission.php |
<?php if ( ! defined( 'ABSPATH' ) ) exit; /** * Class NF_Database_Models_Submission */ final class NF_Database_Models_Submission { protected $_id = ''; protected $_status = ''; protected $_user_id = ''; protected $_form_id = ''; protected $_seq_num = ''; protected $_sub_date = ''; protected $_mod_date = ''; protected $_field_values = array(); protected $_extra_values = array(); /** * Delimiter that uniquely identifies a field as type 'repeater' * * Requests for a field can be made by either an (int) field id or a * (string) field reference, which prior to fieldset repeaters had been * for the field key only. For disambiguation, a fieldset repeater field * request for a specific field within the fieldset is in the form of: * {fieldsetFieldId}{delimiter}{fieldIdOfFieldWithinFieldset} * * @var string */ protected $_fieldsetDelimiter='.'; /** * Delimiter that uniquely identifies multiple fieldset repeater submissions * * Fieldset Repeaters can have multiple values submitted on any given * submission. Each repeated value for a field in the fieldset is * delimited in the submission data with an incremented index value * @var string */ protected $_fieldsetRepetitionDelimiter='_'; public function __construct( $id = '', $form_id = '' ) { $this->_id = $id; $this->_form_id = $form_id; if( $this->_id ){ $sub = get_post( $this->_id ); if ($sub) { $this->_status = $sub->post_status; $this->_user_id = $sub->post_author; $this->_sub_date = $sub->post_date; $this->_mod_date = $sub->post_modified; } } if( $this->_id && ! $this->_form_id ){ $this->_form_id = get_post_meta( $this->_id, '_form_id', TRUE ); } if( $this->_id && $this->_form_id ){ $this->_seq_num = get_post_meta( $this->_id, '_seq_num', TRUE ); } } /** * Get Submission ID * * @return int */ public function get_id() { return intval( $this->_id ); } public function get_status() { return $this->_status; } public function get_user() { return get_user_by( 'id', $this->_user_id ); } public function get_form_id() { return intval( $this->_form_id ); } public function get_form_title() { $form = Ninja_Forms()->form( $this->_form_id )->get(); return $form->get_setting( 'title' ); } public function get_seq_num() { return intval( $this->_seq_num ); } public function get_sub_date( $format = 'm/d/Y' ) { return date( $format, strtotime( $this->_sub_date ) ); } public function get_mod_date( $format = 'm/d/Y' ) { return date( $format, strtotime( $this->_mod_date ) ); } /** * Get Field Value * * Returns a single submission value by field ID or field key. * * @param int|string $field_ref * @return string */ public function get_field_value( $field_ref ) { // Bypass existing method if fieldset repeater if(Ninja_Forms()->fieldsetRepeater->isRepeaterFieldByFieldReference($field_ref) ){ $parsedField = Ninja_Forms()->fieldsetRepeater ->parseFieldsetFieldReference($field_ref); $return = $this->get_field_value_for_fieldset_child($parsedField['fieldId'], $parsedField['fieldsetFieldId']); return $return; } $field_id = ( is_numeric( $field_ref ) ) ? $field_ref : $this->get_field_id_by_key( $field_ref ); $field = '_field_' . $field_id; if( isset( $this->_field_values[ $field ] ) ) return $this->_field_values[ $field ]; $this->_field_values[ $field ] = get_post_meta($this->_id, $field, TRUE); $this->_field_values[ $field_ref ] = get_post_meta($this->_id, $field, TRUE); return WPN_Helper::htmlspecialchars( $this->_field_values[ $field ] ); } /** * Get field values of a single child field within a fieldset repeater field * * get_field_value(), which calls this method, is expected to return a * string. Fieldset Repeater child fields have a unique field reference, * differentiated by their delimiter that ensures that the requesting * external caller knows that it is requesting a fieldset repeater field. * This this method returns a serialized string of values, honoring the * get_field_value() method with the expectation that the external * caller will unserialize this value. * * @param int $fieldsetId * @param int $childFieldId */ protected function get_field_value_for_fieldset_child($fieldsetId, $childFieldId) { if (!isset($this->_field_values[$fieldsetId])) { $this->_field_values[$fieldsetId] = get_post_meta($this->_id, '_field_' . $fieldsetId, true); } $valueCollection = []; if(!empty($this->_field_values[$fieldsetId] )){ foreach ($this->_field_values[$fieldsetId] as $submissionKey => $value) { $explodedFieldset = explode($this->_fieldsetDelimiter, $submissionKey); if (!isset($explodedFieldset[1])) { // data is corrupted as we cannot determine field id construct break; } $explodedChildField = explode($this->_fieldsetRepetitionDelimiter, $explodedFieldset[1]); if (!isset($explodedChildField[1])) { // data is corrupted as we cannote determine child field id construct break; } $submissionChildFieldId = $explodedChildField[0]; $submissionIndex = $explodedChildField[1]; if ($submissionChildFieldId === $childFieldId) { $valueCollection[$submissionIndex] = WPN_Helper::htmlspecialchars($value); } } } $return = serialize($valueCollection); return $return; } /** * Get Field Values * * @return array|mixed */ public function get_field_values() { if( ! empty( $this->_field_values ) ) return $this->_field_values; $field_values = get_post_meta( $this->_id, '' ); foreach( $field_values as $field_id => $field_value ){ $this->_field_values[ $field_id ] = implode( ', ', $field_value ); if( 0 === strpos( $field_id, '_field_' ) ){ $field_id = substr( $field_id, 7 ); } if( ! is_numeric( $field_id ) ) continue; $field = Ninja_Forms()->form()->get_field( $field_id ); $key = $field->get_setting( 'key' ); if( $key ) { $this->_field_values[ $key ] = implode(', ', $field_value); } } return $this->_field_values; } /** * Update Field Value * * @param $field_ref * @param $value * @return $this */ public function update_field_value( $field_ref, $value ) { $field_id = ( is_numeric( $field_ref ) ) ? $field_ref : $this->get_field_id_by_key( $field_ref ); $this->_field_values[ $field_id ] = WPN_Helper::kses_post( $value ); return $this; } /** * Update Field Values * * @param $data * @return $this */ public function update_field_values( $data ) { foreach( $data as $field_ref => $value ) { $this->update_field_value( $field_ref, $value ); } return $this; } public function get_extra_value( $key ) { if( ! isset( $this->_extra_values[ $key ] ) || ! $this->_extra_values[ $key ] ){ $id = ( $this->_id ) ? $this->_id : 0; $this->_extra_values[ $key ] = get_post_meta( $id, $key, TRUE ); } return $this->_extra_values[ $key ]; } public function get_extra_values( $keys ) { $values = array(); foreach( $keys as $key ) { $values[ $key ] = $this->get_extra_value( $key ); } return $values; } public function update_extra_value( $key, $value ) { if( property_exists( $this, $key ) ) return FALSE; return $this->_extra_values[ $key ] = $value; } public function update_extra_values( $values ) { foreach( $values as $key => $value ){ $this->update_extra_value( $key, $value ); } } /** * Find Submissions * * @param $form_id * @param array $where * @return array */ public function find( $form_id, array $where = array(), array $ids = array() ) { $this->_form_id = $form_id; $args = array( 'post_type' => 'nf_sub', 'posts_per_page' => -1, 'meta_query' => $this->format_meta_query( $where ) ); if ( ! empty ( $ids ) ) { $args[ 'post__in' ] = $ids; } $subs = get_posts( $args ); $class = get_class( $this ); $return = array(); foreach( $subs as $sub ){ $return[] = new $class( $sub->ID, $this->_form_id ); } return $return; } /** * Delete Submission */ public function delete() { if( ! $this->_id ) return; wp_delete_post( $this->_id ); } /** * Trash Submission */ public function trash() { if( ! $this->_id ) return; wp_trash_post( $this->_id ); } /** * Save Submission * * @return $this|NF_Database_Models_Submission|void */ public function save() { if( ! $this->_id ){ $sub = array( 'post_type' => 'nf_sub', 'post_status' => 'publish' ); $this->_id = wp_insert_post( $sub ); // Log Error if( ! $this->_id ) return; } if( ! $this->_seq_num && $this->_form_id ){ $this->_seq_num = NF_Database_Models_Form::get_next_sub_seq( $this->_form_id ); } $this->_save_extra_values(); return $this->_save_field_values(); } public static function export( $form_id, array $sub_ids = array(), $return = FALSE ) { $date_format = Ninja_Forms()->get_setting( 'date_format' ); /* * Labels */ $field_labels = array( '_seq_num' => '#', '_date_submitted' => esc_html__( 'Date Submitted', 'ninja-forms' ) ); // Legacy Filter from 2.9.* $field_labels = apply_filters( 'nf_subs_csv_label_array_before_fields', $field_labels, $sub_ids ); $fields = Ninja_Forms()->form( $form_id )->get_fields(); /* * If we are using an add-on that filters our field order, we don't want to call sort again. * * TODO: This is probably not the most effecient way to handle this. It should be re-thought. */ if ( ! has_filter( 'ninja_forms_get_fields_sorted' ) ) { uasort( $fields, array( 'NF_Database_Models_Submission', 'sort_fields' ) ); } $hidden_field_types = apply_filters( 'nf_sub_hidden_field_types', array() ); /* * Submissions */ $subs = Ninja_Forms()->form( $form_id )->get_subs( array(), FALSE, $sub_ids ); foreach( $subs as $sub ){ $value[ '_seq_num' ] = $sub->get_seq_num(); $value[ '_date_submitted' ] = $sub->get_sub_date( $date_format ); // boolean - does this submission use a repeater $hasRepeater = false; // How many repeater submissions does this submission have $submissionCount = 0; // Ids of fields in the repeater $fieldsetFieldIds=[]; foreach ($fields as $field_id => $field) { // Bypass existing method if fieldset repeater if('repeater'===$field->get_setting('type')){ $hasRepeater = true; $fieldsetSubmission= $sub->get_field_value( $field_id ); $fieldsetSettings = $field->get_settings(); $fieldsetLabels = Ninja_Forms()->fieldsetRepeater ->getFieldsetLabels($field_id, $fieldsetSettings, true); foreach($fieldsetLabels as $fieldsetFieldId =>$fieldsetFieldLabel){ $fieldsetFieldIds[]=$fieldsetFieldId; $field_labels[$fieldsetFieldId]=$fieldsetFieldLabel; $fieldType = Ninja_Forms()->fieldsetRepeater->getFieldtype($fieldsetFieldId, $fieldsetSettings); $fieldsetFieldSubmissionCollection=Ninja_Forms()->fieldsetRepeater ->extractSubmissionsByFieldsetField($fieldsetFieldId, $fieldsetSubmission); $submissionCount = count($fieldsetFieldSubmissionCollection); foreach ($fieldsetFieldSubmissionCollection as &$fieldsetFieldSubmission) { if(is_array($fieldsetFieldSubmission['value'])){ $fieldsetFieldSubmission['value']= implode(', ',$fieldsetFieldSubmission['value']); } } $value[$fieldsetFieldId]= array_column($fieldsetFieldSubmissionCollection,'value'); } }else{ if (!is_int($field_id)) continue; if( in_array( $field->get_setting( 'type' ), $hidden_field_types ) ) continue; if ( $field->get_setting( 'admin_label' ) ) { $field_labels[ $field->get_id() ] = $field->get_setting( 'admin_label' ); } else { $field_labels[ $field->get_id() ] = $field->get_setting( 'label' ); } $field_value = maybe_unserialize( $sub->get_field_value( $field_id ) ); $field_value = apply_filters('nf_subs_export_pre_value', $field_value, $field_id); $field_value = apply_filters('ninja_forms_subs_export_pre_value', $field_value, $field_id, $form_id); $field_value = apply_filters( 'ninja_forms_subs_export_field_value_' . $field->get_setting( 'type' ), $field_value, $field ); if ( is_array($field_value ) ) { $field_value = implode( ',', $field_value ); } $value[ $field_id ] = $field_value; } } if(!$hasRepeater){ $value_array[] = $value; }else{ // The the submission has repeater fields, create an indexed array first $repeatingValueArray=[]; $index = 0; do { // iterate each column in the row 'value' foreach($value as $fieldId=>$columnValue){ // If the column in the row value is not a repeater // fieldset field, simply copy it into a new row of the // repeating value array if(!in_array($fieldId,$fieldsetFieldIds)){ $repeatingValueArray[$index][]=$columnValue; }else{ // If the column in the row value is a repeater // fieldset field, copy the next submission index value $repeatingValueArray[$index][]=$columnValue[$index]; } } // at the end of the row value columns, increment the index // until all the submission index values are added $index++; } while ($index < $submissionCount); // After iterating the row value once for each submission index, // add the repeatingValueArray to the value array $value_array[]=$repeatingValueArray; } } $value_array = WPN_Helper::stripslashes( $value_array ); // Legacy Filter from 2.9.* $value_array = apply_filters( 'nf_subs_csv_value_array', $value_array, $sub_ids ); $csv_array[ 0 ][] = $field_labels; $csv_array[ 1 ][] = $value_array; // Get any extra data from our other plugins... $csv_array = apply_filters( 'nf_subs_csv_extra_values', $csv_array, $subs, $form_id ); $today = date( $date_format, current_time( 'timestamp' ) ); $filename = apply_filters( 'nf_subs_csv_filename', 'nf_subs_' . $today ); $filename = $filename . ".csv"; if( $return ){ return WPN_Helper::str_putcsv( $csv_array, apply_filters( 'nf_sub_csv_delimiter', ',' ), apply_filters( 'nf_sub_csv_enclosure', '"' ), apply_filters( 'nf_sub_csv_terminator', "\n" ) ); }else{ header( 'Content-type: application/csv'); header( 'Content-Disposition: attachment; filename="'.$filename .'"' ); header( 'Pragma: no-cache'); header( 'Expires: 0' ); echo apply_filters( 'nf_sub_csv_bom',"\xEF\xBB\xBF" ) ; // Byte Order Mark echo WPN_Helper::str_putcsv( $csv_array, apply_filters( 'nf_sub_csv_delimiter', ',' ), apply_filters( 'nf_sub_csv_enclosure', '"' ), apply_filters( 'nf_sub_csv_terminator', "\n" ) ); die(); } } /* * PROTECTED METHODS */ /** * Save Field Value * * @param $field_id * @param $value * @return $this */ protected function _save_field_value( $field_id, $value ) { update_post_meta( $this->_id, '_field_' . $field_id, $value ); return $this; } /** * Save Field Values * * @return $this|void */ protected function _save_field_values() { if( ! $this->_field_values ) return FALSE; foreach( $this->_field_values as $field_id => $value ) { $this->_save_field_value( $field_id, $value ); } update_post_meta( $this->_id, '_form_id', $this->_form_id ); update_post_meta( $this->_id, '_seq_num', $this->_seq_num ); return $this; } protected function _save_extra_values() { if( ! $this->_extra_values ) return FALSE; foreach( $this->_extra_values as $key => $value ) { if( property_exists( $this, $key ) ) continue; update_post_meta( $this->_id, $key, $value ); } } /* * UTILITIES */ /** * Format Meta Query * * @param array $where * @return array */ protected function format_meta_query( array $where = array() ) { $return = array( array( 'key' => '_form_id', 'value' => $this->_form_id ) ); if( ! empty( $where ) ) { foreach ($where as $ref => $value) { $field_id = ( is_int( $ref ) ) ? $ref : $this->get_field_id_by_key( $ref ); $return[] = ( is_array($value) ) ? $value : array('key' => "_field_$field_id", 'value' => $value); } } return $return; } /** * Get Field ID By Key * * @param $field_key * @return mixed */ protected function get_field_id_by_key( $field_key ) { global $wpdb; $field_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}nf3_fields WHERE `key` = %s AND `parent_id` = {$this->_form_id}", $field_key )); return $field_id; } public static function sort_fields( $a, $b ) { if ( $a->get_setting( 'order' ) == $b->get_setting( 'order' ) ) { return 0; } return ( $a->get_setting( 'order' ) < $b->get_setting( 'order' ) ) ? -1 : 1; } } // End NF_Database_Models_Submission