ninja-forms.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  1. <?php
  2. /*
  3. Plugin Name: Ninja Forms
  4. Plugin URI: http://ninjaforms.com/
  5. Description: Ninja Forms is a webform builder with unparalleled ease of use and features.
  6. Version: 3.3.16
  7. Author: The WP Ninjas
  8. Author URI: http://ninjaforms.com
  9. Text Domain: ninja-forms
  10. Domain Path: /lang/
  11. Copyright 2016 WP Ninjas.
  12. */
  13. require_once dirname( __FILE__ ) . '/lib/NF_VersionSwitcher.php';
  14. require_once dirname( __FILE__ ) . '/lib/NF_Tracking.php';
  15. require_once dirname( __FILE__ ) . '/lib/NF_Conversion.php';
  16. require_once dirname( __FILE__ ) . '/lib/NF_ExceptionHandlerJS.php';
  17. require_once dirname( __FILE__ ) . '/lib/Conversion/Calculations.php';
  18. // Services require PHP v5.6+
  19. if( version_compare( PHP_VERSION, '5.6', '>=' ) ) {
  20. include_once dirname( __FILE__ ) . '/services/bootstrap.php';
  21. }
  22. function ninja_forms_three_table_exists(){
  23. global $wpdb;
  24. $table_name = $wpdb->prefix . 'nf3_forms';
  25. return ( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name );
  26. }
  27. if( get_option( 'ninja_forms_load_deprecated', FALSE ) && ! ( isset( $_POST[ 'nf2to3' ] ) && ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) ){
  28. include 'deprecated/ninja-forms.php';
  29. register_activation_hook( __FILE__, 'ninja_forms_activation_deprecated' );
  30. function ninja_forms_activation_deprecated( $network_wide ){
  31. include_once 'deprecated/includes/activation.php';
  32. ninja_forms_activation( $network_wide );
  33. }
  34. } else {
  35. include_once 'lib/NF_Upgrade.php';
  36. include_once 'lib/NF_AddonChecker.php';
  37. include_once plugin_dir_path( __FILE__ ) . 'includes/deprecated.php';
  38. /**
  39. * Class Ninja_Forms
  40. */
  41. final class Ninja_Forms
  42. {
  43. /**
  44. * @since 3.0
  45. */
  46. const VERSION = '3.3.16';
  47. const WP_MIN_VERSION = '4.7';
  48. /**
  49. * @var Ninja_Forms
  50. * @since 2.7
  51. */
  52. private static $instance;
  53. /**
  54. * Plugin Directory
  55. *
  56. * @since 3.0
  57. * @var string $dir
  58. */
  59. public static $dir = '';
  60. /**
  61. * Plugin URL
  62. *
  63. * @since 3.0
  64. * @var string $url
  65. */
  66. public static $url = '';
  67. /**
  68. * Admin Menus
  69. *
  70. * @since 3.0
  71. * @var array
  72. */
  73. public $menus = array();
  74. /**
  75. * AJAX Controllers
  76. *
  77. * @since 3.0
  78. * @var array
  79. */
  80. public $controllers = array();
  81. /**
  82. * Form Fields
  83. *
  84. * @since 3.0
  85. * @var array
  86. */
  87. public $fields = array();
  88. /**
  89. * Form Actions
  90. *
  91. * @since 3.0
  92. * @var array
  93. */
  94. public $actions = array();
  95. /**
  96. * Merge Tags
  97. *
  98. * @since 3.0
  99. * @var array
  100. */
  101. public $merge_tags = array();
  102. /**
  103. * Metaboxes
  104. *
  105. * @since 3.0
  106. * @var array
  107. */
  108. public $metaboxes = array();
  109. /**
  110. * Model Factory
  111. *
  112. * @var object
  113. */
  114. public $factory = '';
  115. /**
  116. * Logger
  117. *
  118. * @var string
  119. */
  120. protected $_logger = '';
  121. /**
  122. * Dispatcher
  123. *
  124. * @var string
  125. */
  126. protected $_dispatcher = '';
  127. /**
  128. * @var NF_Session
  129. */
  130. protected $session = '';
  131. /**
  132. * @var NF_Tracking
  133. */
  134. public $tracking;
  135. /**
  136. * Plugin Settings
  137. *
  138. * @since 3.0
  139. * @var array
  140. */
  141. protected $settings = array();
  142. protected $requests = array();
  143. protected $processes = array();
  144. /**
  145. * Main Ninja_Forms Instance
  146. *
  147. * Insures that only one instance of Ninja_Forms exists in memory at any one
  148. * time. Also prevents needing to define globals all over the place.
  149. *
  150. * @since 2.7
  151. * @static
  152. * @staticvar array $instance
  153. * @return Ninja_Forms Highlander Instance
  154. */
  155. public static function instance()
  156. {
  157. if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Ninja_Forms ) ) {
  158. self::$instance = new Ninja_Forms;
  159. self::$dir = plugin_dir_path( __FILE__ );
  160. // Define old constants for backwards compatibility.
  161. if( ! defined( 'NF_PLUGIN_DIR' ) ){
  162. define( 'NF_PLUGIN_DIR', self::$dir );
  163. define( 'NINJA_FORMS_DIR', self::$dir . 'deprecated' );
  164. }
  165. self::$url = plugin_dir_url( __FILE__ );
  166. if( ! defined( 'NF_PLUGIN_URL' ) ){
  167. define( 'NF_PLUGIN_URL', self::$url );
  168. }
  169. $saved_version = get_option( 'ninja_forms_version' );
  170. // If this is a fresh install... (The version has never been saved.)
  171. if ( ! $saved_version ) {
  172. // Assume we have clean data.
  173. update_option( 'ninja_forms_data_is_clean', 'true' );
  174. }
  175. // If we have a recorded version...
  176. // AND that version is less than our current version...
  177. if ( $saved_version && version_compare( $saved_version, self::VERSION, '<' ) ) {
  178. // *IMPORTANT: Filter to delete old bad data.
  179. // Leave this here until at least 3.4.0.
  180. if ( version_compare( $saved_version, '3.3.7', '<' ) && version_compare( $saved_version, '3.3.4', '>' ) ) {
  181. delete_option( 'nf_sub_expiration' );
  182. }
  183. // We just upgraded the plugin.
  184. $plugin_upgrade = true;
  185. } else {
  186. $plugin_upgrade = false;
  187. }
  188. update_option( 'ninja_forms_version', self::VERSION );
  189. // If we've not recorded our db version...
  190. if ( ! get_option( 'ninja_forms_db_version' ) ) {
  191. // If this isn't a fresh install...
  192. // AND If we're upgrading from a version before 3.3.0...
  193. if ( $saved_version && version_compare( $saved_version, '3.3.0', '<' ) ) {
  194. // Set it to the baseline (1.0) so that our upgrade process will run properly.
  195. add_option( 'ninja_forms_db_version', '1.0', '', 'no' );
  196. }
  197. else {
  198. // Set it to 1.1.
  199. add_option( 'ninja_forms_db_version', '1.1', '', 'no' );
  200. }
  201. }
  202. /*
  203. * Register our autoloader
  204. */
  205. spl_autoload_register( array( self::$instance, 'autoloader' ) );
  206. /*
  207. * Admin Menus
  208. */
  209. self::$instance->menus[ 'forms' ] = new NF_Admin_Menus_Forms();
  210. self::$instance->menus[ 'dashboard' ] = new NF_Admin_Menus_Dashboard();
  211. self::$instance->menus[ 'add-new' ] = new NF_Admin_Menus_AddNew();
  212. self::$instance->menus[ 'submissions'] = new NF_Admin_Menus_Submissions();
  213. self::$instance->menus[ 'import-export'] = new NF_Admin_Menus_ImportExport();
  214. self::$instance->menus[ 'settings' ] = new NF_Admin_Menus_Settings();
  215. self::$instance->menus[ 'licenses'] = new NF_Admin_Menus_Licenses();
  216. self::$instance->menus[ 'system_status'] = new NF_Admin_Menus_SystemStatus();
  217. self::$instance->menus[ 'add-ons' ] = new NF_Admin_Menus_Addons();
  218. self::$instance->menus[ 'divider'] = new NF_Admin_Menus_Divider();
  219. self::$instance->menus[ 'mock-data'] = new NF_Admin_Menus_MockData();
  220. /*
  221. * AJAX Controllers
  222. */
  223. self::$instance->controllers[ 'form' ] = new NF_AJAX_Controllers_Form();
  224. self::$instance->controllers[ 'fields' ] = new NF_AJAX_Controllers_Fields();
  225. self::$instance->controllers[ 'batch_process' ] = new NF_AJAX_REST_BatchProcess();
  226. self::$instance->controllers[ 'preview' ] = new NF_AJAX_Controllers_Preview();
  227. self::$instance->controllers[ 'submission' ] = new NF_AJAX_Controllers_Submission();
  228. self::$instance->controllers[ 'savedfields' ] = new NF_AJAX_Controllers_SavedFields();
  229. self::$instance->controllers[ 'deletealldata' ] = new NF_AJAX_Controllers_DeleteAllData();
  230. self::$instance->controllers[ 'jserror' ] = new NF_AJAX_Controllers_JSError();
  231. self::$instance->controllers[ 'dispatchpoints' ] = new NF_AJAX_Controllers_DispatchPoints();
  232. /*
  233. * REST Controllers
  234. */
  235. self::$instance->controllers[ 'REST' ][ 'forms' ] = new NF_AJAX_REST_Forms();
  236. self::$instance->controllers[ 'REST' ][ 'new-form-templates' ] = new NF_AJAX_REST_NewFormTemplates();
  237. /*
  238. * Async Requests
  239. */
  240. require_once Ninja_Forms::$dir . 'includes/Libraries/BackgroundProcessing/classes/wp-async-request.php';
  241. self::$instance->requests[ 'delete-field' ] = new NF_AJAX_Requests_DeleteField();
  242. /*
  243. * Background Processes
  244. */
  245. require_once Ninja_Forms::$dir . 'includes/Libraries/BackgroundProcessing/wp-background-processing.php';
  246. self::$instance->requests[ 'update-fields' ] = new NF_AJAX_Processes_UpdateFields();
  247. /*
  248. * WP-CLI Commands
  249. */
  250. if( class_exists( 'WP_CLI_Command' ) ) {
  251. WP_CLI::add_command('ninja-forms', 'NF_WPCLI_NinjaFormsCommand');
  252. }
  253. /*
  254. * Preview Page
  255. */
  256. self::$instance->preview = new NF_Display_Preview();
  257. /*
  258. * Shortcodes
  259. */
  260. self::$instance->shortcodes = new NF_Display_Shortcodes();
  261. /*
  262. * Submission CPT
  263. */
  264. new NF_Admin_CPT_Submission();
  265. new NF_Admin_CPT_DownloadAllSubmissions();
  266. require_once Ninja_Forms::$dir . 'lib/StepProcessing/menu.php';
  267. /*
  268. * Submission Metabox
  269. */
  270. new NF_Admin_Metaboxes_Calculations();
  271. /*
  272. * User data requests ( GDPR actions )
  273. */
  274. new NF_Admin_UserDataRequests();
  275. /*
  276. * Logger
  277. */
  278. self::$instance->_logger = new NF_Database_Logger();
  279. /*
  280. * Dispatcher
  281. */
  282. self::$instance->_dispatcher = new NF_Dispatcher();
  283. /*
  284. * Merge Tags
  285. */
  286. self::$instance->merge_tags[ 'wp' ] = new NF_MergeTags_WP();
  287. self::$instance->merge_tags[ 'fields' ] = new NF_MergeTags_Fields();
  288. self::$instance->merge_tags[ 'calcs' ] = new NF_MergeTags_Calcs();
  289. self::$instance->merge_tags[ 'form' ] = new NF_MergeTags_Form();
  290. self::$instance->merge_tags[ 'other' ] = new NF_MergeTags_Other();
  291. self::$instance->merge_tags[ 'deprecated' ] = new NF_MergeTags_Deprecated();
  292. /*
  293. * Add Form Modal
  294. */
  295. self::$instance->add_form_modal = new NF_Admin_AddFormModal();
  296. /*
  297. * EOS Parser
  298. */
  299. self::$instance->_eos[ 'parser' ] = require_once 'includes/Libraries/EOS/Parser.php';
  300. /*
  301. * Plugin Settings
  302. */
  303. self::$instance->settings = apply_filters( 'ninja_forms_settings', get_option( 'ninja_forms_settings' ) );
  304. /*
  305. * Admin Notices System
  306. */
  307. self::$instance->notices = new NF_Admin_Notices();
  308. self::$instance->widgets[] = new NF_Widget();
  309. /*
  310. * Gutenberg
  311. */
  312. self::$instance->gutenblock = new NF_FormBlock();
  313. /*
  314. * Opt-In Tracking
  315. */
  316. self::$instance->tracking = new NF_Tracking();
  317. self::$instance->submission_expiration_cron = new NF_Database_SubmissionExpirationCron();
  318. /*
  319. * JS Exception Handler
  320. *
  321. * TODO: Review PR#2492 for improvements.
  322. */
  323. // self::$instance->exception_handler_js = new NF_ExceptionHandlerJS();
  324. /*
  325. * Activation Hook
  326. * TODO: Move to a permanent home.
  327. */
  328. register_activation_hook( __FILE__, array( self::$instance, 'activation' ) );
  329. self::$instance->metaboxes[ 'append-form' ] = new NF_Admin_Metaboxes_AppendAForm();
  330. /*
  331. * Require EDD auto-update file
  332. */
  333. if( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
  334. // Load our custom updater if it doesn't already exist
  335. require_once( self::$dir . 'includes/Integrations/EDD/EDD_SL_Plugin_Updater.php');
  336. }
  337. require_once self::$dir . 'includes/Integrations/EDD/class-extension-updater.php';
  338. // If Ninja Forms was just upgraded...
  339. if ( $plugin_upgrade ) {
  340. // Ensure all of our tables have been defined.
  341. $migrations = new NF_Database_Migrations();
  342. $migrations->migrate();
  343. // If our db version is below 1.1...
  344. if ( version_compare( get_option( 'ninja_forms_db_version' ), '1.1', '<' ) ) {
  345. // Do our stage 1 updates.
  346. $migrations->do_stage_one();
  347. // Update our db version.
  348. update_option( 'ninja_forms_db_version', '1.1' );
  349. }
  350. // Fix for legacy versions that upgraded without a set DB version.
  351. // If our version is exactly 1.1...
  352. if ( version_compare( get_option( 'ninja_forms_db_version' ), '1.1', '==' ) ) {
  353. global $wpdb;
  354. // Fetch the form_title column from the fields table.
  355. $sql = "SHOW FULL COLUMNS FROM `{$wpdb->prefix}nf3_forms` WHERE Field = 'form_title'";
  356. $result = $wpdb->get_results( $sql, 'ARRAY_A' );
  357. // If we didn't get a result...
  358. if ( empty( $result ) ) {
  359. // Do our stage 1 updates, even though they should have already run.
  360. $migrations->do_stage_one();
  361. }
  362. }
  363. }
  364. }
  365. add_action( 'admin_notices', array( self::$instance, 'admin_notices' ) );
  366. add_action( 'plugins_loaded', array( self::$instance, 'plugins_loaded' ) );
  367. add_action( 'ninja_forms_available_actions', array( self::$instance, 'scrub_available_actions' ) );
  368. add_action( 'init', array( self::$instance, 'init' ), 5 );
  369. add_action( 'admin_init', array( self::$instance, 'admin_init' ), 5 );
  370. // Checks php version and..
  371. if( PHP_VERSION < 5.6 ) {
  372. // Pulls in the whip notice if the user is.
  373. add_action( 'admin_init', array( self::$instance, 'nf_whip_notice' ) );
  374. }
  375. add_action( 'admin_init', array( self::$instance, 'nf_do_telemetry' ) );
  376. add_action( 'admin_init', array( self::$instance, 'nf_plugin_add_suggested_privacy_content' ), 20 );
  377. return self::$instance;
  378. }
  379. public function init()
  380. {
  381. do_action( 'nf_init', self::$instance );
  382. }
  383. public function admin_init()
  384. {
  385. do_action( 'nf_admin_init', self::$instance );
  386. if ( isset ( $_GET[ 'nf-upgrade' ] ) && 'complete' == $_GET[ 'nf-upgrade' ] ) {
  387. Ninja_Forms()->dispatcher()->send( 'upgrade' );
  388. }
  389. add_filter( 'ninja_forms_dashboard_menu_items', array( $this, 'maybe_hide_dashboard_items' ) );
  390. // If we don't have clean data...
  391. if ( ! get_option( 'ninja_forms_data_is_clean' ) ) {
  392. // Register a new notice.
  393. add_filter( 'ninja_forms_admin_notices', array( $this, 'data_cleanup_notice' ) );
  394. }
  395. }
  396. /**
  397. * Privacy policy suggested content for Ninja Forms
  398. */
  399. function nf_plugin_add_suggested_privacy_content() {
  400. if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) return;
  401. $content = $this->plugin_get_default_privacy_content();
  402. wp_add_privacy_policy_content(
  403. __( 'Ninja Forms' ),
  404. wp_kses_post( wpautop( $content, false) ) );
  405. }
  406. /**
  407. * Return the default suggested privacy policy content.
  408. *
  409. * @return string The default policy content.
  410. */
  411. function plugin_get_default_privacy_content() {
  412. return
  413. '<h2>' . __( 'Ninja Forms allows you to collect personal information' ) . '</h2>' .
  414. '<p>' . __( 'If you are using Ninja Forms to collect personal information, you should consult a legal professional for your use case.' ) . '</p>';
  415. }
  416. /**
  417. * NF Whip Notice
  418. * If the user is on a version below PHP 5.6 then we get an instance of the
  419. * NF Whip class which will add a non-dismissible admin notice.
  420. *
  421. * @return NF_Whip
  422. */
  423. public function nf_whip_notice()
  424. {
  425. require_once self::$dir . '/includes/Libraries/Whip/NF_Whip.php';
  426. return new NF_Whip();
  427. }
  428. /**
  429. * Function to launch our various telemetry calls on admin_init.
  430. */
  431. public function nf_do_telemetry() {
  432. if ( ! has_filter( 'ninja_forms_settings_licenses_addons' ) && ( ! Ninja_Forms()->tracking->is_opted_in() || Ninja_Forms()->tracking->is_opted_out() ) ) {
  433. return false;
  434. }
  435. global $wpdb;
  436. // If we've not already sent table collation...
  437. if ( ! get_option( 'nf_tel_collate' ) ) {
  438. $collate = array();
  439. // Get the collation of the wp_options table.
  440. $sql = "SHOW FULL COLUMNS FROM `" . $wpdb->prefix . "options` WHERE Field = 'option_value'";
  441. $result = $wpdb->get_results( $sql, 'ARRAY_A' );
  442. $collate[ 'cache' ] = $result[ 0 ][ 'Collation' ];
  443. // Get the collation of the nf3_forms table.
  444. $sql = "SHOW FULL COLUMNS FROM `" . $wpdb->prefix . "nf3_forms` WHERE Field = 'title'";
  445. $result = $wpdb->get_results( $sql, 'ARRAY_A' );
  446. $collate[ 'forms' ] = $result[ 0 ][ 'Collation' ];
  447. // Send our data to api.ninjaforms.com.
  448. Ninja_Forms()->dispatcher()->send( 'table_collate', $collate );
  449. // Record an option so that we don't run this again.
  450. add_option( 'nf_tel_collate', '1', '', 'no' );
  451. }
  452. }
  453. public function maybe_hide_dashboard_items( $items )
  454. {
  455. $disable_marketing = false;
  456. if ( apply_filters( 'ninja_forms_disable_marketing', $disable_marketing ) ) {
  457. unset(
  458. $items[ 'apps' ],
  459. $items[ 'memberships' ],
  460. $items[ 'services' ]
  461. );
  462. }
  463. return $items;
  464. }
  465. public function scrub_available_actions( $actions )
  466. {
  467. foreach( $actions as $key => $action ){
  468. if ( ! is_plugin_active( $action[ 'plugin_path' ] ) ) continue;
  469. unset( $actions[ $key ] );
  470. }
  471. return $actions;
  472. }
  473. public function admin_notices()
  474. {
  475. // Notices filter and run the notices function.
  476. $admin_notices = Ninja_Forms()->config( 'AdminNotices' );
  477. self::$instance->notices->admin_notice( apply_filters( 'nf_admin_notices', $admin_notices ) );
  478. }
  479. public function plugins_loaded()
  480. {
  481. load_plugin_textdomain( 'ninja-forms', false, basename( dirname( __FILE__ ) ) . '/lang' );
  482. /*
  483. * Field Class Registration
  484. */
  485. self::$instance->fields = apply_filters( 'ninja_forms_register_fields', self::load_classes( 'Fields' ) );
  486. if( ! apply_filters( 'ninja_forms_enable_credit_card_fields', false ) ){
  487. unset( self::$instance->fields[ 'creditcard' ] );
  488. unset( self::$instance->fields[ 'creditcardcvc' ] );
  489. unset( self::$instance->fields[ 'creditcardexpiration' ] );
  490. unset( self::$instance->fields[ 'creditcardfullname' ] );
  491. unset( self::$instance->fields[ 'creditcardnumber' ] );
  492. unset( self::$instance->fields[ 'creditcardzip' ] );
  493. }
  494. /*
  495. * Form Action Registration
  496. */
  497. self::$instance->actions = apply_filters( 'ninja_forms_register_actions', self::load_classes( 'Actions' ) );
  498. /*
  499. * Merge Tag Registration
  500. */
  501. self::$instance->merge_tags = apply_filters( 'ninja_forms_register_merge_tags', self::$instance->merge_tags );
  502. /*
  503. * It's Ninja Time: Hook for Extensions
  504. */
  505. do_action( 'ninja_forms_loaded' );
  506. }
  507. /**
  508. * Autoloader
  509. *
  510. * Autoload Ninja Forms classes
  511. *
  512. * @param $class_name
  513. */
  514. public function autoloader( $class_name )
  515. {
  516. if( class_exists( $class_name ) ) return;
  517. /* Ninja Forms Prefix */
  518. if (false !== strpos($class_name, 'NF_')) {
  519. $class_name = str_replace('NF_', '', $class_name);
  520. $classes_dir = realpath(plugin_dir_path(__FILE__)) . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR;
  521. $class_file = str_replace('_', DIRECTORY_SEPARATOR, $class_name) . '.php';
  522. if (file_exists($classes_dir . $class_file)) {
  523. require_once $classes_dir . $class_file;
  524. }
  525. }
  526. /* WP Ninjas Prefix */
  527. if (false !== strpos($class_name, 'WPN_')) {
  528. $class_name = str_replace('WPN_', '', $class_name);
  529. $classes_dir = realpath(plugin_dir_path(__FILE__)) . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR;
  530. $class_file = str_replace('_', DIRECTORY_SEPARATOR, $class_name) . '.php';
  531. if (file_exists($classes_dir . $class_file)) {
  532. require_once $classes_dir . $class_file;
  533. }
  534. }
  535. }
  536. /*
  537. * PUBLIC API WRAPPERS
  538. */
  539. /**
  540. * Form Model Factory Wrapper
  541. *
  542. * @param $id
  543. * @return NF_Abstracts_ModelFactory
  544. */
  545. public function form( $id = '' )
  546. {
  547. global $wpdb;
  548. static $forms;
  549. if ( isset ( $forms[ $id ] ) ) {
  550. return $forms[ $id ];
  551. }
  552. $forms[ $id ] = new NF_Abstracts_ModelFactory( $wpdb, $id );
  553. return $forms[ $id ];
  554. }
  555. /**
  556. * Logger Class Wrapper
  557. *
  558. * Example Use:
  559. * Ninja_Forms()->logger()->log( 'debug', "Hello, {name}!", array( 'name' => 'world' ) );
  560. * Ninja_Forms()->logger()->debug( "Hello, {name}!", array( 'name' => 'world' ) );
  561. *
  562. * @return string
  563. */
  564. public function logger()
  565. {
  566. return $this->_logger;
  567. }
  568. public function dispatcher()
  569. {
  570. return $this->_dispatcher;
  571. }
  572. public function eos()
  573. {
  574. return new NF_EOS_Parser();
  575. }
  576. public function session()
  577. {
  578. if( ! $this->session ){
  579. $this->session = new NF_Session();
  580. $this->session->init();
  581. }
  582. return $this->session;
  583. }
  584. public function request( $action )
  585. {
  586. if( ! isset( $this->requests[ $action ] ) ) return new NF_AJAX_Requests_NullRequest();
  587. return $this->requests[ $action ];
  588. }
  589. public function background_process( $action )
  590. {
  591. if( ! isset( $this->requests[ $action ] ) ) return new NF_AJAX_Processes_NullProcess();
  592. return $this->requests[ $action ];
  593. }
  594. /**
  595. * Get a setting
  596. *
  597. * @param string $key
  598. * @param bool|false $default
  599. * @return bool
  600. */
  601. public function get_setting( $key = '', $default = false )
  602. {
  603. if( empty( $key ) || ! isset( $this->settings[ $key ] ) || empty( $this->settings[ $key ] ) ) return $default;
  604. return $this->settings[ $key ];
  605. }
  606. /**
  607. * Get all the settings
  608. *
  609. * @return array
  610. */
  611. public function get_settings()
  612. {
  613. return ( is_array( $this->settings ) ) ? $this->settings : array();
  614. }
  615. /**
  616. * Update a setting
  617. *
  618. * @param string $key
  619. * @param mixed $value
  620. * @param bool|false $defer_update Defer the database update of all settings
  621. */
  622. public function update_setting( $key, $value, $defer_update = false )
  623. {
  624. $this->settings[ $key ] = $value;
  625. if ( ! $defer_update ) {
  626. $this->update_settings();
  627. }
  628. }
  629. /**
  630. * Save settings to database
  631. *
  632. * @param array $settings
  633. */
  634. public function update_settings( $settings = array() )
  635. {
  636. if( ! is_array( $this->settings ) ) $this->settings = array();
  637. if( $settings && is_array( $settings ) ) {
  638. $this->settings = array_merge($this->settings, $settings);
  639. }
  640. update_option( 'ninja_forms_settings', $this->settings );
  641. }
  642. /**
  643. * Display Wrapper
  644. *
  645. * @param $form_id
  646. */
  647. public function display( $form_id, $preview = FALSE )
  648. {
  649. if( ! $form_id ) return;
  650. $noscript_message = __( 'Notice: JavaScript is required for this content.', 'ninja-forms' );
  651. $noscript_message = apply_filters( 'ninja_forms_noscript_message', $noscript_message );
  652. Ninja_Forms()->template( 'display-noscript-message.html.php', array( 'message' => $noscript_message ) );
  653. if( ! $preview ) {
  654. NF_Display_Render::localize($form_id);
  655. } else {
  656. NF_Display_Render::localize_preview($form_id);
  657. }
  658. }
  659. /*
  660. * PRIVATE METHODS
  661. */
  662. /**
  663. * Load Classes from Directory
  664. *
  665. * @param string $prefix
  666. * @return array
  667. */
  668. private static function load_classes( $prefix = '' )
  669. {
  670. $return = array();
  671. $subdirectory = str_replace( '_', DIRECTORY_SEPARATOR, str_replace( 'NF_', '', $prefix ) );
  672. $directory = 'includes/' . $subdirectory;
  673. foreach (scandir( self::$dir . $directory ) as $path) {
  674. $path = explode( DIRECTORY_SEPARATOR, str_replace( self::$dir, '', $path ) );
  675. $filename = str_replace( '.php', '', end( $path ) );
  676. $class_name = 'NF_' . $prefix . '_' . $filename;
  677. if( ! class_exists( $class_name ) ) continue;
  678. $return[ strtolower( $filename ) ] = new $class_name;
  679. }
  680. return $return;
  681. }
  682. /*
  683. * STATIC METHODS
  684. */
  685. /**
  686. * Template
  687. *
  688. * @param string $file_name
  689. * @param array $data
  690. */
  691. public static function template( $file_name = '', array $data = array(), $return = FALSE )
  692. {
  693. if( ! $file_name ) return FALSE;
  694. extract( $data );
  695. $path = self::$dir . 'includes/Templates/' . $file_name;
  696. if( ! file_exists( $path ) ) return FALSE;
  697. if( $return ) return file_get_contents( $path );
  698. include $path;
  699. }
  700. /**
  701. * Config
  702. *
  703. * @param $file_name
  704. * @return mixed
  705. */
  706. public static function config( $file_name )
  707. {
  708. return include self::$dir . 'includes/Config/' . $file_name . '.php';
  709. }
  710. /**
  711. * Activation
  712. */
  713. public function activation() {
  714. $migrations = new NF_Database_Migrations();
  715. $migrations->migrate();
  716. if( Ninja_Forms()->form()->get_forms() ) return;
  717. // Assume we're on a clean installation.
  718. update_option( 'ninja_forms_data_is_clean', 'true' );
  719. $form = Ninja_Forms::template( 'formtemplate-contactform.nff', array(), TRUE );
  720. Ninja_Forms()->form()->import_form( $form );
  721. }
  722. /**
  723. * Deprecated Notice
  724. *
  725. * Example: Ninja_Forms::deprecated_hook( 'ninja_forms_old', '3.0', 'ninja_forms_new', debug_backtrace() );
  726. *
  727. * @param $deprecated
  728. * @param $version
  729. * @param null $replacement
  730. * @param null $backtrace
  731. */
  732. public static function deprecated_notice( $deprecated, $version, $replacement = null, $backtrace = null )
  733. {
  734. do_action( 'ninja_forms_deprecated_call', $deprecated, $replacement, $version );
  735. $show_errors = current_user_can( 'manage_options' );
  736. // Allow plugin to filter the output error trigger
  737. if ( WP_DEBUG && apply_filters( 'ninja_forms_deprecated_function_trigger_error', $show_errors ) ) {
  738. if ( ! is_null( $replacement ) ) {
  739. trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Ninja Forms version %2$s! Use %3$s instead.', 'ninja-forms' ), $deprecated, $version, $replacement ) );
  740. // trigger_error( print_r( $backtrace, 1 ) ); // Limited to previous 1028 characters, but since we only need to move back 1 in stack that should be fine.
  741. // Alternatively we could dump this to a file.
  742. } else {
  743. trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Ninja Forms version %2$s.', 'ninja-forms' ), $deprecated, $version ) );
  744. // trigger_error( print_r( $backtrace, 1 ) );// Limited to previous 1028 characters, but since we only need to move back 1 in stack that should be fine.
  745. // Alternatively we could dump this to a file.
  746. }
  747. }
  748. }
  749. /**
  750. * Function to register an admin notice if we detect that this installation has "unclean" Ninja Forms data.
  751. *
  752. * @since 3.3.1
  753. *
  754. * @param $notices (Array) Our array of admin notices.
  755. * @return $notices (Array) Our array of admin notices.
  756. */
  757. public function data_cleanup_notice( $notices ) {
  758. $notices[ 'data_cleanup' ] = array(
  759. 'title' => __( 'Data Cleanup', 'ninja-forms' ),
  760. 'msg' => sprintf( __( 'Ninja Forms has detected data on your site leftover from old forms or Ninja Forms versions.%sWe would like to run a quick cleanup process to remove this old data. Your forms will not be impacted by this process, but it may take several minutes to complete.%sPlease %sclick here%s to begin.', 'ninja-forms' ), '<br />', '<br /><br />', '<a href="' . admin_url( 'admin.php?page=ninja-forms&action=cleanup' ) . '">', '</a>' ),
  761. 'int' => 0,
  762. 'ignore_spam' => true,
  763. 'dismiss' => 0
  764. );
  765. return $notices;
  766. }
  767. } // End Class Ninja_Forms
  768. /**
  769. * The main function responsible for returning The Highlander Ninja_Forms
  770. * Instance to functions everywhere.
  771. *
  772. * Use this function like you would a global variable, except without needing
  773. * to declare the global.
  774. *
  775. * Example: <?php $nf = Ninja_Forms(); ?>
  776. *
  777. * @since 2.7
  778. * @return Ninja_Forms Highlander Instance
  779. */
  780. function Ninja_Forms()
  781. {
  782. return Ninja_Forms::instance();
  783. }
  784. Ninja_Forms();
  785. /*
  786. |--------------------------------------------------------------------------
  787. | Uninstall Hook
  788. |--------------------------------------------------------------------------
  789. */
  790. register_uninstall_hook( __FILE__, 'ninja_forms_uninstall' );
  791. function ninja_forms_uninstall(){
  792. if( Ninja_Forms()->get_setting( 'delete_on_uninstall' ) ) {
  793. require_once plugin_dir_path(__FILE__) . '/includes/Database/Migrations.php';
  794. $migrations = new NF_Database_Migrations();
  795. $migrations->nuke(TRUE, TRUE);
  796. $migrations->nuke_settings(TRUE, TRUE);
  797. $migrations->nuke_deprecated(TRUE, TRUE);
  798. }
  799. }
  800. // Scheduled Action Hook
  801. function nf_optin_update_environment_vars() {
  802. /**
  803. * Send updated environment variables.
  804. */
  805. Ninja_Forms()->dispatcher()->update_environment_vars();
  806. /**
  807. * Make sure that we've reported our opt-in.
  808. */
  809. if( get_option( 'ninja_forms_optin_reported', 0 ) ) return;
  810. Ninja_Forms()->dispatcher()->send( 'optin', array( 'send_email' => 1 ) );
  811. // Debounce opt-in dispatch.
  812. update_option( 'ninja_forms_optin_reported', 1 );
  813. }
  814. add_action( 'nf_optin_cron', 'nf_optin_update_environment_vars' );
  815. // Custom Cron Recurrences
  816. function nf_custom_cron_job_recurrence( $schedules ) {
  817. $schedules[ 'nf-monthly' ] = array(
  818. 'display' => __( 'Once per month', 'ninja-forms' ),
  819. 'interval' => 2678400,
  820. );
  821. return $schedules;
  822. }
  823. add_filter( 'cron_schedules', 'nf_custom_cron_job_recurrence' );
  824. // Schedule Cron Job Event
  825. function nf_optin_send_admin_email_cron_job() {
  826. if ( ! wp_next_scheduled( 'nf_optin_cron' ) ) {
  827. wp_schedule_event( current_time( 'timestamp' ), 'nf-monthly', 'nf_optin_cron' );
  828. }
  829. }
  830. add_action( 'wp', 'nf_optin_send_admin_email_cron_job' );
  831. }