Submission.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <?php if ( ! defined( 'ABSPATH' ) ) exit;
  2. /**
  3. * Class NF_Database_Models_Submission
  4. */
  5. final class NF_Database_Models_Submission
  6. {
  7. protected $_id = '';
  8. protected $_status = '';
  9. protected $_user_id = '';
  10. protected $_form_id = '';
  11. protected $_seq_num = '';
  12. protected $_sub_date = '';
  13. protected $_mod_date = '';
  14. protected $_field_values = array();
  15. protected $_extra_values = array();
  16. public function __construct( $id = '', $form_id = '' )
  17. {
  18. $this->_id = $id;
  19. $this->_form_id = $form_id;
  20. if( $this->_id ){
  21. $sub = get_post( $this->_id );
  22. if ($sub) {
  23. $this->_status = $sub->post_status;
  24. $this->_user_id = $sub->post_author;
  25. $this->_sub_date = $sub->post_date;
  26. $this->_mod_date = $sub->post_modified;
  27. }
  28. }
  29. if( $this->_id && ! $this->_form_id ){
  30. $this->_form_id = get_post_meta( $this->_id, '_form_id', TRUE );
  31. }
  32. if( $this->_id && $this->_form_id ){
  33. $this->_seq_num = get_post_meta( $this->_id, '_seq_num', TRUE );
  34. }
  35. }
  36. /**
  37. * Get Submission ID
  38. *
  39. * @return int
  40. */
  41. public function get_id()
  42. {
  43. return intval( $this->_id );
  44. }
  45. public function get_status()
  46. {
  47. return $this->_status;
  48. }
  49. public function get_user()
  50. {
  51. return get_user_by( 'id', $this->_user_id );
  52. }
  53. public function get_form_id()
  54. {
  55. return intval( $this->_form_id );
  56. }
  57. public function get_form_title()
  58. {
  59. $form = Ninja_Forms()->form( $this->_form_id )->get();
  60. return $form->get_setting( 'title' );
  61. }
  62. public function get_seq_num()
  63. {
  64. return intval( $this->_seq_num );
  65. }
  66. public function get_sub_date( $format )
  67. {
  68. return date( $format, strtotime( $this->_sub_date ) );
  69. }
  70. public function get_mod_date( $format = 'm/d/Y' )
  71. {
  72. return date( $format, strtotime( $this->_mod_date ) );
  73. }
  74. /**
  75. * Get Field Value
  76. *
  77. * Returns a single submission value by field ID or field key.
  78. *
  79. * @param int|string $field_ref
  80. * @return string
  81. */
  82. public function get_field_value( $field_ref )
  83. {
  84. $field_id = ( is_numeric( $field_ref ) ) ? $field_ref : $this->get_field_id_by_key( $field_ref );
  85. $field = '_field_' . $field_id;
  86. if( isset( $this->_field_values[ $field ] ) ) return $this->_field_values[ $field ];
  87. $this->_field_values[ $field ] = get_post_meta($this->_id, $field, TRUE);
  88. $this->_field_values[ $field_ref ] = get_post_meta($this->_id, $field, TRUE);
  89. return $this->_field_values[ $field ];
  90. }
  91. /**
  92. * Get Field Values
  93. *
  94. * @return array|mixed
  95. */
  96. public function get_field_values()
  97. {
  98. if( ! empty( $this->_field_values ) ) return $this->_field_values;
  99. $field_values = get_post_meta( $this->_id, '' );
  100. foreach( $field_values as $field_id => $field_value ){
  101. $this->_field_values[ $field_id ] = implode( ', ', $field_value );
  102. if( 0 === strpos( $field_id, '_field_' ) ){
  103. $field_id = substr( $field_id, 7 );
  104. }
  105. if( ! is_numeric( $field_id ) ) continue;
  106. $field = Ninja_Forms()->form()->get_field( $field_id );
  107. $key = $field->get_setting( 'key' );
  108. if( $key ) {
  109. $this->_field_values[ $key ] = implode(', ', $field_value);
  110. }
  111. }
  112. return $this->_field_values;
  113. }
  114. /**
  115. * Update Field Value
  116. *
  117. * @param $field_ref
  118. * @param $value
  119. * @return $this
  120. */
  121. public function update_field_value( $field_ref, $value )
  122. {
  123. $field_id = ( is_numeric( $field_ref ) ) ? $field_ref : $this->get_field_id_by_key( $field_ref );
  124. $this->_field_values[ $field_id ] = WPN_Helper::kses_post( $value );
  125. return $this;
  126. }
  127. /**
  128. * Update Field Values
  129. *
  130. * @param $data
  131. * @return $this
  132. */
  133. public function update_field_values( $data )
  134. {
  135. foreach( $data as $field_ref => $value )
  136. {
  137. $this->update_field_value( $field_ref, $value );
  138. }
  139. return $this;
  140. }
  141. public function get_extra_value( $key )
  142. {
  143. if( ! isset( $this->_extra_values[ $key ] ) || ! $this->_extra_values[ $key ] ){
  144. $id = ( $this->_id ) ? $this->_id : 0;
  145. $this->_extra_values[ $key ] = get_post_meta( $id, $key, TRUE );
  146. }
  147. return $this->_extra_values[ $key ];
  148. }
  149. public function get_extra_values( $keys )
  150. {
  151. $values = array();
  152. foreach( $keys as $key ) {
  153. $values[ $key ] = $this->get_extra_value( $key );
  154. }
  155. return $values;
  156. }
  157. public function update_extra_value( $key, $value )
  158. {
  159. if( property_exists( $this, $key ) ) return FALSE;
  160. return $this->_extra_values[ $key ] = $value;
  161. }
  162. public function update_extra_values( $values )
  163. {
  164. foreach( $values as $key => $value ){
  165. $this->update_extra_value( $key, $value );
  166. }
  167. }
  168. /**
  169. * Find Submissions
  170. *
  171. * @param $form_id
  172. * @param array $where
  173. * @return array
  174. */
  175. public function find( $form_id, array $where = array(), array $ids = array() )
  176. {
  177. $this->_form_id = $form_id;
  178. $args = array(
  179. 'post_type' => 'nf_sub',
  180. 'posts_per_page' => -1,
  181. 'meta_query' => $this->format_meta_query( $where )
  182. );
  183. if ( ! empty ( $ids ) ) {
  184. $args[ 'post__in' ] = $ids;
  185. }
  186. $subs = get_posts( $args );
  187. $class = get_class( $this );
  188. $return = array();
  189. foreach( $subs as $sub ){
  190. $return[] = new $class( $sub->ID, $this->_form_id );
  191. }
  192. return $return;
  193. }
  194. /**
  195. * Delete Submission
  196. */
  197. public function delete()
  198. {
  199. if( ! $this->_id ) return;
  200. wp_delete_post( $this->_id );
  201. }
  202. /**
  203. * Save Submission
  204. *
  205. * @return $this|NF_Database_Models_Submission|void
  206. */
  207. public function save()
  208. {
  209. if( ! $this->_id ){
  210. $sub = array(
  211. 'post_type' => 'nf_sub',
  212. 'post_status' => 'publish'
  213. );
  214. $this->_id = wp_insert_post( $sub );
  215. // Log Error
  216. if( ! $this->_id ) return;
  217. }
  218. if( ! $this->_seq_num && $this->_form_id ){
  219. $this->_seq_num = NF_Database_Models_Form::get_next_sub_seq( $this->_form_id );
  220. }
  221. $this->_save_extra_values();
  222. return $this->_save_field_values();
  223. }
  224. public static function export( $form_id, array $sub_ids = array(), $return = FALSE )
  225. {
  226. $date_format = Ninja_Forms()->get_setting( 'date_format' );
  227. /*
  228. * Labels
  229. */
  230. $field_labels = array(
  231. '_seq_num' => '#',
  232. '_date_submitted' => __( 'Date Submitted', 'ninja-forms' )
  233. );
  234. // Legacy Filter from 2.9.*
  235. $field_labels = apply_filters( 'nf_subs_csv_label_array_before_fields', $field_labels, $sub_ids );
  236. $fields = Ninja_Forms()->form( $form_id )->get_fields();
  237. /*
  238. * If we are using an add-on that filters our field order, we don't want to call sort again.
  239. *
  240. * TODO: This is probably not the most effecient way to handle this. It should be re-thought.
  241. */
  242. if ( ! has_filter( 'ninja_forms_get_fields_sorted' ) ) {
  243. uasort( $fields, array( 'NF_Database_Models_Submission', 'sort_fields' ) );
  244. }
  245. $hidden_field_types = apply_filters( 'nf_sub_hidden_field_types', array() );
  246. /*
  247. * Submissions
  248. */
  249. $subs = Ninja_Forms()->form( $form_id )->get_subs( array(), FALSE, $sub_ids );
  250. foreach( $subs as $sub ){
  251. $value[ '_seq_num' ] = $sub->get_seq_num();
  252. $value[ '_date_submitted' ] = $sub->get_sub_date( $date_format );
  253. foreach ($fields as $field_id => $field) {
  254. if (!is_int($field_id)) continue;
  255. if( in_array( $field->get_setting( 'type' ), $hidden_field_types ) ) continue;
  256. if ( $field->get_setting( 'admin_label' ) ) {
  257. $field_labels[ $field->get_id() ] = $field->get_setting( 'admin_label' );
  258. } else {
  259. $field_labels[ $field->get_id() ] = $field->get_setting( 'label' );
  260. }
  261. $field_value = maybe_unserialize( $sub->get_field_value( $field_id ) );
  262. $field_value = apply_filters('nf_subs_export_pre_value', $field_value, $field_id);
  263. $field_value = apply_filters('ninja_forms_subs_export_pre_value', $field_value, $field_id, $form_id);
  264. $field_value = apply_filters( 'ninja_forms_subs_export_field_value_' . $field->get_setting( 'type' ), $field_value, $field );
  265. if ( is_array($field_value ) ) {
  266. $field_value = implode( ',', $field_value );
  267. }
  268. $value[ $field_id ] = $field_value;
  269. }
  270. $value_array[] = $value;
  271. }
  272. $value_array = WPN_Helper::stripslashes( $value_array );
  273. // Legacy Filter from 2.9.*
  274. $value_array = apply_filters( 'nf_subs_csv_value_array', $value_array, $sub_ids );
  275. $csv_array[ 0 ][] = $field_labels;
  276. $csv_array[ 1 ][] = $value_array;
  277. // Get any extra data from our other plugins...
  278. $csv_array = apply_filters( 'nf_subs_csv_extra_values', $csv_array, $subs, $form_id );
  279. $today = date( $date_format, current_time( 'timestamp' ) );
  280. $filename = apply_filters( 'nf_subs_csv_filename', 'nf_subs_' . $today );
  281. $filename = $filename . ".csv";
  282. if( $return ){
  283. return WPN_Helper::str_putcsv( $csv_array,
  284. apply_filters( 'nf_sub_csv_delimiter', ',' ),
  285. apply_filters( 'nf_sub_csv_enclosure', '"' ),
  286. apply_filters( 'nf_sub_csv_terminator', "\n" )
  287. );
  288. }else{
  289. header( 'Content-type: application/csv');
  290. header( 'Content-Disposition: attachment; filename="'.$filename .'"' );
  291. header( 'Pragma: no-cache');
  292. header( 'Expires: 0' );
  293. echo apply_filters( 'nf_sub_csv_bom',"\xEF\xBB\xBF" ) ; // Byte Order Mark
  294. echo WPN_Helper::str_putcsv( $csv_array,
  295. apply_filters( 'nf_sub_csv_delimiter', ',' ),
  296. apply_filters( 'nf_sub_csv_enclosure', '"' ),
  297. apply_filters( 'nf_sub_csv_terminator', "\n" )
  298. );
  299. die();
  300. }
  301. }
  302. /*
  303. * PROTECTED METHODS
  304. */
  305. /**
  306. * Save Field Value
  307. *
  308. * @param $field_id
  309. * @param $value
  310. * @return $this
  311. */
  312. protected function _save_field_value( $field_id, $value )
  313. {
  314. update_post_meta( $this->_id, '_field_' . $field_id, $value );
  315. return $this;
  316. }
  317. /**
  318. * Save Field Values
  319. *
  320. * @return $this|void
  321. */
  322. protected function _save_field_values()
  323. {
  324. if( ! $this->_field_values ) return FALSE;
  325. foreach( $this->_field_values as $field_id => $value )
  326. {
  327. $this->_save_field_value( $field_id, $value );
  328. }
  329. update_post_meta( $this->_id, '_form_id', $this->_form_id );
  330. update_post_meta( $this->_id, '_seq_num', $this->_seq_num );
  331. return $this;
  332. }
  333. protected function _save_extra_values()
  334. {
  335. if( ! $this->_extra_values ) return FALSE;
  336. foreach( $this->_extra_values as $key => $value )
  337. {
  338. if( property_exists( $this, $key ) ) continue;
  339. update_post_meta( $this->_id, $key, $value );
  340. }
  341. }
  342. /*
  343. * UTILITIES
  344. */
  345. /**
  346. * Format Meta Query
  347. *
  348. * @param array $where
  349. * @return array
  350. */
  351. protected function format_meta_query( array $where = array() )
  352. {
  353. $return = array(
  354. array(
  355. 'key' => '_form_id',
  356. 'value' => $this->_form_id
  357. )
  358. );
  359. if( ! empty( $where ) ) {
  360. foreach ($where as $ref => $value) {
  361. $field_id = ( is_int( $ref ) ) ? $ref : $this->get_field_id_by_key( $ref );
  362. $return[] = ( is_array($value) ) ? $value : array('key' => "_field_$field_id", 'value' => $value);
  363. }
  364. }
  365. return $return;
  366. }
  367. /**
  368. * Get Field ID By Key
  369. *
  370. * @param $field_key
  371. * @return mixed
  372. */
  373. protected function get_field_id_by_key( $field_key )
  374. {
  375. global $wpdb;
  376. $field_id = $wpdb->get_var( "SELECT id FROM {$wpdb->prefix}nf3_fields WHERE `key` = '{$field_key}' AND `parent_id` = {$this->_form_id}" );
  377. return $field_id;
  378. }
  379. public static function sort_fields( $a, $b )
  380. {
  381. if ( $a->get_setting( 'order' ) == $b->get_setting( 'order' ) ) {
  382. return 0;
  383. }
  384. return ( $a->get_setting( 'order' ) < $b->get_setting( 'order' ) ) ? -1 : 1;
  385. }
  386. } // End NF_Database_Models_Submission