GFPDFModelModel_Install

Model_Install.

Defined (1)

The class is defined in the following location(s).

/src/model/Model_Install.php  
  1. class Model_Install extends Helper_Abstract_Model { 
  2.  
  3. /** 
  4. * Holds the abstracted Gravity Forms API specific to Gravity PDF 
  5. * @var \GFPDF\Helper\Helper_Form 
  6. * @since 4.0 
  7. */ 
  8. protected $gform; 
  9.  
  10. /** 
  11. * Holds our log class 
  12. * @var \Monolog\Logger|LoggerInterface 
  13. * @since 4.0 
  14. */ 
  15. protected $log; 
  16.  
  17. /** 
  18. * Holds our Helper_Data object 
  19. * which we can autoload with any data needed 
  20. * @var \GFPDF\Helper\Helper_Data 
  21. * @since 4.0 
  22. */ 
  23. protected $data; 
  24.  
  25. /** 
  26. * Holds our Helper_Misc object 
  27. * Makes it easy to access common methods throughout the plugin 
  28. * @var \GFPDF\Helper\Helper_Misc 
  29. * @since 4.0 
  30. */ 
  31. protected $misc; 
  32.  
  33. /** 
  34. * Holds our Helper_Notices object 
  35. * which we can use to queue up admin messages for the user 
  36. * @var \GFPDF\Helper\Helper_Notices 
  37. * @since 4.0 
  38. */ 
  39. protected $notices; 
  40.  
  41. /** 
  42. * Setup our class by injecting all our dependancies 
  43. * @param \GFPDF\Helper\Helper_Abstract_Form $gform Our abstracted Gravity Forms helper functions 
  44. * @param \Monolog\Logger|LoggerInterface $log Our logger class 
  45. * @param \GFPDF\Helper\Helper_Data $data Our plugin data store 
  46. * @param \GFPDF\Helper\Helper_Misc $misc Our miscellaneous class 
  47. * @param \GFPDF\Helper\Helper_Notices $notices Our notice class used to queue admin messages and errors 
  48. * @since 4.0 
  49. */ 
  50. public function __construct( Helper_Abstract_Form $gform, LoggerInterface $log, Helper_Data $data, Helper_Misc $misc, Helper_Notices $notices ) { 
  51.  
  52. /** Assign our internal variables */ 
  53. $this->gform = $gform; 
  54. $this->log = $log; 
  55. $this->data = $data; 
  56. $this->misc = $misc; 
  57. $this->notices = $notices; 
  58.  
  59. /** 
  60. * The Gravity PDF Installer 
  61. * @return void 
  62. * @since 4.0 
  63. */ 
  64. public function install_plugin() { 
  65.  
  66. $this->log->addNotice( 'Gravity PDF Installed' ); 
  67. update_option( 'gfpdf_is_installed', true ); 
  68. $this->data->is_installed = true; 
  69.  
  70. /** See https://gravitypdf.com/documentation/v4/gfpdf_plugin_installed/ for more details about this action */ 
  71. do_action( 'gfpdf_plugin_installed' ); 
  72.  
  73. /** 
  74. * Get our permalink regex structure 
  75. * @return string 
  76. * @since 4.0 
  77. */ 
  78. public function get_permalink_regex() { 
  79. global $wp_rewrite; 
  80.  
  81. $root = str_replace( '/', '\/', $wp_rewrite->root ); 
  82.  
  83. return '^' . $root . 'pdf\/([A-Za-z0-9]+)\/([0-9]+)\/?(download)?\/?'; 
  84.  
  85. /** 
  86. * Get the plugin working directory name 
  87. * @return string 
  88. * @since 4.0 
  89. */ 
  90. public function get_working_directory() { 
  91. /** See https://gravitypdf.com/documentation/v4/gfpdf_working_folder_name/ for more details about this filter */ 
  92. return apply_filters( 'gfpdf_working_folder_name', 'PDF_EXTENDED_TEMPLATES' ); 
  93.  
  94. /** 
  95. * Get a link to the plugin's settings page URL 
  96. * @return string 
  97. * @since 4.0 
  98. */ 
  99. public function get_settings_url() { 
  100. return admin_url( 'admin.php?page=gf_settings&subview=PDF' ); 
  101.  
  102. /** 
  103. * Get our current installation status 
  104. * @return boolean 
  105. * @since 4.0 
  106. */ 
  107. public function is_installed() { 
  108. return get_option( 'gfpdf_is_installed' ); 
  109.  
  110. /** 
  111. * Used to set up our PDF template folder, tmp folder and font folder 
  112. * @since 4.0 
  113. */ 
  114. public function setup_template_location() { 
  115.  
  116. $template_dir = $this->data->upload_dir . '/' . $this->data->working_folder . '/'; 
  117. $template_url = $this->data->upload_dir_url . '/' . $this->data->working_folder . '/'; 
  118. $working_folder = $this->data->working_folder; 
  119. $upload_dir = $this->data->upload_dir; 
  120. $upload_dir_url = $this->data->upload_dir_url; 
  121.  
  122. /** Legacy Filters */ 
  123. $this->data->template_location = apply_filters( 'gfpdfe_template_location', $template_dir, $working_folder, $upload_dir ); 
  124. $this->data->template_location_url = apply_filters( 'gfpdfe_template_location_uri', $template_url, $working_folder, $upload_dir_url ); 
  125.  
  126. /** Allow user to change directory location(s) */ 
  127.  
  128. /** See https://gravitypdf.com/documentation/v4/gfpdf_template_location/ for more details about this filter */ 
  129. $this->data->template_location = apply_filters( 'gfpdf_template_location', $this->data->template_location, $working_folder, $upload_dir ); /** needs to be accessible from the web */ 
  130.  
  131. /** See https://gravitypdf.com/documentation/v4/gfpdf_template_location_uri/ for more details about this filter */ 
  132. $this->data->template_location_url = apply_filters( 'gfpdf_template_location_uri', $this->data->template_location_url, $working_folder, $upload_dir_url ); /** needs to be accessible from the web */ 
  133.  
  134. /** See https://gravitypdf.com/documentation/v4/gfpdf_font_location/ for more details about this filter */ 
  135. $this->data->template_font_location = apply_filters( 'gfpdf_font_location', $this->data->template_location . 'fonts/', $working_folder, $upload_dir ); /** can be in a directory not accessible via the web */ 
  136.  
  137. /** @todo normally font and fontdata should be kept together but it may be worth adding a filter here */ 
  138. $this->data->template_fontdata_location = $this->data->template_font_location . 'fontdata/'; 
  139.  
  140. /** See https://gravitypdf.com/documentation/v4/gfpdf_tmp_location/ for more details about this filter */ 
  141. $this->data->template_tmp_location = apply_filters( 'gfpdf_tmp_location', $this->data->template_location . 'tmp/', $working_folder, $upload_dir_url ); /** encouraged to move this to a directory not accessible via the web */ 
  142.  
  143. $this->log->addNotice( 'Template Locations', [ 
  144. 'path' => $this->data->template_location,  
  145. 'url' => $this->data->template_location_url,  
  146. 'font' => $this->data->template_font_location,  
  147. 'fontdata' => $this->data->template_fontdata_location,  
  148. 'tmp' => $this->data->template_tmp_location,  
  149. ] ); 
  150.  
  151. /** 
  152. * If running a multisite we'll setup the path to the current multisite folder 
  153. * @since 4.0 
  154. * @return void 
  155. */ 
  156. public function setup_multisite_template_location() { 
  157.  
  158. if ( is_multisite() ) { 
  159.  
  160. $blog_id = get_current_blog_id(); 
  161.  
  162. $template_dir = $this->data->template_location . $blog_id . '/'; 
  163. $template_url = $this->data->template_location_url . $blog_id . '/'; 
  164. $working_folder = $this->data->working_folder; 
  165. $upload_dir = $this->data->upload_dir; 
  166. $upload_dir_url = $this->data->upload_dir_url; 
  167.  
  168. /** 
  169. * Allow user to change directory location(s) 
  170. * @internal Folder location needs to be accessible from the web 
  171. */ 
  172.  
  173. /** Global filter */ 
  174.  
  175. /** See https://gravitypdf.com/documentation/v4/gfpdf_multisite_template_location/ for more details about this filter */ 
  176. $this->data->multisite_template_location = apply_filters( 'gfpdf_multisite_template_location', $template_dir, $working_folder, $upload_dir, $blog_id ); 
  177.  
  178. /** See https://gravitypdf.com/documentation/v4/gfpdf_multisite_template_location_uri/ for more details about this filter */ 
  179. $this->data->multisite_template_location_url = apply_filters( 'gfpdf_multisite_template_location_uri', $template_url, $working_folder, $upload_dir_url, $blog_id ); 
  180.  
  181. /** Per-blog filters */ 
  182. $this->data->multisite_template_location = apply_filters( 'gfpdf_multisite_template_location_' . $blog_id, $this->data->multisite_template_location, $working_folder, $upload_dir, $blog_id ); 
  183. $this->data->multisite_template_location_url = apply_filters( 'gfpdf_multisite_template_location_uri_' . $blog_id, $this->data->multisite_template_location_url, $working_folder, $upload_dir_url, $blog_id ); 
  184.  
  185. $this->log->addNotice( 'Multisite Template Locations', [ 
  186. 'path' => $this->data->multisite_template_location,  
  187. 'url' => $this->data->multisite_template_location_url,  
  188. ] ); 
  189.  
  190. /** 
  191. * Create the appropriate folder structure automatically 
  192. * The upload directory should have all appropriate permissions to allow this kind of maniupulation 
  193. * but devs who tap into the gfpdfe_template_location filter will need to ensure we can write to the appropraite folder 
  194. * @since 4.0 
  195. * @return void 
  196. */ 
  197. public function create_folder_structures() { 
  198.  
  199. /** don't create the folder structure on our welcome page or through AJAX as an errors on the first page they see will confuse users */ 
  200. if ( is_admin() && 
  201. ( rgget( 'page' ) == 'gfpdf-getting-started' ) || ( rgget( 'page' ) == 'gfpdf-update' ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || get_transient( '_gravitypdf_activation_redirect' ) 
  202. ) { 
  203. return null; 
  204.  
  205. /** add folders that need to be checked */ 
  206. $folders = [ 
  207. $this->data->template_location,  
  208. $this->data->template_font_location,  
  209. $this->data->template_fontdata_location,  
  210. $this->data->template_tmp_location,  
  211. ]; 
  212.  
  213. if ( is_multisite() ) { 
  214. $folders[] = $this->data->multisite_template_location; 
  215.  
  216. /** allow other plugins to add their own folders which should be checked */ 
  217. $folders = apply_filters( 'gfpdf_installer_create_folders', $folders ); 
  218.  
  219. /** create the required folder structure, or throw error */ 
  220. foreach ( $folders as $dir ) { 
  221. if ( ! is_dir( $dir ) ) { 
  222. if ( ! wp_mkdir_p( $dir ) ) { 
  223. $this->log->addError( 'Failed Creating Folder Structure', [ 
  224. 'dir' => $dir,  
  225. ] ); 
  226.  
  227. $this->notices->add_error( sprintf( esc_html__( 'There was a problem creating the %s directory. Ensure you have write permissions to your uploads folder.', 'gravity-forms-pdf-extended' ), '<code>' . $this->misc->relative_path( $dir ) . '</code>' ) ); 
  228. } else { 
  229. /** test the directory is currently writable by the web server, otherwise throw an error */ 
  230. if ( ! wp_is_writable( $dir ) ) { 
  231. $this->log->addError( 'Failed Write Permissions Check.', [ 
  232. 'dir' => $dir,  
  233. ] ); 
  234.  
  235. $this->notices->add_error( sprintf( esc_html__( 'Gravity PDF does not have write permission to the %s directory. Contact your web hosting provider to fix the issue.', 'gravity-forms-pdf-extended' ), '<code>' . $this->misc->relative_path( $dir ) . '</code>' ) ); 
  236.  
  237. /** create blank index file in all folders to prevent web servers listing the entire directory */ 
  238. if ( is_dir( $this->data->template_location ) && ! is_file( $this->data->template_location . 'index.html' ) ) { 
  239. GFCommon::recursive_add_index_file( $this->data->template_location ); 
  240.  
  241. /** create deny htaccess file to prevent direct access to files */ 
  242. if ( is_dir( $this->data->template_tmp_location ) && ! is_file( $this->data->template_tmp_location . '.htaccess' ) ) { 
  243. $this->log->addNotice( 'Create Apache .htaccess Security' ); 
  244. file_put_contents( $this->data->template_tmp_location . '.htaccess', 'deny from all' ); 
  245.  
  246. /** 
  247. * Register our PDF custom rewrite rules 
  248. * @since 4.0 
  249. * @return void 
  250. */ 
  251. public function register_rewrite_rules() { 
  252.  
  253. /** store query */ 
  254. $query = $this->data->permalink; 
  255. $rewrite_to = 'index.php?gpdf=1&pid=$matches[1]&lid=$matches[2]&action=$matches[3]'; 
  256.  
  257. /** Add our main endpoint */ 
  258. add_rewrite_rule( 
  259. $query,  
  260. $rewrite_to,  
  261. 'top' ); 
  262.  
  263. $this->log->addNotice( 'Add Rewrite Rules', [ 
  264. 'query' => $query,  
  265. 'rewrite' => $rewrite_to,  
  266. ] ); 
  267.  
  268. /** check to see if we need to flush the rewrite rules */ 
  269. $this->maybe_flush_rewrite_rules( $query ); 
  270.  
  271. /** 
  272. * Register our PDF custom rewrite rules 
  273. * @since 4.0 
  274. * @param array $tags 
  275. * @return array 
  276. */ 
  277. public function register_rewrite_tags( $tags ) { 
  278. $tags[] = 'gpdf'; 
  279. $tags[] = 'pid'; 
  280. $tags[] = 'lid'; 
  281. $tags[] = 'action'; 
  282.  
  283. return $tags; 
  284.  
  285. /** 
  286. * Check if we need to force the rewrite rules to be flushed 
  287. * @param string $rule The rule to check 
  288. * @since 4.0 
  289. * @return void 
  290. */ 
  291. public function maybe_flush_rewrite_rules( $rule ) { 
  292.  
  293. $rules = get_option( 'rewrite_rules' ); 
  294.  
  295. if ( ! isset( $rules[ $rule ] ) ) { 
  296. $this->log->addNotice( 'Flushing WordPress Rewrite Rules.' ); 
  297. flush_rewrite_rules( false ); 
  298.  
  299.  
  300. /** 
  301. * The Gravity PDF Uninstaller 
  302. * @return void 
  303. * @since 4.0 
  304. */ 
  305. public function uninstall_plugin() { 
  306. $this->log->addNotice( 'Uninstall Gravity PDF.' ); 
  307.  
  308. /** Clean up database */ 
  309. if ( is_multisite() ) { 
  310. $sites = ( function_exists( 'get_sites' ) ) ? get_sites() : wp_get_sites(); 
  311.  
  312. foreach ( $sites as $site ) { 
  313. $site = (array) $site; /** Back-compat: ensure the new site object introduced in 4.6 gets converted back to an array */ 
  314. switch_to_blog( $site['blog_id'] ); 
  315. $this->remove_plugin_options(); 
  316. $this->remove_plugin_form_settings(); 
  317. restore_current_blog(); 
  318.  
  319. } else { 
  320. $this->remove_plugin_options(); 
  321. $this->remove_plugin_form_settings(); 
  322.  
  323. /** Remove folder structure and deactivate */ 
  324. $this->remove_folder_structure(); 
  325. $this->deactivate_plugin(); 
  326.  
  327. /** 
  328. * Remove and options stored in the database 
  329. * @return void 
  330. * @since 4.0 
  331. */ 
  332. public function remove_plugin_options() { 
  333. delete_option( 'gfpdf_is_installed' ); 
  334. delete_option( 'gfpdf_current_version' ); 
  335. delete_option( 'gfpdf_settings' ); 
  336.  
  337. /** 
  338. * Remove all form settings from each individual form. 
  339. * Because we stored out PDF settings with each form and have no index we need to individually load and forms and check them for Gravity PDF settings 
  340. * @return void 
  341. * @since 4.0 
  342. */ 
  343. public function remove_plugin_form_settings() { 
  344.  
  345. $forms = $this->gform->get_forms(); 
  346.  
  347. foreach ( $forms as $form ) { 
  348. /** only update forms which have a PDF configuration */ 
  349. if ( isset( $form['gfpdf_form_settings'] ) ) { 
  350. unset( $form['gfpdf_form_settings'] ); 
  351. if ( $this->gform->update_form( $form ) !== true ) { 
  352. $this->log->addError( 'Cannot Remove PDF Settings from Form.', [ 
  353. 'form_id' => $form['id'],  
  354. ] ); 
  355.  
  356. $this->notices->add_error( sprintf( esc_html__( 'There was a problem removing the Gravity Form "%s" PDF configuration. Try delete manually.', 'gravity-forms-pdf-extended' ), $form['id'] . ': ' . $form['title'] ) ); 
  357.  
  358. /** 
  359. * Remove our PDF directory structure 
  360. * @return void 
  361. * @since 4.0 
  362. */ 
  363. public function remove_folder_structure() { 
  364.  
  365. $paths = apply_filters( 'gfpdf_uninstall_path', [ 
  366. $this->data->template_font_location,  
  367. $this->data->template_tmp_location,  
  368. $this->data->template_location,  
  369. ] ); 
  370.  
  371. foreach ( $paths as $dir ) { 
  372. if ( is_dir( $dir ) ) { 
  373. $results = $this->misc->rmdir( $dir ); 
  374.  
  375. if ( is_wp_error( $results ) || ! $results ) { 
  376. $this->log->addError( 'Cannot Remove Folder Structure.', [ 
  377. 'WP_Error_Message' => $results->get_error_message(),  
  378. 'WP_Error_Code' => $results->get_error_code(),  
  379. 'dir' => $dir,  
  380. ] ); 
  381.  
  382. $this->notices->add_error( sprintf( esc_html__( 'There was a problem removing the %s directory. Clean up manually via (S)FTP.', 'gravity-forms-pdf-extended' ), '<code>' . $this->misc->relative_path( $dir ) . '</code>' ) ); 
  383.  
  384. /** 
  385. * Deactivate Gravity PDF 
  386. * @return void 
  387. * @since 4.0 
  388. */ 
  389. public function deactivate_plugin() { 
  390. deactivate_plugins( PDF_PLUGIN_BASENAME ); 
  391.  
  392. /** 
  393. * Safe redirect after deactivation 
  394. * @return void 
  395. * @since 4.0 
  396. */ 
  397. public function redirect_to_plugins_page() { 
  398. /** check if user can view the plugins page */ 
  399. if ( current_user_can( 'activate_plugins' ) ) { 
  400. wp_safe_redirect( admin_url( 'plugins.php' ) ); 
  401. } else { /** otherwise redirect to dashboard */ 
  402. wp_safe_redirect( admin_url( 'index.php' ) ); 
  403. exit;