/src/model/Model_Form_Settings.php

  1. <?php 
  2.  
  3. namespace GFPDF\Model; 
  4.  
  5. use GFPDF\Helper\Helper_Abstract_Model; 
  6. use GFPDF\Helper\Helper_PDF_List_Table; 
  7. use GFPDF\Helper\Helper_Interface_Config; 
  8. use GFPDF\Helper\Helper_Abstract_Form; 
  9. use GFPDF\Helper\Helper_Data; 
  10. use GFPDF\Helper\Helper_Misc; 
  11. use GFPDF\Helper\Helper_Notices; 
  12. use GFPDF\Helper\Helper_Templates; 
  13. use GFPDF\Helper\Helper_Abstract_Options; 
  14.  
  15. use Psr\Log\LoggerInterface; 
  16.  
  17. use _WP_Editors; 
  18.  
  19. /** 
  20. * Settings Model 
  21. * 
  22. * @package Gravity PDF 
  23. * @copyright Copyright (c) 2016, Blue Liquid Designs 
  24. * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License 
  25. * @since 4.0 
  26. */ 
  27.  
  28. /** Exit if accessed directly */ 
  29. if ( ! defined( 'ABSPATH' ) ) { 
  30. exit; 
  31.  
  32. /** 
  33. This file is part of Gravity PDF. 
  34.   
  35. Gravity PDF * Copyright (C) 2016, Blue Liquid Designs 
  36.   
  37. This program is free software; you can redistribute it and/or modify 
  38. it under the terms of the GNU General Public License as published by 
  39. the Free Software Foundation; either version 2 of the License, or 
  40. (at your option) any later version. 
  41.   
  42. This program is distributed in the hope that it will be useful,  
  43. but WITHOUT ANY WARRANTY; without even the implied warranty of 
  44. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
  45. GNU General Public License for more details. 
  46.   
  47. You should have received a copy of the GNU General Public License 
  48. along with this program; if not, write to the Free Software 
  49. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
  50. */ 
  51.  
  52. /** 
  53. * Model_Welcome_Screen 
  54. * 
  55. * A general class for About / Intro Screen 
  56. * 
  57. * @since 4.0 
  58. */ 
  59. class Model_Form_Settings extends Helper_Abstract_Model { 
  60.  
  61. /** 
  62. * Holds the abstracted Gravity Forms API specific to Gravity PDF 
  63. * 
  64. * @var \GFPDF\Helper\Helper_Form 
  65. * 
  66. * @since 4.0 
  67. */ 
  68. protected $gform; 
  69.  
  70. /** 
  71. * Holds our log class 
  72. * 
  73. * @var \Monolog\Logger|LoggerInterface 
  74. * 
  75. * @since 4.0 
  76. */ 
  77. protected $log; 
  78.  
  79. /** 
  80. * Holds our Helper_Data object 
  81. * which we can autoload with any data needed 
  82. * 
  83. * @var \GFPDF\Helper\Helper_Data 
  84. * 
  85. * @since 4.0 
  86. */ 
  87. protected $data; 
  88.  
  89. /** 
  90. * Holds our Helper_Abstract_Options / Helper_Options_Fields object 
  91. * Makes it easy to access global PDF settings and individual form PDF settings 
  92. * 
  93. * @var \GFPDF\Helper\Helper_Options_Fields 
  94. * 
  95. * @since 4.0 
  96. */ 
  97. protected $options; 
  98.  
  99. /** 
  100. * Holds our Helper_Misc object 
  101. * Makes it easy to access common methods throughout the plugin 
  102. * 
  103. * @var \GFPDF\Helper\Helper_Misc 
  104. * 
  105. * @since 4.0 
  106. */ 
  107. protected $misc; 
  108.  
  109. /** 
  110. * Holds our Helper_Notices object 
  111. * which we can use to queue up admin messages for the user 
  112. * 
  113. * @var \GFPDF\Helper\Helper_Misc 
  114. * 
  115. * @since 4.0 
  116. */ 
  117. protected $notices; 
  118.  
  119. /** 
  120. * Holds our Helper_Templates object 
  121. * used to ease access to our PDF templates 
  122. * 
  123. * @var \GFPDF\Helper\Helper_Templates 
  124. * 
  125. * @since 4.0 
  126. */ 
  127. protected $templates; 
  128.  
  129. /** 
  130. * Setup our class by injecting all our dependancies 
  131. * 
  132. * @param \GFPDF\Helper\Helper_Abstract_Form $gform Our abstracted Gravity Forms helper functions 
  133. * @param \Monolog\Logger|LoggerInterface $log Our logger class 
  134. * @param \GFPDF\Helper\Helper_Data $data Our plugin data store 
  135. * @param \GFPDF\Helper\Helper_Abstract_Options $options Our options class which allows us to access any settings 
  136. * @param \GFPDF\Helper\Helper_Misc $misc Our miscellaneous class 
  137. * @param \GFPDF\Helper\Helper_Notices $notices Our notice class used to queue admin messages and errors 
  138. * @param \GFPDF\Helper\Helper_Templates $templates 
  139. * 
  140. * @since 4.0 
  141. */ 
  142. public function __construct( Helper_Abstract_Form $gform, LoggerInterface $log, Helper_Data $data, Helper_Abstract_Options $options, Helper_Misc $misc, Helper_Notices $notices, Helper_Templates $templates ) { 
  143.  
  144. /** Assign our internal variables */ 
  145. $this->gform = $gform; 
  146. $this->log = $log; 
  147. $this->data = $data; 
  148. $this->options = $options; 
  149. $this->misc = $misc; 
  150. $this->notices = $notices; 
  151. $this->templates = $templates; 
  152.  
  153. /** 
  154. * Add the form settings tab. 
  155. * 
  156. * Override this function to add the tab conditionally. 
  157. * 
  158. * @param array $tabs The list of existing tags 
  159. * 
  160. * @return array modified list of $tabs 
  161. * 
  162. * @since 4.0 
  163. */ 
  164. public function add_form_settings_menu( $tabs ) { 
  165. $tabs[] = [ 
  166. 'name' => $this->data->slug,  
  167. 'label' => $this->data->short_title,  
  168. 'query' => [ 'pid' => null ],  
  169. ]; 
  170.  
  171. return $tabs; 
  172.  
  173. /** 
  174. * Setup the PDF Settings List View Logic 
  175. * 
  176. * @param integer $form_id The Gravity Form ID 
  177. * 
  178. * @return void 
  179. * 
  180. * @since 4.0 
  181. */ 
  182. public function process_list_view( $form_id ) { 
  183.  
  184. /** prevent unauthorized access */ 
  185. if ( ! $this->gform->has_capability( 'gravityforms_edit_settings' ) ) { 
  186. $this->log->addWarning( 'Lack of User Capabilities.' ); 
  187. wp_die( esc_html__( 'You do not have permission to access this page', 'gravity-forms-pdf-extended' ) ); 
  188.  
  189. $controller = $this->getController(); 
  190.  
  191. /** get the form object */ 
  192. $form = $this->gform->get_form( $form_id ); 
  193.  
  194. /** load our list table */ 
  195. $pdf_table = new Helper_PDF_List_Table( $form, $this->gform, $this->misc, $this->templates ); 
  196. $pdf_table->prepare_items(); 
  197.  
  198. /** pass to view */ 
  199. $controller->view->list( [ 
  200. 'title' => $this->data->title,  
  201. 'add_new_url' => $add_new_url = add_query_arg( [ 'pid' => 0 ] ),  
  202. 'list_items' => $pdf_table,  
  203. ] ); 
  204.  
  205. /** 
  206. * Setup the PDF Settings Add/Edit View Logic 
  207. * 
  208. * @param integer $form_id The Gravity Form ID 
  209. * @param integer $pdf_id The PDF configuration ID 
  210. * 
  211. * @return void 
  212. * 
  213. * @since 4.0 
  214. */ 
  215. public function show_edit_view( $form_id, $pdf_id ) { 
  216.  
  217. /** prevent unauthorized access */ 
  218. if ( ! $this->gform->has_capability( 'gravityforms_edit_settings' ) ) { 
  219. $this->log->addWarning( 'Lack of User Capabilities.' ); 
  220. wp_die( esc_html__( 'You do not have permission to access this page', 'gravity-forms-pdf-extended' ) ); 
  221.  
  222. $controller = $this->getController(); 
  223.  
  224. /** get the form object */ 
  225. $form = $this->gform->get_form( $form_id ); 
  226.  
  227. /** parse input and get required information */ 
  228. if ( ! $pdf_id ) { 
  229. if ( rgpost( 'gform_pdf_id' ) ) { 
  230. $pdf_id = rgpost( 'gform_pdf_id' ); 
  231. } else { 
  232. $pdf_id = uniqid(); 
  233.  
  234. /** re-register all our settings to show form-specific options */ 
  235. $this->options->register_settings( $this->options->get_registered_fields() ); 
  236.  
  237. /** re-register our Gravity Forms Notifications */ 
  238. $this->register_notifications( $form['notifications'] ); 
  239.  
  240. /** Pull the PDF settings */ 
  241. $pdf = $this->options->get_pdf( $form_id, $pdf_id ); 
  242.  
  243. /** prepare our data */ 
  244. $label = ( ! is_wp_error( $pdf ) && ! isset( $pdf['status'] ) ) ? esc_html__( 'Update PDF', 'gravity-forms-pdf-extended' ) : esc_html__( 'Add PDF', 'gravity-forms-pdf-extended' ); 
  245.  
  246. /** pass to view */ 
  247. $controller->view->add_edit( [ 
  248. 'pdf_id' => $pdf_id,  
  249. 'title' => $label,  
  250. 'button_label' => $label,  
  251. 'form' => $form,  
  252. 'pdf' => $pdf,  
  253. 'wp_editor_loaded' => class_exists( '_WP_Editors' ),  
  254. ] ); 
  255.  
  256. /** 
  257. * Validate, Sanatize and Update PDF settings 
  258. * 
  259. * @param integer $form_id The Gravity Form ID 
  260. * @param integer $pdf_id The PDF configuration ID 
  261. * 
  262. * @return boolean 
  263. * 
  264. * @since 4.0 
  265. */ 
  266. public function process_submission( $form_id, $pdf_id ) { 
  267.  
  268. /** prevent unauthorized access */ 
  269. if ( ! $this->gform->has_capability( 'gravityforms_edit_settings' ) ) { 
  270.  
  271. $this->log->addCritical( 'Lack of User Capabilities.', [ 
  272. 'user' => wp_get_current_user(),  
  273. 'user_meta' => get_user_meta( get_current_user_id() ),  
  274. ] ); 
  275.  
  276. wp_die( esc_html__( 'You do not have permission to access this page', 'gravity-forms-pdf-extended' ) ); 
  277.  
  278. /** Check Nonce is valid */ 
  279. if ( ! wp_verify_nonce( rgpost( 'gfpdf_save_pdf' ), 'gfpdf_save_pdf' ) ) { 
  280. $this->log->addWarning( 'Nonce Verification Failed.' ); 
  281. $this->notices->add_error( esc_html__( 'There was a problem saving your PDF settings. Please try again.', 'gravity-forms-pdf-extended' ) ); 
  282.  
  283. return false; 
  284.  
  285. /** Check if we have a new PDF ID */ 
  286. if ( empty( $pdf_id ) ) { 
  287. $pdf_id = ( rgpost( 'gform_pdf_id' ) ) ? rgpost( 'gform_pdf_id' ) : false; 
  288.  
  289. $input = rgpost( 'gfpdf_settings' ); 
  290.  
  291. /** check appropriate settings */ 
  292. if ( ! is_array( $input ) || ! $pdf_id ) { 
  293. $this->log->addError( 'Invalid Data.', [ 
  294. 'post' => $input,  
  295. 'pid' => $pdf_id,  
  296. ] ); 
  297.  
  298. $this->notices->add_error( esc_html__( 'There was a problem saving your PDF settings. Please try again.', 'gravity-forms-pdf-extended' ) ); 
  299.  
  300. return false; 
  301.  
  302. $sanitized = $this->settings_sanitize( $input ); 
  303.  
  304. /** Update our GFPDF settings */ 
  305. $sanitized['id'] = $pdf_id; 
  306. $sanitized['status'] = 'sanitizing'; /** used as a switch to tell when a record has been saved to the database, or stuck in validation */ 
  307.  
  308. /** Save current PDF state */ 
  309. $pdf = $this->options->get_pdf( $form_id, $pdf_id ); 
  310. $sanitized['active'] = ( ! is_wp_error( $pdf ) && isset( $pdf['active'] ) ) ? $pdf['active'] : true; 
  311.  
  312. $this->options->update_pdf( $form_id, $pdf_id, $sanitized, false ); 
  313.  
  314. /** Do validation */ 
  315. if ( empty( $sanitized['name'] ) || empty( $sanitized['filename'] ) || 
  316. ( $sanitized['pdf_size'] == 'CUSTOM' && ( (int) $sanitized['custom_pdf_size'][0] === 0 || (int) $sanitized['custom_pdf_size'][1] === 0 ) ) 
  317. ) { 
  318.  
  319. $this->log->addNotice( 'Validation failed.' ); 
  320. $this->notices->add_error( esc_html__( 'PDF could not be saved. Please enter all required information below.', 'gravity-forms-pdf-extended' ) ); 
  321.  
  322. return false; 
  323.  
  324. /** Remove our status */ 
  325. unset( $sanitized['status'] ); 
  326.  
  327. /** Update the database */ 
  328. $did_update = $this->options->update_pdf( $form_id, $pdf_id, $sanitized ); 
  329.  
  330. /** If it updated, let's update the global variable */ 
  331. if ( $did_update !== false ) { 
  332.  
  333. $this->log->addNotice( 'Successfully Saved.', [ 
  334. 'form_id' => $form_id,  
  335. 'pdf_id' => $pdf_id,  
  336. 'settings' => $sanitized,  
  337. ] ); 
  338.  
  339. $this->notices->add_notice( sprintf( esc_html__( 'PDF saved successfully. %sBack to PDF list.%s', 'gravity-forms-pdf-extended' ), '<a href="' . remove_query_arg( 'pid' ) . '">', '</a>' ) ); 
  340.  
  341. return true; 
  342.  
  343. $this->log->addError( 'Database Update Failed.' ); 
  344. $this->notices->add_error( esc_html__( 'There was a problem saving your PDF settings. Please try again.', 'gravity-forms-pdf-extended' ) ); 
  345.  
  346. return false; 
  347.  
  348. /** 
  349. * Apply gfield_error class when validation fails, highlighting field blocks with problems 
  350. * 
  351. * @param array $fields Array of fields to process 
  352. * 
  353. * @return array Modified list of fields 
  354. * 
  355. * @since 4.0 
  356. */ 
  357. public function validation_error( $fields ) { 
  358.  
  359. /** 
  360. * Check if we actually need to do any validating 
  361. * Because of the way the Gravity Forms Settings page is processed we are hooking into the core 
  362. * "gfpdf_form_settings" filter which runs when ever update_option( 'pdf_form_settings' ) is run. 
  363. * We don't need to do any validation when not on the GF PDF Settings page 
  364. */ 
  365. if ( empty( $_POST['gfpdf_save_pdf'] ) ) { 
  366. return $fields; 
  367.  
  368. /** Check we have a valid nonce, or throw an error */ 
  369. if ( ! wp_verify_nonce( rgpost( 'gfpdf_save_pdf' ), 'gfpdf_save_pdf' ) ) { 
  370.  
  371. $this->log->addWarning( 'Nonce Verification Failed.' ); 
  372. $this->notices->add_error( esc_html__( 'There was a problem saving your PDF settings. Please try again.', 'gravity-forms-pdf-extended' ) ); 
  373.  
  374. return false; 
  375.  
  376. $input = rgpost( 'gfpdf_settings' ); 
  377.  
  378. /** Throw errors on required fields */ 
  379. foreach ( $fields as $key => &$field ) { 
  380.  
  381. if ( isset( $field['required'] ) && $field['required'] === true ) { 
  382.  
  383. /** Get field value */ 
  384. $value = ( isset( $input[ $field['id'] ] ) ) ? $input[ $field['id'] ] : ''; 
  385.  
  386. /** Set a class if it doesn't exist */ 
  387. $field['class'] = ( isset( $field['class'] ) ) ? $field['class'] : ''; 
  388.  
  389. /** Add way to skip the highlighting of errors */ 
  390. $skip_errors = apply_filters( 'gfpdf_skip_highlight_errors', false, $field, $input ); 
  391.  
  392. if ( $skip_errors ) { 
  393. continue; 
  394.  
  395. /** If the value is an array ensure all items have values */ 
  396. if ( is_array( $value ) ) { 
  397.  
  398. $size = sizeof( $value ); 
  399. if ( sizeof( array_filter( $value ) ) !== $size ) { 
  400. $field['class'] .= ' gfield_error'; 
  401. } else { 
  402.  
  403. /** 
  404. * If string, sanitize and add error if appropriate 
  405. * 
  406. * See https://gravitypdf.com/documentation/v4/gfpdf_form_settings_sanitize/ for more details about this filter 
  407. */ 
  408. $value = apply_filters( 'gfpdf_form_settings_sanitize_text', $value, $key ); 
  409. if ( empty( $value ) ) { 
  410. $field['class'] .= ' gfield_error'; 
  411.  
  412. return $fields; 
  413.  
  414. /** 
  415. * Do further checks to see if the custom PDF size should in fact be marked as an error 
  416. * Because it is dependant on the paper size option in some cases it shouldn't be highlighted 
  417. * 
  418. * @param boolean $skip Whether to skip error highlighting checks 
  419. * @param array $field The Gravity Form field 
  420. * @param array $input The user input 
  421. * 
  422. * @return boolean 
  423. * 
  424. * @since 4.0 
  425. */ 
  426. public function check_custom_size_error_highlighting( $skip, $field, $input ) { 
  427.  
  428. if ( $field['id'] == 'custom_pdf_size' ) { 
  429.  
  430. /** Skip if not currently being shown */ 
  431. if ( $input['pdf_size'] !== 'CUSTOM' ) { 
  432. return true; 
  433.  
  434. return $skip; 
  435.  
  436. /** 
  437. * Similar to Helper_Abstract_Options->settings_sanitize() except we don't need as robust validation and error checking 
  438. * 
  439. * @param array $input Fields to process 
  440. * 
  441. * @return array Sanitized fields 
  442. * 
  443. * @since 4.0 
  444. */ 
  445. public function settings_sanitize( $input = [] ) { 
  446.  
  447. $settings = $this->options->get_registered_fields(); 
  448. $sections = [ 
  449. 'form_settings',  
  450. 'form_settings_appearance',  
  451. 'form_settings_custom_appearance',  
  452. 'form_settings_advanced',  
  453. ]; 
  454.  
  455. foreach ( $sections as $s ) { 
  456. $input = apply_filters( 'gfpdf_settings_' . $s . '_sanitize', $input ); 
  457.  
  458. /** Loop through each setting being saved and pass it through a sanitization filter */ 
  459. if ( is_array( $input ) && 0 < sizeof( $input ) ) { 
  460. foreach ( $input as $key => $value ) { 
  461.  
  462. foreach ( $sections as $s ) { 
  463.  
  464. /** only process field if found in the section */ 
  465. if ( isset( $settings[ $s ][ $key ] ) ) { 
  466. $type = isset( $settings[ $s ][ $key ]['type'] ) ? $settings[ $s ][ $key ]['type'] : false; 
  467.  
  468. /** 
  469. * General filter 
  470. * 
  471. * See https://gravitypdf.com/documentation/v4/gfpdf_form_settings_sanitize/ for more details about this filter 
  472. */ 
  473. $input[ $key ] = apply_filters( 'gfpdf_form_settings_sanitize', $input[ $key ], $key, $input, $settings[ $s ][ $key ] ); 
  474.  
  475. if ( $type ) { 
  476. /** 
  477. * Field type specific filter 
  478. * 
  479. * See https://gravitypdf.com/documentation/v4/gfpdf_form_settings_sanitize/ for more details about this filter 
  480. */ 
  481. $input[ $key ] = apply_filters( 'gfpdf_form_settings_sanitize_' . $type, $input[ $key ], $key, $input, $settings[ $s ][ $key ] ); 
  482.  
  483. return $input; 
  484.  
  485. /** 
  486. * Check if we are on the Form Settings Edit page and gets the appropriate template name 
  487. * 
  488. * @return string The current saved PDF template 
  489. * 
  490. * @since 4.0 
  491. */ 
  492. public function get_template_name_from_current_page() { 
  493.  
  494. $pid = ( ! empty( $_GET['pid'] ) ) ? rgget( 'pid' ) : rgpost( 'gform_pdf_id' ); 
  495. $form_id = ( isset( $_GET['id'] ) ) ? (int) $_GET['id'] : 0; 
  496.  
  497. /** If we don't have a specific PDF we'll use the defaults */ 
  498. if ( empty( $pid ) || empty( $form_id ) ) { 
  499. $template = $this->options->get_option( 'default_template', 'zadani' ); 
  500. } else { 
  501. /** Load the PDF configuration */ 
  502. $pdf = $this->options->get_pdf( $form_id, $pid ); 
  503.  
  504. if ( ! is_wp_error( $pdf ) ) { 
  505. $template = $pdf['template']; 
  506. } else { 
  507. $template = ''; 
  508.  
  509. return $template; 
  510.  
  511. /** 
  512. * If the PDF ID exists (either POST or GET) and we have a template with a config file 
  513. * we will load any fields loaded in the config file 
  514. * 
  515. * @param array $settings Any existing settings loaded 
  516. * 
  517. * @return array 
  518. * 
  519. * @since 4.0 
  520. */ 
  521. public function register_custom_appearance_settings( $settings ) { 
  522. $template = $this->get_template_name_from_current_page(); 
  523. $class = $this->templates->get_config_class( $template ); 
  524.  
  525. return $this->setup_custom_appearance_settings( $class, $settings ); 
  526.  
  527. /** 
  528. * To allow for correct backwards compatibility with our v3 templates we need to hide the font, size and colour 
  529. * information when selected. To allow this behaviour we're going to assign a 'data-template_group' attribute 
  530. * to the template select box which our JS can pick up and use to toggle those fields 
  531. * 
  532. * @param array $settings The current PDF settings 
  533. * 
  534. * @return array 
  535. * 
  536. * @since 4.0 
  537. */ 
  538. public function register_template_group( $settings ) { 
  539.  
  540. /** Add our template group */ 
  541. if ( isset( $settings['template'] ) && is_array( $settings['template'] ) ) { 
  542.  
  543. $template_info = $this->templates->get_template_info_by_id( $this->get_template_name_from_current_page() ); 
  544.  
  545. /** Ensure the key we want is an array, otherwise set it to one */ 
  546. $settings['template']['data'] = ( isset( $settings['template']['data'] ) && is_array( $settings['template']['data'] ) ) ? $settings['template']['data'] : []; 
  547. $settings['template']['data']['template_group'] = $template_info['group']; 
  548.  
  549. return $settings; 
  550.  
  551. /** 
  552. * Load our custom appearance settings (if needed) 
  553. * 
  554. * @param object $class The template configuration class 
  555. * @param array $settings Any current settings 
  556. * 
  557. * @return array 
  558. * 
  559. * @since 4.0 
  560. */ 
  561. public function setup_custom_appearance_settings( $class, $settings = [] ) { 
  562.  
  563. /** If class isn't an instance of our interface return $settings */ 
  564. if ( ! ( $class instanceof Helper_Interface_Config ) ) { 
  565.  
  566. $this->log->addWarning( 'Instanceof Failed.', [ 
  567. 'object' => get_class( $class ),  
  568. 'type' => 'Helper_Interface_Config',  
  569. ] ); 
  570.  
  571. return $settings; 
  572.  
  573. /** 
  574. * Now we have the class initialised, let's load our configuration array 
  575. */ 
  576. $template_settings = $class->configuration(); 
  577.  
  578. /** register any custom fields */ 
  579. if ( isset( $template_settings['fields'] ) && is_array( $template_settings['fields'] ) ) { 
  580. foreach ( $template_settings['fields'] as $key => $field ) { 
  581. $settings[ $key ] = $field; 
  582.  
  583. $settings = $this->setup_core_custom_appearance_settings( $settings, $class, $template_settings ); 
  584.  
  585. $this->log->addNotice( 'Setup Template-Specific Settings', [ 
  586. 'settings' => $settings,  
  587. ] ); 
  588.  
  589. return $settings; 
  590.  
  591. /** 
  592. * Setup any core fields that are registered to the PDF template 
  593. * 
  594. * @param array $settings Any current settings 
  595. * @param \GFPDF\Helper\Helper_Interface_Config $class The template configuration class 
  596. * @param array $template_settings Loaded configuration array 
  597. * 
  598. * @return array 
  599. * 
  600. * @since 4.0 
  601. */ 
  602. public function setup_core_custom_appearance_settings( $settings = [], Helper_Interface_Config $class, $template_settings ) { 
  603.  
  604. /** register our core fields */ 
  605. $core_fields = [ 
  606. 'show_form_title' => [ $this->options, 'get_form_title_display_field' ],  
  607. 'show_page_names' => [ $this->options, 'get_page_names_display_field' ],  
  608. 'show_html' => [ $this->options, 'get_html_display_field' ],  
  609. 'show_section_content' => [ $this->options, 'get_section_content_display_field' ],  
  610. 'enable_conditional' => [ $this->options, 'get_conditional_display_field' ],  
  611. 'show_empty' => [ $this->options, 'get_empty_display_field' ],  
  612.  
  613. 'background_color' => [ $this->options, 'get_background_color_field' ],  
  614. 'background_image' => [ $this->options, 'get_background_image_field' ],  
  615. 'header' => [ $this->options, 'get_header_field' ],  
  616. 'first_header' => [ $this->options, 'get_first_page_header_field' ],  
  617. 'footer' => [ $this->options, 'get_footer_field' ],  
  618. 'first_footer' => [ $this->options, 'get_first_page_footer_field' ],  
  619. ]; 
  620.  
  621. /** See https://gravitypdf.com/documentation/v4/gfpdf_core_template_fields_list/ for more details about this filter */ 
  622. $core_fields = apply_filters( 'gfpdf_core_template_fields_list', $core_fields, $template_settings, $class ); 
  623.  
  624. foreach ( $core_fields as $id => $method ) { 
  625.  
  626. if ( isset( $template_settings['core'][ $id ] ) && $template_settings['core'][ $id ] === true ) { 
  627. $settings[ $id ] = call_user_func( $method ); 
  628.  
  629. return $settings; 
  630.  
  631. /** 
  632. * Auto strip the .pdf extension when sanitizing 
  633. * 
  634. * @param string $value The value entered by the user 
  635. * @param string $key The field to be parsed 
  636. * 
  637. * @return string The sanitized data 
  638. */ 
  639. public function parse_filename_extension( $value, $key ) { 
  640.  
  641. if ( $key == 'filename' ) { 
  642. $value = $this->misc->remove_extension_from_string( $value ); 
  643.  
  644. return $value; 
  645.  
  646. /** 
  647. * Auto decode the JSON conditional logic string 
  648. * 
  649. * @param string $value The value entered by the user 
  650. * @param string $key The field to be parsed 
  651. * 
  652. * @return string The sanitized data 
  653. */ 
  654. public function decode_json( $value, $key ) { 
  655.  
  656. if ( $key == 'conditionalLogic' ) { 
  657. return json_decode( $value, true ); 
  658.  
  659. return $value; 
  660.  
  661.  
  662. /** 
  663. * Update our notification form settings which is specific to the PDF Form Settings Page (i.e we need an actual $form object which isn't present when we originally register the settings) 
  664. * 
  665. * @param array $notifications The current form notifications 
  666. * 
  667. * @return void 
  668. * 
  669. * @since 4.0 
  670. */ 
  671. public function register_notifications( $notifications ) { 
  672.  
  673. /** Loop through notifications and format it to our standard */ 
  674. if ( is_array( $notifications ) ) { 
  675. $options = []; 
  676.  
  677. /** Filter out the save and continue notifications */ 
  678. $omit = [ 'form_saved', 'form_save_email_requested' ]; 
  679.  
  680. foreach ( $notifications as $notification ) { 
  681. $event = ( isset( $notification['event'] ) ) ? $notification['event'] : ''; 
  682.  
  683. if ( ! in_array( $event, $omit ) ) { 
  684. $options[ $notification['id'] ] = $notification['name']; 
  685.  
  686. /** Apply our settings update */ 
  687. $this->options->update_registered_field( 'form_settings', 'notification', 'options', $options ); 
  688.  
  689. /** 
  690. * AJAX Endpoint for deleting PDF Settings 
  691. * 
  692. * @return string JSON 
  693. * 
  694. * @internal param $_POST ['nonce'] a valid nonce 
  695. * @internal param $_POST ['fid'] a valid form ID 
  696. * @internal param $_POST ['pid'] a valid PDF ID 
  697. * 
  698. * @since 4.0 
  699. */ 
  700. public function delete_gf_pdf_setting() { 
  701.  
  702. $fid = ( isset( $_POST['fid'] ) ) ? (int) $_POST['fid'] : 0; 
  703. $pid = ( isset( $_POST['pid'] ) ) ? $_POST['pid'] : ''; 
  704. $nonce_id = "gfpdf_delete_nonce_{$fid}_{$pid}"; 
  705.  
  706. /** User / CORS validation */ 
  707. $this->misc->handle_ajax_authentication( 'Delete PDF Settings', 'gravityforms_edit_settings', $nonce_id ); 
  708.  
  709. /** Delete PDF settings */ 
  710. $results = $this->options->delete_pdf( $fid, $pid ); 
  711.  
  712. if ( $results && ! is_wp_error( $results ) ) { 
  713.  
  714. $this->log->addNotice( 'AJAX Endpoint Successful' ); 
  715.  
  716. $return = [ 
  717. 'msg' => esc_html__( 'PDF successfully deleted.', 'gravity-forms-pdf-extended' ),  
  718. ]; 
  719.  
  720. echo json_encode( $return ); 
  721. wp_die(); 
  722.  
  723. $errors = []; 
  724. if ( is_wp_error( $results ) ) { 
  725. $errors = [ 
  726. 'WP_Error_Message' => $results->get_error_message(),  
  727. 'WP_Error_Code' => $results->get_error_code(),  
  728. ]; 
  729.  
  730. $this->log->addError( 'AJAX Endpoint Failed', $errors ); 
  731.  
  732. /** Internal Server Error */ 
  733. wp_die( '500', 500 ); 
  734.  
  735. /** 
  736. * AJAX Endpoint for duplicating PDF Settings 
  737. * 
  738. * @return string JSON 
  739. * 
  740. * @internal param $_POST ['nonce'] a valid nonce 
  741. * @internal param $_POST ['fid'] a valid form ID 
  742. * @internal param $_POST ['pid'] a valid PDF ID 
  743. * 
  744. * @since 4.0 
  745. */ 
  746. public function duplicate_gf_pdf_setting() { 
  747.  
  748. $fid = ( isset( $_POST['fid'] ) ) ? (int) $_POST['fid'] : 0; 
  749. $pid = ( isset( $_POST['pid'] ) ) ? $_POST['pid'] : ''; 
  750.  
  751. $nonce_id = "gfpdf_duplicate_nonce_{$fid}_{$pid}"; 
  752.  
  753. /** User / CORS validation */ 
  754. $this->misc->handle_ajax_authentication( 'Duplicate PDF Settings', 'gravityforms_edit_settings', $nonce_id ); 
  755.  
  756. /** Duplicate PDF config */ 
  757. $config = $this->options->get_pdf( $fid, $pid ); 
  758.  
  759. if ( ! is_wp_error( $config ) ) { 
  760. $config['id'] = uniqid(); 
  761. $config['name'] = $config['name'] . ' (copy)'; 
  762. $config['active'] = false; 
  763.  
  764. $results = $this->options->update_pdf( $fid, $config['id'], $config ); 
  765.  
  766. if ( $results ) { 
  767. $this->log->addNotice( 'AJAX Endpoint Successful' ); 
  768.  
  769. /** @todo just use the same nonce for all requests since WP nonces aren't one-time user (time based) */ 
  770. $dup_nonce = wp_create_nonce( "gfpdf_duplicate_nonce_{$fid}_{$config['id']}" ); 
  771. $del_nonce = wp_create_nonce( "gfpdf_delete_nonce_{$fid}_{$config['id']}" ); 
  772. $state_nonce = wp_create_nonce( "gfpdf_state_nonce_{$fid}_{$config['id']}" ); 
  773.  
  774. $return = [ 
  775. 'msg' => esc_html__( 'PDF successfully duplicated.', 'gravity-forms-pdf-extended' ),  
  776. 'pid' => $config['id'],  
  777. 'name' => $config['name'],  
  778. 'dup_nonce' => $dup_nonce,  
  779. 'del_nonce' => $del_nonce,  
  780. 'state_nonce' => $state_nonce,  
  781. ]; 
  782.  
  783. echo json_encode( $return ); 
  784. wp_die(); 
  785.  
  786. $this->log->addError( 'AJAX Endpoint Failed', [ 
  787. 'WP_Error_Message' => $config->get_error_message(),  
  788. 'WP_Error_Code' => $config->get_error_code(),  
  789. ] ); 
  790.  
  791. /** Internal Server Error */ 
  792. wp_die( '500', 500 ); 
  793.  
  794. /** 
  795. * AJAX Endpoint for changing the PDF Settings state 
  796. * 
  797. * @return string JSON 
  798. * 
  799. * @internal param $_POST ['nonce'] a valid nonce 
  800. * @internal param $_POST ['fid'] a valid form ID 
  801. * @internal param $_POST ['pid'] a valid PDF ID 
  802. * 
  803. * @since 4.0 
  804. */ 
  805. public function change_state_pdf_setting() { 
  806.  
  807. $fid = ( isset( $_POST['fid'] ) ) ? (int) $_POST['fid'] : 0; 
  808. $pid = ( isset( $_POST['pid'] ) ) ? $_POST['pid'] : ''; 
  809. $nonce_id = "gfpdf_state_nonce_{$fid}_{$pid}"; 
  810.  
  811. /** User / CORS validation */ 
  812. $this->misc->handle_ajax_authentication( 'Change PDF Settings State', 'gravityforms_edit_settings', $nonce_id ); 
  813.  
  814. /** Change the PDF state */ 
  815. $config = $this->options->get_pdf( $fid, $pid ); 
  816.  
  817. if ( ! is_wp_error( $config ) ) { 
  818.  
  819. /** toggle state */ 
  820. $config['active'] = ( $config['active'] === true ) ? false : true; 
  821. $state = ( $config['active'] ) ? esc_attr__( 'Active', 'gravity-forms-pdf-extended' ) : esc_attr__( 'Inactive', 'gravity-forms-pdf-extended' ); 
  822. $src = $this->gform->get_plugin_url() . '/images/active' . intval( $config['active'] ) . '.png'; 
  823.  
  824. $results = $this->options->update_pdf( $fid, $config['id'], $config ); 
  825.  
  826. if ( $results ) { 
  827. $this->log->addNotice( 'AJAX Endpoint Successful' ); 
  828.  
  829. $return = [ 
  830. 'state' => $state,  
  831. 'src' => $src,  
  832. 'fid' => $fid,  
  833. 'pid' => $config['id'],  
  834. ]; 
  835.  
  836. echo json_encode( $return ); 
  837. wp_die(); 
  838.  
  839. $this->log->addError( 'AJAX Endpoint Failed', [ 
  840. 'WP_Error_Message' => $config->get_error_message(),  
  841. 'WP_Error_Code' => $config->get_error_code(),  
  842. ] ); 
  843.  
  844. /** Internal Server Error */ 
  845. wp_die( '500', 500 ); 
  846.  
  847. /** 
  848. * AJAX Endpoint for rendering the template field settings options 
  849. * 
  850. * @return string JSON 
  851. * 
  852. * @internal param $_POST ['template'] the template to select 
  853. * 
  854. * @since 4.0 
  855. */ 
  856. public function render_template_fields() { 
  857.  
  858. /** User / CORS validation */ 
  859. $this->misc->handle_ajax_authentication( 'Render Template Custom Fields', 'gravityforms_edit_settings' ); 
  860.  
  861. /** get the current template */ 
  862. $template = ( isset( $_POST['template'] ) ) ? $_POST['template'] : ''; 
  863. $type = ( isset( $_POST['type'] ) ) ? $_POST['type'] : ''; 
  864. $class = $this->templates->get_config_class( $template ); 
  865. $settings = $this->setup_custom_appearance_settings( $class ); 
  866.  
  867. /** Only handle fields when in the PDF Forms Settings, and not in the general settings */ 
  868. if ( $type != 'gfpdf_settings[default_template]' ) { 
  869.  
  870. /** Get the template type so we can return out to the browser */ 
  871. $template_data = $this->templates->get_template_info_by_id( $template ); 
  872. $template_type = mb_strtolower( $template_data['group'] ); 
  873.  
  874. /** add our filter to override what template gets rendered (by default it is the current selected template in the config) */ 
  875. add_filter( 'gfpdf_form_settings_custom_appearance', function () use ( &$settings ) { 
  876. /** check if the template has any configuration */ 
  877. return $settings; 
  878. }, 100 ); 
  879.  
  880. /** Ensure our new fields are registered */ 
  881. $this->options->register_settings( $this->options->get_registered_fields() ); 
  882.  
  883. /** generate the HTML */ 
  884. ob_start(); 
  885.  
  886. do_settings_fields( 'gfpdf_settings_form_settings_custom_appearance', 'gfpdf_settings_form_settings_custom_appearance' ); 
  887.  
  888. $html = ob_get_clean(); 
  889.  
  890. /** 
  891. * Pass the required wp_editor IDs and settings in our AJAX response so the client 
  892. * can correctly load the instances. 
  893. */ 
  894. $editors = []; 
  895.  
  896. foreach ( $settings as $field ) { 
  897. if ( isset( $field['type'] ) && $field['type'] == 'rich_editor' ) { 
  898. $editors[] = 'gfpdf_settings_' . $field['id']; 
  899.  
  900. $editor_init = ( isset( $this->data->tiny_mce_editor_settings ) ) ? $this->data->tiny_mce_editor_settings : null; 
  901. $html = ( isset( $html ) && strlen( trim( $html ) ) > 0 ) ? $html : null; 
  902. $editors = ( isset( $editors ) ) ? $editors : null; 
  903. $template_type = ( isset( $template_type ) ) ? $template_type : null; 
  904.  
  905. $return = [ 
  906. 'fields' => $html,  
  907. 'editors' => $editors,  
  908. 'editor_init' => $editor_init,  
  909. 'template_type' => $template_type,  
  910. ]; 
  911.  
  912. $this->log->addNotice( 'AJAX Endpoint Successful', $return ); 
  913.  
  914. echo json_encode( $return ); 
  915.  
  916. /** end AJAX function */ 
  917. wp_die(); 
.