calc.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. <?php if ( ! defined( 'ABSPATH' ) ) exit;
  2. /**
  3. * Function to register a new field for calculations
  4. *
  5. * @since 2.2.28
  6. * @return void
  7. */
  8. function ninja_forms_register_field_calc() {
  9. $args = array(
  10. 'name' => __( 'Calculation', 'ninja-forms' ),
  11. 'sidebar' => 'template_fields',
  12. 'edit_function' => 'ninja_forms_field_calc_edit',
  13. 'display_function' => 'ninja_forms_field_calc_display',
  14. 'group' => 'standard_fields',
  15. 'edit_conditional' => true,
  16. 'edit_req' => false,
  17. 'edit_label' => false,
  18. 'edit_label_pos' => false,
  19. 'edit_custom_class' => false,
  20. 'edit_help' => false,
  21. //'process_field' => false,
  22. //'pre_process' => 'ninja_forms_field_calc_strip_currency_symbol',
  23. 'edit_options' => array(
  24. array(
  25. 'type' => 'hidden',
  26. 'name' => 'payment_field_group',
  27. 'default' => 1,
  28. ),
  29. array(
  30. 'type' => 'hidden',
  31. 'name' => 'payment_total',
  32. //'label' => __( 'Total', 'ninja-forms' ),
  33. ),
  34. array(
  35. 'type' => 'hidden',
  36. 'name' => 'payment_sub_total',
  37. //'label' => __( 'Sub Total', 'ninja-forms' ),
  38. ),
  39. array(
  40. 'type' => 'text',
  41. 'name' => 'calc_places',
  42. 'label' => __( 'Number of decimal places.', 'ninja-forms' ),
  43. 'default' => 2,
  44. ),
  45. ),
  46. 'conditional' => array(
  47. 'value' => array(
  48. 'type' => 'text',
  49. ),
  50. ),
  51. );
  52. ninja_forms_register_field( '_calc', $args );
  53. }
  54. add_action( 'init', 'ninja_forms_register_field_calc' );
  55. /**
  56. * Function that filters the field LI label on the edit field back-end.
  57. *
  58. * @since 2.2.28
  59. * @return $li_label
  60. */
  61. function ninja_forms_calc_edit_label_filter( $li_label, $field_id ) {
  62. $field_row = ninja_forms_get_field_by_id( $field_id );
  63. if ( $field_row['type'] == '_calc' ) {
  64. if ( isset ( $field_row['data']['calc_name'] ) ) {
  65. $li_label = $field_row['data']['calc_name'];
  66. } else {
  67. $li_label = __( 'Calculation', 'ninja-forms' );
  68. }
  69. }
  70. return $li_label;
  71. }
  72. add_filter( 'ninja_forms_edit_field_li_label', 'ninja_forms_calc_edit_label_filter', 10, 2 );
  73. /**
  74. * Function that outputs the edit options for our calculation field
  75. *
  76. * @since 2.2.28
  77. * @return void
  78. */
  79. function ninja_forms_field_calc_edit( $field_id, $data ) {
  80. $calc_name = isset ( $data['calc_name'] ) ? $data['calc_name'] : 'calc_name';
  81. $default_value = isset ( $data['default_value'] ) ? $data['default_value'] : '';
  82. $calc_payment = isset ( $data['calc_payment'] ) ? $data['calc_payment'] : '';
  83. $calc_autho = isset ( $data['calc_auto'] ) ? $data['calc_auto'] : 0;
  84. // Output calculation display type
  85. $options = array(
  86. array( 'name' => __( '- None', 'ninja-forms' ), 'value' => 'hidden' ),
  87. array( 'name' => __( 'Textbox', 'ninja-forms' ), 'value' => 'text'),
  88. array( 'name' => __( 'HTML', 'ninja-forms' ), 'value' => 'html'),
  89. );
  90. $calc_display_type = isset ( $data['calc_display_type'] ) ? $data['calc_display_type'] : 'text';
  91. ninja_forms_edit_field_el_output($field_id, 'select', __( 'Output calculation as', 'ninja-forms' ), 'calc_display_type', $calc_display_type, 'wide', $options, 'widefat ninja-forms-calc-display');
  92. // If the calc_display_type is set to text, then we have several options to output.
  93. // Set the output to hidden for these options if the calc_display_type is not set to text.
  94. if ( $calc_display_type != 'text' ) {
  95. $class = 'hidden';
  96. } else {
  97. $class = '';
  98. }
  99. echo '<div id="ninja_forms_field_'.$field_id.'_calc_text_display" class="'.$class.'">';
  100. // Output a label input textbox.
  101. $label = isset ( $data['label'] ) ? stripslashes( $data['label'] ) : __( 'Calculation', 'ninja-forms' );
  102. ninja_forms_edit_field_el_output($field_id, 'text', __( 'Label', 'ninja-forms' ), 'label', $label, 'wide', '', 'widefat');
  103. // Output a label position select box.
  104. if ( isset ( $data['label_pos'] ) ) {
  105. $label_pos = $data['label_pos'];
  106. } else {
  107. $label_pos = '';
  108. }
  109. $options = array(
  110. array('name' => __( 'Left of Element', 'ninja-forms' ), 'value' => 'left'),
  111. array('name' => __( 'Above Element', 'ninja-forms' ), 'value' => 'above'),
  112. array('name' => __( 'Below Element', 'ninja-forms' ), 'value' => 'below'),
  113. array('name' => __( 'Right of Element', 'ninja-forms' ), 'value' => 'right'),
  114. );
  115. ninja_forms_edit_field_el_output($field_id, 'select', __( 'Label Position', 'ninja-forms' ), 'label_pos', $label_pos, 'wide', $options, 'widefat');
  116. // Output a disabled option checkbox.
  117. if( isset ( $data['calc_display_text_disabled'] ) ) {
  118. $calc_display_text_disabled = $data['calc_display_text_disabled'];
  119. } else {
  120. $calc_display_text_disabled = 1;
  121. }
  122. ninja_forms_edit_field_el_output($field_id, 'checkbox', __( 'Disable input?', 'ninja-forms' ), 'calc_display_text_disabled', $calc_display_text_disabled, 'wide', '', '');
  123. echo '</div>';
  124. // Set the output to hidden for the HTML RTE if the calc_display_type is not set to HTML.
  125. if ( $calc_display_type != 'html' ) {
  126. $class = 'hidden';
  127. } else {
  128. $class = '';
  129. }
  130. // Output our RTE. This is the only extra setting needed if the calc_display_type is set to HTML.
  131. if ( isset ( $data['calc_display_html'] ) ) {
  132. $calc_display_html = $data['calc_display_html'];
  133. } else {
  134. $calc_display_html = '[ninja_forms_calc]';
  135. }
  136. echo '<div id="ninja_forms_field_'.$field_id.'_calc_html_display" class="'.$class.'">';
  137. ninja_forms_edit_field_el_output($field_id, 'rte', '', 'calc_display_html', $calc_display_html, '', '', '', __( 'Use the following shortcode to insert the final calculation: [ninja_forms_calc]', 'ninja-forms' ) );
  138. echo '</div>';
  139. if ( isset ( $data['calc_method'] ) ) {
  140. $calc_method = $data['calc_method'];
  141. } else {
  142. $calc_method = 'auto';
  143. }
  144. switch ( $calc_method ) {
  145. case 'auto':
  146. $eq_class = 'hidden';
  147. $field_class = 'hidden';
  148. break;
  149. case 'fields':
  150. $eq_class = 'hidden';
  151. $field_class = '';
  152. break;
  153. case 'eq':
  154. $eq_class = '';
  155. $field_class = 'hidden';
  156. break;
  157. }
  158. if ( isset ( $data['calc_eq'] ) ) {
  159. $calc_eq = $data['calc_eq'];
  160. } else {
  161. $calc_eq = '';
  162. }
  163. if ( isset ( $data['calc'] ) AND $data['calc'] != '' ) {
  164. $calc = $data['calc'];
  165. } else {
  166. $calc = array();
  167. }
  168. $desc = '<p>' . sprintf( __( 'You can enter calculation equations here using field_x where x is the ID of the field you want to use. For example, %sfield_53 + field_28 + field_65%s.', 'field_ should NOT be translated.', 'ninja-forms' ), '<strong>', '</strong>' ) . '</p>';
  169. $desc .= '<p>' . sprintf( __( 'Complex equations can be created by adding parentheses: %s( field_45 * field_2 ) / 2%s.', 'field_ should NOT be translated.', 'ninja-forms' ), '<strong>', '</strong>' ) . '</p>';
  170. $desc .= '<p>' .__( 'Please use these operators: + - * /. This is an advanced feature. Watch out for things like division by 0.', 'ninja-forms' ).'</p>';
  171. $options = array(
  172. array( 'name' => __( 'Automatically Total Calculation Values', 'ninja-forms' ), 'value' => 'auto' ),
  173. array( 'name' => __( 'Specify Operations And Fields (Advanced)', 'ninja-forms' ), 'value' => 'fields' ),
  174. array( 'name' => __( 'Use An Equation (Advanced)', 'ninja-forms' ), 'value' => 'eq' ),
  175. );
  176. ninja_forms_edit_field_el_output($field_id, 'select', __( 'Calculation Method', 'ninja-forms' ), 'calc_method', $calc_method, 'wide', $options, 'widefat ninja-forms-calc-method');
  177. ?>
  178. <div class="ninja-forms-calculations <?php echo $field_class;?>">
  179. <div class="label">
  180. <?php _e( 'Field Operations', 'ninja-forms' );?> - <a href="#" name="" id="ninja_forms_field_<?php echo $field_id;?>_add_calc" class="ninja-forms-field-add-calc" rel="<?php echo $field_id;?>"><?php _e( 'Add Operation', 'ninja-forms' );?></a>
  181. <span class="spinner" style="float:left;"></span>
  182. </div>
  183. <input type="hidden" name="ninja_forms_field_<?php echo $field_id;?>[calc]" value="">
  184. <div id="ninja_forms_field_<?php echo $field_id;?>_calc" class="" name="">
  185. <?php
  186. $x = 0;
  187. foreach ( $calc as $c ) {
  188. ninja_forms_output_field_calc_row( $field_id, $c, $x );
  189. $x++;
  190. }
  191. ?>
  192. </div>
  193. </div>
  194. <div class="ninja-forms-eq <?php echo $eq_class;?>">
  195. <?php
  196. ninja_forms_edit_field_el_output($field_id, 'textarea', __( 'Advanced Equation', 'ninja-forms' ), 'calc_eq', $calc_eq, 'wide', '', 'widefat', $desc);
  197. ?>
  198. </div>
  199. <hr>
  200. <?php
  201. }
  202. function nf_field_calc_advanced_settings( $field_id, $data ) {
  203. $field = ninja_forms_get_field_by_id( $field_id );
  204. if ( '_calc' != $field['type'] )
  205. return false;
  206. $calc_name = isset ( $data['calc_name'] ) ? $data['calc_name'] : 'calc_name';
  207. $default_value = isset ( $data['default_value'] ) ? $data['default_value'] : '';
  208. $calc_payment = isset ( $data['calc_payment'] ) ? $data['calc_payment'] : '';
  209. $calc_autho = isset ( $data['calc_auto'] ) ? $data['calc_auto'] : 0;
  210. $calc_display_type = isset ( $data['calc_display_type'] ) ? $data['calc_display_type'] : 'text';
  211. ninja_forms_edit_field_el_output($field_id, 'text', __( 'Calculation name', 'ninja-forms' ), 'calc_name', $calc_name, 'wide', '', 'widefat ninja-forms-calc-name', __( 'This is the programmatic name of your field. Examples are: my_calc, price_total, user-total.', 'ninja-forms' ));
  212. ninja_forms_edit_field_el_output($field_id, 'text', __( 'Default Value', 'ninja-forms' ), 'default_value', $default_value, 'wide', '', 'widefat' );
  213. // If any option besides "none" is selected, then show our custom class and help options.
  214. if ( $calc_display_type == 'hidden' ) {
  215. $class = 'hidden';
  216. } else {
  217. $class = '';
  218. }
  219. if ( isset ( $data['class'] ) ) {
  220. $custom_class = $data['class'];
  221. } else {
  222. $custom_class = '';
  223. }
  224. if ( isset ( $data['show_help'] ) ) {
  225. $show_help = $data['show_help'];
  226. } else {
  227. $show_help = 0;
  228. }
  229. if ( isset ( $data['help_text'] ) ) {
  230. $help_text = $data['help_text'];
  231. } else {
  232. $help_text = '';
  233. }
  234. if( $show_help == 1 ){
  235. $display_span = '';
  236. } else {
  237. $display_span = 'display:none;';
  238. }
  239. echo '<div id="ninja_forms_field_'.$field_id.'_calc_extra_display" class="'.$class.'">';
  240. // Output our custom class textbox.
  241. ninja_forms_edit_field_el_output($field_id, 'text', __( 'Custom CSS Class', 'ninja-forms' ), 'class', $custom_class, 'wide', '', 'widefat');
  242. // Output our help text options.
  243. $help_desc = sprintf(__('If "help text" is enabled, there will be a question mark %s placed next to the input field. Hovering over this question mark will show the help text.', 'ninja-forms'), '<img src="'.NINJA_FORMS_URL.'images/question-ico.gif">');
  244. ninja_forms_edit_field_el_output($field_id, 'checkbox', __( 'Show Help Text', 'ninja-forms' ), 'show_help', $show_help, 'wide', '', 'ninja-forms-show-help');
  245. ?>
  246. <span id="ninja_forms_field_<?php echo $field_id;?>_help_span" style="<?php echo $display_span;?>">
  247. <?php
  248. ninja_forms_edit_field_el_output($field_id, 'textarea', __( 'Help Text', 'ninja-forms' ), 'help_text', $help_text, 'wide', '', 'widefat', $help_desc);
  249. ?>
  250. </span>
  251. <?php
  252. echo '</div>';
  253. }
  254. add_action( 'nf_edit_field_advanced', 'nf_field_calc_advanced_settings', 7, 2 );
  255. /**
  256. * Function that outputs the display for our calculation field
  257. *
  258. * @since 2.2.28
  259. * @return void
  260. */
  261. function ninja_forms_field_calc_display( $field_id, $data, $form_id = '' ){
  262. if ( isset( $data['default_value'] ) ) {
  263. $default_value = $data['default_value'];
  264. } else {
  265. $default_value = 0;
  266. }
  267. if ( $default_value == '' ) {
  268. $default_value = 0;
  269. }
  270. if ( isset ( $data['calc_display_text_disabled'] ) AND $data['calc_display_text_disabled'] == 1 ) {
  271. $disabled = "disabled";
  272. } else {
  273. $disabled = '';
  274. }
  275. if ( isset ( $data['calc_display_type'] ) ) {
  276. $calc_display_type = $data['calc_display_type'];
  277. } else {
  278. $calc_display_type = 'text';
  279. }
  280. if ( isset ( $data['calc_display_html'] ) ) {
  281. $calc_display_html = $data['calc_display_html'];
  282. } else {
  283. $calc_display_html = '';
  284. }
  285. if ( isset ( $data['calc_method'] ) ) {
  286. $calc_method = $data['calc_method'];
  287. } else {
  288. $calc_method = '';
  289. }
  290. $field_class = ninja_forms_get_field_class( $field_id, $form_id );
  291. ?>
  292. <input type="hidden" name="ninja_forms_field_<?php echo $field_id;?>" value="<?php echo $default_value;?>" class="<?php echo $field_class;?>">
  293. <?php
  294. switch ( $calc_display_type ) {
  295. case 'text':
  296. ?>
  297. <input type="text" id="ninja_forms_field_<?php echo $field_id;?>" name="ninja_forms_field_<?php echo $field_id;?>" value="<?php echo $default_value;?>" <?php echo $disabled;?> class="<?php echo $field_class;?>" rel="<?php echo $field_id;?>">
  298. <?php
  299. break;
  300. case 'html':
  301. $calc_display_html = str_replace( '[ninja_forms_calc]', '<span id="ninja_forms_field_'.$field_id.'" class="'.$field_class.'" rel="'.$field_id.'">'.$default_value.'</span>', $calc_display_html );
  302. echo $calc_display_html;
  303. break;
  304. }
  305. }
  306. /**
  307. * Function to output specific calculation options for a given field
  308. *
  309. * @param int $field_id - ID of the field being edited.
  310. * @param array $c - Array containing the data.
  311. * @param int $x - Index for this row of the calc array.
  312. * @since 2.2.28
  313. * @returns void
  314. */
  315. function ninja_forms_output_field_calc_row( $field_id, $c = array(), $x = 0 ){
  316. global $ninja_forms_fields;
  317. $field_row = ninja_forms_get_field_by_id( $field_id );
  318. $field_type = $field_row['type'];
  319. $form_id = $field_row['form_id'];
  320. if ( isset ( $c['field'] ) ) {
  321. $calc_field = $c['field'];
  322. } else {
  323. $calc_field = '';
  324. }
  325. if ( isset ( $c['op'] ) ) {
  326. $op = $c['op'];
  327. } else {
  328. $op = '';
  329. }
  330. ?>
  331. <div id="ninja_forms_field_<?php echo $field_id;?>_calc_row_<?php echo $x;?>" class="ninja-forms-calc-row" rel="<?php echo $x;?>">
  332. <a href="#" id="ninja_forms_field_<?php echo $field_id;?>_remove_calc" name="<?php echo $x;?>" rel="<?php echo $field_id;?>" class="ninja-forms-field-remove-calc">X</a>
  333. <select name="ninja_forms_field_<?php echo $field_id;?>[calc][<?php echo $x;?>][op]">
  334. <option value="add" <?php selected( $op, 'add' );?>>+</option>
  335. <option value="subtract" <?php selected( $op, 'subtract' );?>>-</option>
  336. <option value="multiply" <?php selected( $op, 'multiply' );?>>*</option>
  337. <option value="divide" <?php selected( $op, 'divide' );?>>/</option>
  338. </select>
  339. <select name="ninja_forms_field_<?php echo $field_id;?>[calc][<?php echo $x;?>][field]" class="ninja-forms-calc-select">
  340. <option value=""><?php _e( '- Select a Field', 'ninja-forms' );?></option>
  341. <?php
  342. // Loop through our fields and output all of our calculation fields.
  343. $fields = ninja_forms_get_fields_by_form_id( $form_id );
  344. foreach ( $fields as $field ) {
  345. if ( isset ( $field['data']['label'] ) ) {
  346. $label = $field['data']['label'];
  347. } else {
  348. $label = '';
  349. }
  350. if ( strlen ( $label ) > 15 ) {
  351. $label = substr ( $label, 0, 15 );
  352. $label .= '...';
  353. }
  354. $process_field = $ninja_forms_fields[$field['type']]['process_field'];
  355. if ( $field['id'] != $field_id AND $process_field ) {
  356. ?>
  357. <option value="<?php echo $field['id'];?>" <?php selected( $calc_field, $field['id'] );?>><?php echo $field['id'];?> - <?php echo $label;?></option>
  358. <?php
  359. }
  360. }
  361. ?>
  362. </select>
  363. </div>
  364. <?php
  365. }
  366. /**
  367. * Function that runs during pre_processing and calcuates the value of this field.
  368. *
  369. * @since 2.2.30
  370. * @return void
  371. */
  372. function ninja_forms_field_calc_pre_process(){
  373. global $ninja_forms_loading, $ninja_forms_processing, $wp_locale;
  374. if ( isset ( $ninja_forms_loading ) ) {
  375. $form_id = $ninja_forms_loading->get_form_ID();
  376. $all_fields = $ninja_forms_loading->get_all_fields();
  377. } else {
  378. $form_id = $ninja_forms_processing->get_form_ID();
  379. $all_fields = $ninja_forms_processing->get_all_fields();
  380. }
  381. if ( is_array ( $all_fields ) ) {
  382. foreach ( $all_fields as $field_id => $user_value ) {
  383. if ( isset ( $ninja_forms_loading ) ) {
  384. $field_row = $ninja_forms_loading->get_field_settings( $field_id );
  385. } else {
  386. $field_row = $ninja_forms_processing->get_field_settings( $field_id );
  387. }
  388. if ( isset ( $field_row['type'] ) ) {
  389. $field_type = $field_row['type'];
  390. } else {
  391. $field_type = '';
  392. }
  393. if ( $field_type == '_calc' ) {
  394. $field_data = $field_row['data'];
  395. if ( isset ( $field_data['default_value'] ) ){
  396. $default_value = $field_data['default_value'];
  397. } else {
  398. $default_value = 0;
  399. }
  400. $result = $default_value;
  401. // Figure out which method we are using to calculate this field.
  402. if ( isset ( $field_data['calc_method'] ) ) {
  403. $calc_method = $field_data['calc_method'];
  404. } else {
  405. $calc_method = 'auto';
  406. }
  407. // Get our advanced field op settings if they exist.
  408. if ( isset ( $field_data['calc'] ) ) {
  409. $calc_fields = $field_data['calc'];
  410. } else {
  411. $calc_fields = array();
  412. }
  413. // Get our calculation equation if it exists.
  414. if ( isset ( $field_data['calc_eq'] ) ) {
  415. $calc_eq = $field_data['calc_eq'];
  416. } else {
  417. $calc_eq = array();
  418. }
  419. // Get our calculation equation if it exists.
  420. if ( isset ( $field_data['calc_places'] ) ) {
  421. $calc_places = $field_data['calc_places'];
  422. } else {
  423. $calc_places = 0;
  424. }
  425. // Figure out if there is a sub_total and a tax field. If there are, and this is a total field set to calc_method auto, we're using an equation, not auto.
  426. $tax = false;
  427. $sub_total = false;
  428. if ( is_array ( $all_fields ) ) {
  429. foreach ( $all_fields as $f_id => $user_value ) {
  430. if ( isset ( $ninja_forms_loading ) ) {
  431. $field = $ninja_forms_loading->get_field_settings( $f_id );
  432. } else {
  433. $field = $ninja_forms_processing->get_field_settings( $f_id );
  434. }
  435. if ( isset ( $field['type'] ) ) {
  436. $f_type = $field['type'];
  437. } else {
  438. $f_type = '';
  439. }
  440. $data = apply_filters( 'ninja_forms_field', $field['data'], $f_id );
  441. if ( $f_type == '_tax' ) {
  442. // There is a tax field; save its field_id.
  443. $tax = $field['id'];
  444. } else if ( isset ( $data['payment_sub_total'] ) AND $data['payment_sub_total'] == 1 ) {
  445. // There is a sub_total field; save its field_id.
  446. $sub_total = $field['id'];
  447. }
  448. }
  449. }
  450. // If the tax and sub_total have been found, and this is a total field set to auto, change the calc_method and calc_eq.
  451. if ( $tax AND $sub_total AND isset ( $field_data['payment_total'] ) AND $field_data['payment_total'] == 1 AND $calc_method == 'auto' ) {
  452. $calc_method = 'eq';
  453. if ( isset ( $ninja_forms_loading ) ) {
  454. $tax_rate = $ninja_forms_loading->get_field_value( $tax );
  455. } else {
  456. $tax_rate = $ninja_forms_processing->get_field_value( $tax );
  457. }
  458. if ( strpos( $tax_rate, "%" ) !== false ) {
  459. $tax_rate = str_replace( "%", "", $tax_rate );
  460. $tax_rate = $tax_rate / 100;
  461. }
  462. $calc_eq = 'field_'.$sub_total.' + ( field_'.$sub_total.' * '.$tax_rate.' )';
  463. if ( isset ( $ninja_forms_loading ) ) {
  464. $field_settings = $ninja_forms_loading->get_field_settings( $field_id );
  465. } else {
  466. $field_settings = $ninja_forms_processing->get_field_settings( $field_id );
  467. }
  468. $field_settings['data']['calc_method'] = $calc_method;
  469. $field_settings['data']['calc_eq'] = $calc_eq;
  470. if ( isset ( $ninja_forms_loading ) ) {
  471. $ninja_forms_loading->update_field_settings( $field_id, $field_settings );
  472. } else {
  473. $ninja_forms_processing->update_field_settings( $field_id, $field_settings );
  474. }
  475. }
  476. // Loop through our fields and see which ones should be used for calculations.
  477. if ( is_array ( $all_fields ) ) {
  478. foreach ( $all_fields as $f_id => $user_value ) {
  479. if ( isset ( $ninja_forms_loading ) ) {
  480. $field = $ninja_forms_loading->get_field_settings( $f_id );
  481. $field_value = $ninja_forms_loading->get_field_value( $f_id );
  482. } else {
  483. $field = $ninja_forms_processing->get_field_settings( $f_id );
  484. $field_value = $ninja_forms_processing->get_field_value( $f_id );
  485. }
  486. $field_data = $field['data'];
  487. if ( $f_id == $tax ) {
  488. $tax = ninja_forms_field_calc_value( $field['id'], $field_value, 'auto' );;
  489. }
  490. switch ( $calc_method ) {
  491. case 'auto': // We are automatically totalling the fields that have a calc_auto_include set to 1.
  492. if ( isset ( $field_data['calc_auto_include'] ) AND $field_data['calc_auto_include'] == 1 && $field_value ) {
  493. if ( $field['type'] == '_calc' ) {
  494. $calc_value = ninja_forms_calc_field_loop( $field['id'], '', $result );
  495. } else {
  496. $calc_value = ninja_forms_field_calc_value( $field['id'], $field_value, $calc_method );
  497. }
  498. if ( $calc_value !== false ) {
  499. $result = ninja_forms_calc_evaluate( 'add', $result, $calc_value );
  500. }
  501. }
  502. break;
  503. case 'fields': // We are performing a specific set of operations on a set of fields.
  504. if ( is_array ( $calc_fields ) ) {
  505. foreach ( $calc_fields as $c ) {
  506. if ( $c['field'] == $field['id'] ) {
  507. if ( $field['type'] == '_calc' ) {
  508. $calc_value = ninja_forms_calc_field_loop( $field['id'], '', $result );
  509. }
  510. $calc_value = ninja_forms_field_calc_value( $field['id'], $field_value, $calc_method );
  511. if ( $calc_value !== false ) {
  512. $result = ninja_forms_calc_evaluate( $c['op'], $result, $calc_value );
  513. }
  514. }
  515. }
  516. }
  517. break;
  518. case 'eq':
  519. if (preg_match("/\bfield_".$f_id."\b/i", $calc_eq ) ) {
  520. if ( $field['type'] == '_calc' ) {
  521. $calc_value = ninja_forms_calc_field_loop( $field['id'], $calc_eq );
  522. } else {
  523. $calc_value = ninja_forms_field_calc_value( $field['id'], $field_value, $calc_method );
  524. }
  525. if ( $calc_value !== false ) {
  526. $calc_eq = preg_replace('/\bfield_'.$field['id'].'\b/', $calc_value, $calc_eq );
  527. }
  528. }
  529. break;
  530. }
  531. }
  532. }
  533. if ( $calc_method == 'eq' ) {
  534. $eq = new eqEOS();
  535. // Swap out decimal separator
  536. $decimal_point = $wp_locale->number_format['decimal_point'];
  537. $calc_eq = str_replace( $decimal_point, '.', $calc_eq );
  538. $result = $eq->solveIF($calc_eq);
  539. // Swap back decimal separator
  540. $result = str_replace( '.', $decimal_point, $result );
  541. }
  542. if ( isset ( $calc_places ) ) {
  543. if ( empty( $calc_places ) ) {
  544. $calc_places = 0;
  545. }
  546. // Swap out decimal separator
  547. $decimal_point = $wp_locale->number_format['decimal_point'];
  548. $result = str_replace( $decimal_point, '.', $result );
  549. // Round and Format
  550. $result = number_format( round( $result, $calc_places ), $calc_places );
  551. // Swap back decimal separator
  552. $result = str_replace( '.', $decimal_point, $result );
  553. }
  554. $result = str_replace( $wp_locale->number_format['thousands_sep'], '', $result );
  555. if ( isset ( $ninja_forms_loading ) ) {
  556. $ninja_forms_loading->update_field_value( $field_id, $result );
  557. } else {
  558. $ninja_forms_processing->update_field_value( $field_id, $result );
  559. }
  560. }
  561. }
  562. }
  563. }
  564. add_action( 'ninja_forms_pre_process', 'ninja_forms_field_calc_pre_process', 999 );
  565. function ninja_forms_calc_check_load() {
  566. global $ninja_forms_processing;
  567. if ( ! is_object ( $ninja_forms_processing ) ) {
  568. ninja_forms_field_calc_pre_process();
  569. }
  570. }
  571. add_action( 'ninja_forms_display_pre_init', 'ninja_forms_calc_check_load', 999 );
  572. function ninja_forms_calc_field_loop( $field_id, $calc_eq = '', $result = '' ) {
  573. global $ninja_forms_loading, $ninja_forms_processing;
  574. if ( isset ( $ninja_forms_loading ) ) {
  575. $field_settings = $ninja_forms_loading->get_field_settings( $field_id );
  576. } else {
  577. $field_settings = $ninja_forms_processing->get_field_settings( $field_id );
  578. }
  579. $calc_data = $field_settings['data'];
  580. // Figure out which method we are using to calculate this field.
  581. if ( isset ( $calc_data['calc_method'] ) ) {
  582. $calc_method = $calc_data['calc_method'];
  583. } else {
  584. $calc_method = 'auto';
  585. }
  586. // Get our advanced field op settings if they exist.
  587. if ( isset ( $calc_data['calc'] ) ) {
  588. $calc_fields = $calc_data['calc'];
  589. } else {
  590. $calc_fields = array();
  591. }
  592. // Get our calculation equation if it exists.
  593. if ( isset ( $calc_data['calc_eq'] ) ) {
  594. $calc_eq = $calc_data['calc_eq'];
  595. } else {
  596. $calc_eq = array();
  597. }
  598. if ( isset ( $ninja_forms_loading ) ) {
  599. $form_id = $ninja_forms_loading->get_form_ID();
  600. $all_fields = $ninja_forms_loading->get_all_fields();
  601. } else {
  602. $form_id = $ninja_forms_processing->get_form_ID();
  603. $all_fields = $ninja_forms_processing->get_all_fields();
  604. }
  605. // Figure out if there is a sub_total and a tax field. If there are, and this is a total field set to calc_method auto, we're using an equation, not auto.
  606. $tax = false;
  607. $sub_total = false;
  608. foreach ( $all_fields as $f_id => $user_value ) {
  609. if ( isset ( $ninja_forms_loading ) ) {
  610. $field = $ninja_forms_loading->get_field_settings( $f_id );
  611. } else {
  612. $field = $ninja_forms_processing->get_field_settings( $f_id );
  613. }
  614. $field_value = $user_value;
  615. $data = $field['data'];
  616. if ( $field['type'] == '_tax' ) {
  617. // There is a tax field; save its field_id.
  618. $tax = $field['id'];
  619. } else if ( isset ( $data['payment_sub_total'] ) AND $data['payment_sub_total'] == 1 ) {
  620. // There is a sub_total field; save its field_id.
  621. $sub_total = $field['id'];
  622. }
  623. }
  624. // If the tax and sub_total have been found, and this is a total field set to auto, change the calc_method and calc_eq.
  625. if ( $tax AND $sub_total AND isset ( $calc_data['payment_total'] ) AND $calc_data['payment_total'] == 1 AND $calc_method == 'auto' ) {
  626. $calc_method = 'eq';
  627. if ( isset ( $ninja_forms_loading ) ) {
  628. $tax_rate = $ninja_forms_loading->get_field_value( $tax );
  629. } else {
  630. $tax_rate = $ninja_forms_processing->get_field_value( $tax );
  631. }
  632. if ( strpos( $tax_rate, "%" ) !== false ) {
  633. $tax_rate = str_replace( "%", "", $tax_rate );
  634. $tax_rate = $tax_rate / 100;
  635. }
  636. $calc_eq = 'field_'.$sub_total.' + ( field_'.$sub_total.' * '.$tax_rate.' )';
  637. }
  638. // Figure out how many calculation fields we have and run
  639. foreach ( $all_fields as $f_id => $user_value ) {
  640. if ( isset ( $ninja_forms_loading ) ) {
  641. $field = $ninja_forms_loading->get_field_settings( $f_id );
  642. $field_value = $ninja_forms_loading->get_field_value( $f_id );
  643. } else {
  644. $field = $ninja_forms_processing->get_field_settings( $f_id );
  645. $field_value = $ninja_forms_processing->get_field_value( $f_id );
  646. }
  647. $field_data = $field['data'];
  648. if ( $f_id != $field_id ) {
  649. switch ( $calc_method ) {
  650. case 'auto': // We are automatically totalling the fields that have a calc_auto_include set to 1.
  651. if ( isset ( $field_data['calc_auto_include'] ) AND $field_data['calc_auto_include'] == 1 ) {
  652. if ( $field['type'] == '_calc' ) {
  653. $calc_value = ninja_forms_calc_field_loop( $field['id'], '', $result );
  654. } else {
  655. $calc_value = ninja_forms_field_calc_value( $field['id'], $field_value, $calc_method );
  656. }
  657. if ( $calc_value !== false ) {
  658. $result = ninja_forms_calc_evaluate( 'add', $result, $calc_value );
  659. }
  660. }
  661. break;
  662. case 'fields': // We are performing a specific set of operations on a set of fields.
  663. if ( is_array ( $calc_fields ) ) {
  664. foreach ( $calc_fields as $c ) {
  665. if ( $c['field'] == $field['id'] ) {
  666. if ( $field['type'] == '_calc' ) {
  667. $result = ninja_forms_calc_field_loop( $field['id'], '', $result );
  668. } else {
  669. $calc_value = ninja_forms_field_calc_value( $field['id'], $field_value, $calc_method );
  670. if ( $calc_value !== false ) {
  671. $result = ninja_forms_calc_evaluate( $c['op'], $result, $calc_value );
  672. }
  673. }
  674. }
  675. }
  676. }
  677. break;
  678. case 'eq':
  679. if (preg_match("/\bfield_".$field['id']."\b/i", $calc_eq ) ) {
  680. if ( $field['type'] == '_calc' ) {
  681. $calc_value = ninja_forms_calc_field_loop( $field['id'], $calc_eq, $result );
  682. } else {
  683. $calc_value = ninja_forms_field_calc_value( $field['id'], $field_value, $calc_method );
  684. }
  685. if ( $calc_value !== false ) {
  686. $calc_eq = preg_replace('/\bfield_'.$field['id'].'\b/', $calc_value, $calc_eq );
  687. }
  688. }
  689. break;
  690. }
  691. }
  692. }
  693. if ( $calc_method == 'eq' ) {
  694. $eq = new eqEOS();
  695. $result = $eq->solveIF($calc_eq);
  696. }
  697. if ( $result == '' ) {
  698. $result = 0;
  699. }
  700. return $result;
  701. }
  702. /**
  703. * Function that filters the list options span and adds the appropriate listener class if there is a calc needed for the field.
  704. *
  705. * @since 2.2.28
  706. * @return $class
  707. */
  708. function ninja_forms_calc_filter_list_options_span( $class, $field_id ) {
  709. global $ninja_forms_loading, $ninja_forms_processing;
  710. if ( isset ( $ninja_forms_loading ) ) {
  711. $field_row = $ninja_forms_loading->get_field_settings( $field_id );
  712. } else {
  713. $field_row = $ninja_forms_processing->get_field_settings( $field_id );
  714. }
  715. $add_class = false;
  716. // Check to see if this field has cal_auto_include set to 1. If it does, we want to output a class name.
  717. if ( isset ( $field_row['data']['calc_auto_include'] ) AND !empty ( $field_row['data']['calc_auto_include'] ) ) {
  718. $add_class = true;
  719. }
  720. if ( isset ( $ninja_forms_loading ) ) {
  721. $all_fields = $ninja_forms_loading->get_all_fields();
  722. } else {
  723. $all_fields = $ninja_forms_processing->get_all_fields();
  724. }
  725. foreach ( $all_fields as $f_id => $user_value ) {
  726. if ( isset ( $ninja_forms_loading ) ) {
  727. $field = $ninja_forms_loading->get_field_settings( $f_id );
  728. } else {
  729. $field = $ninja_forms_processing->get_field_settings( $f_id );
  730. }
  731. if ( isset ( $field['type'] ) && $field['type'] == '_calc' ) {
  732. if ( isset ( $field['data']['calc_method'] ) ) {
  733. $calc_method = $field['data']['calc_method'];
  734. } else {
  735. $calc_method = 'auto';
  736. }
  737. switch ( $calc_method ) {
  738. case 'fields':
  739. if ( isset ( $field['data']['calc'] ) ) {
  740. foreach ( $field['data']['calc'] as $calc ) {
  741. if ( $calc['field'] == $field_id ) {
  742. $add_class = true;
  743. break;
  744. }
  745. }
  746. }
  747. break;
  748. case 'eq':
  749. $eq = $field['data']['calc_eq'];
  750. if (preg_match("/\bfield_".$field_id."\b/i", $eq ) ) {
  751. $add_class = true;
  752. break;
  753. }
  754. break;
  755. }
  756. }
  757. }
  758. if ( $add_class ) {
  759. $class .= ' ninja-forms-field-list-options-span-calc-listen';
  760. }
  761. return $class;
  762. }
  763. add_filter( 'ninja_forms_display_list_options_span_class', 'ninja_forms_calc_filter_list_options_span', 10, 2 );
  764. /**
  765. * Function that takes two variables and our calculation string operator and returns the result.
  766. *
  767. * @since 2.2.28
  768. * @return int value
  769. */
  770. function ninja_forms_calc_evaluate( $op, $value1, $value2 ) {
  771. switch ( $op ) {
  772. case 'add':
  773. return $value1 + $value2;
  774. break;
  775. case 'subtract':
  776. return $value1 - $value2;
  777. break;
  778. case 'multiply':
  779. return $value1 * $value2;
  780. break;
  781. case 'divide':
  782. return $value1 / $value2;
  783. break;
  784. }
  785. }
  786. /**
  787. * Function that returns the calculation value of a field given by field_id if it is to be included in the auto total.
  788. *
  789. * @since 2.2.30
  790. * @return calc_value
  791. */
  792. function ninja_forms_field_calc_value( $field_id, $field_value = '', $calc_method = 'auto' ) {
  793. global $ninja_forms_loading, $ninja_forms_processing, $wp_locale;
  794. if ( isset ( $ninja_forms_loading ) ) {
  795. $field = $ninja_forms_loading->get_field_settings( $field_id );
  796. } else {
  797. $field = $ninja_forms_processing->get_field_settings( $field_id );
  798. }
  799. $field_data = apply_filters( 'ninja_forms_field', $field['data'], $field_id );
  800. if ( isset ( $field_data['default_value'] ) ) {
  801. $default_value = $field_data['default_value'];
  802. } else {
  803. $default_value = '';
  804. }
  805. if ( $field_value == '' ) {
  806. $field_value = $default_value;
  807. }
  808. $calc_value = 0;
  809. if ( $field['type'] == '_list' ) {
  810. if ( isset ( $field_data['list']['options'] ) ) {
  811. foreach ( $field_data['list']['options'] as $option ) {
  812. if ( isset ( $field_data['list_show_value'] ) AND $field_data['list_show_value'] == 1 ) {
  813. $option_value = $option['value'];
  814. } else {
  815. $option_value = $option['label'];
  816. }
  817. if ( $option_value == $field_value OR ( is_array ( $field_value ) AND in_array ( $option_value, $field_value ) ) ) {
  818. $calc_value += $option['calc'];
  819. }
  820. }
  821. }
  822. } else if ( $field['type'] == '_checkbox' ) {
  823. if ( $field_value == 'checked' ){
  824. $calc_value = $field_data['calc_value']['checked'];
  825. } else {
  826. if ( $calc_method == 'auto' ) {
  827. return false;
  828. } else {
  829. $calc_value = $field_data['calc_value']['unchecked'];
  830. }
  831. }
  832. } else {
  833. if ( !$field_value OR $field_value == '' ) {
  834. $field_value = 0;
  835. }
  836. $decimal_point = $wp_locale->number_format['decimal_point'];
  837. /* Casting to a Float removes decimal */
  838. // $calc_value = (float) preg_replace('/[^0-9' . $decimal_point . '-]*/','',$field_value);
  839. $calc_value = preg_replace('/[^0-9' . $decimal_point . '-]*/','',$field_value);
  840. }
  841. if ( is_string( $calc_value ) AND strpos( $calc_value, "%" ) !== false ) {
  842. $calc_value = str_replace( "%", "", $calc_value );
  843. $calc_value = $calc_value / 100;
  844. }
  845. if ( $calc_value == '' OR !$calc_value ) {
  846. $calc_value = 0;
  847. }
  848. return $calc_value;
  849. }