0, // 0 = keep entries forever. ); } public function settings() { if ( null === $this->settings ) { $saved = get_option( self::OPTION, array() ); $this->settings = wp_parse_args( is_array( $saved ) ? $saved : array(), self::defaults() ); } return $this->settings; } public function update_settings( array $s ) { update_option( self::OPTION, $s, false ); $this->settings = null; } public function audit( $action, $message, $object_type = '', $object_id = 0 ) { $this->log( $action, $message, $object_type, $object_id ); } public function init() { foreach ( array( 'files', 'store', 'render', 'mailer', 'admin', 'io' ) as $f ) { require_once $this->dir( 'includes/class-forms-' . $f . '.php' ); } Bylt_Forms_Store::maybe_install(); if ( did_action( 'init' ) ) { Bylt_Forms_Store::register_cpt(); } else { add_action( 'init', array( 'Bylt_Forms_Store', 'register_cpt' ), 5 ); } $this->render = new Bylt_Forms_Render( $this ); $this->admin = new Bylt_Forms_Admin( $this ); $this->render->init(); $this->admin->init(); add_action( self::CRON, array( $this, 'cleanup' ) ); if ( ! wp_next_scheduled( self::CRON ) ) { wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', self::CRON ); } add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'register_exporter' ) ); add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'register_eraser' ) ); } public function mailer() { if ( ! $this->mailer ) { $this->mailer = new Bylt_Forms_Mailer(); } return $this->mailer; } /** Form Protection, when it's on, set up and the form wants it. */ public function protection( array $form ) { if ( 'yes' !== $form['settings']['protect'] || ! function_exists( 'bylt' ) || ! bylt()->is_active( 'form-protection' ) ) { return null; } $fp = bylt()->module( 'form-protection' ); return $fp && $fp->configured() ? $fp : null; } /** Form types: contact, quote, and any a module adds (e.g. wholesale application). */ public static function kinds() { return apply_filters( 'bylt_form_kinds', array( 'contact' => __( 'Contact', 'byltcommerce-toolkit' ), 'quote' => __( 'Quote request', 'byltcommerce-toolkit' ), ) ); } /** * Fields a form type always has (key, type, label, required, show, map…). * They can be relabelled and styled but not removed, retyped or disabled. */ public static function locked_fields( $kind ) { $out = apply_filters( 'bylt_form_locked_fields', array(), $kind ); return is_array( $out ) ? array_values( array_filter( $out, 'is_array' ) ) : array(); } /** Customer fields a form field can be saved to (key => label). */ public static function map_targets() { $t = array( 'first_name' => __( 'First name', 'byltcommerce-toolkit' ), 'last_name' => __( 'Last name', 'byltcommerce-toolkit' ), 'billing_company' => __( 'Billing company', 'byltcommerce-toolkit' ), 'billing_phone' => __( 'Billing phone', 'byltcommerce-toolkit' ), 'billing_address_1' => __( 'Billing address line 1', 'byltcommerce-toolkit' ), 'billing_address_2' => __( 'Billing address line 2', 'byltcommerce-toolkit' ), 'billing_city' => __( 'Billing city', 'byltcommerce-toolkit' ), 'billing_state' => __( 'Billing state / county', 'byltcommerce-toolkit' ), 'billing_postcode' => __( 'Billing postcode / ZIP', 'byltcommerce-toolkit' ), 'billing_country' => __( 'Billing country (2-letter code)', 'byltcommerce-toolkit' ), ); $t = apply_filters( 'bylt_form_map_targets', $t ); return is_array( $t ) ? $t : array(); } /** The visitor's IP (Cloudflare-aware). See Bylt_Ip. */ public static function client_ip() { return Bylt_Ip::client(); } public static function is_cloudflare( $ip ) { return Bylt_Ip::is_cloudflare( $ip ); } public static function in_range( $ip, $cidr ) { return Bylt_Ip::in_range( $ip, $cidr ); } /** Starting points for a new form. */ public static function templates() { return apply_filters( 'bylt_form_templates', self::core_templates(), self::class ); } /** A field for a template or locked list. */ public static function field( $key, $type, $label, $extra = array() ) { return array_merge( Bylt_Forms_Store::blank_field(), array( 'key' => $key, 'type' => $type, 'label' => $label ), $extra ); } private static function core_templates() { $f = array( __CLASS__, 'field' ); return array( 'contact' => array( 'name' => __( 'Contact form', 'byltcommerce-toolkit' ), 'fields' => array( $f( 'name', 'text', __( 'Name', 'byltcommerce-toolkit' ), array( 'required' => true, 'width' => 'half' ) ), $f( 'email', 'email', __( 'Email', 'byltcommerce-toolkit' ), array( 'required' => true, 'width' => 'half' ) ), $f( 'phone', 'tel', __( 'Phone', 'byltcommerce-toolkit' ), array( 'width' => 'half' ) ), $f( 'subject', 'text', __( 'Subject', 'byltcommerce-toolkit' ), array( 'width' => 'half' ) ), $f( 'message', 'textarea', __( 'Message', 'byltcommerce-toolkit' ), array( 'required' => true ) ), ), 'settings' => array( 'kind' => 'contact', 'submit_label' => __( 'Send message', 'byltcommerce-toolkit' ), 'notify_subject' => __( 'New message from {name}', 'byltcommerce-toolkit' ) ), ), 'quote' => array( 'name' => __( 'Quote request', 'byltcommerce-toolkit' ), 'fields' => array( $f( 'name', 'text', __( 'Name', 'byltcommerce-toolkit' ), array( 'required' => true, 'width' => 'half' ) ), $f( 'company', 'text', __( 'Company', 'byltcommerce-toolkit' ), array( 'width' => 'half' ) ), $f( 'email', 'email', __( 'Email', 'byltcommerce-toolkit' ), array( 'required' => true, 'width' => 'half' ) ), $f( 'phone', 'tel', __( 'Phone', 'byltcommerce-toolkit' ), array( 'width' => 'half' ) ), $f( 'product', 'text', __( 'Product', 'byltcommerce-toolkit' ), array( 'param' => 'quote_product', 'width' => 'half', 'help' => __( 'Filled in when you come from a product page.', 'byltcommerce-toolkit' ) ) ), $f( 'quantity', 'number', __( 'Quantity', 'byltcommerce-toolkit' ), array( 'width' => 'half', 'default' => '1' ) ), $f( 'needed_by', 'date', __( 'Needed by', 'byltcommerce-toolkit' ), array( 'width' => 'half' ) ), $f( 'details', 'textarea', __( 'Details', 'byltcommerce-toolkit' ), array( 'placeholder' => __( 'Sizes, options, delivery address…', 'byltcommerce-toolkit' ) ) ), ), 'settings' => array( 'kind' => 'quote', 'submit_label' => __( 'Request a quote', 'byltcommerce-toolkit' ), 'success' => __( 'Thanks! We\'ll send your quote shortly.', 'byltcommerce-toolkit' ), 'notify_subject' => __( 'Quote request: {product} from {name}', 'byltcommerce-toolkit' ), 'product_button' => 'no' ), ), 'blank' => array( 'name' => __( 'New form', 'byltcommerce-toolkit' ), 'fields' => array( $f( 'email', 'email', __( 'Email', 'byltcommerce-toolkit' ), array( 'required' => true ) ) ), 'settings' => array(), ), ); } public function cleanup() { $days = (int) $this->settings()['retention_days']; if ( $days <= 0 ) { return; } $before = gmdate( 'Y-m-d H:i:s', time() - $days * DAY_IN_SECONDS ); for ( $i = 0; $i < 50; $i++ ) { // Through the store, so uploaded files are deleted too. $old = Bylt_Forms_Store::entries( array( 'before' => $before, 'per_page' => 200 ) ); if ( ! $old['items'] || ! Bylt_Forms_Store::delete_entries( wp_list_pluck( $old['items'], 'id' ) ) ) { break; } } } /* --------------------------------------------------------------------- * Privacy (Tools → Export / Erase Personal Data) * ------------------------------------------------------------------- */ public function register_exporter( $list ) { $list['bylt-forms'] = array( 'exporter_friendly_name' => __( 'Form entries', 'byltcommerce-toolkit' ), 'callback' => array( $this, 'privacy_export' ) ); return $list; } public function register_eraser( $list ) { $list['bylt-forms'] = array( 'eraser_friendly_name' => __( 'Form entries', 'byltcommerce-toolkit' ), 'callback' => array( $this, 'privacy_erase' ) ); return $list; } public function privacy_export( $email, $page = 1 ) { $res = Bylt_Forms_Store::entries( array( 'email' => $email, 'page' => $page, 'per_page' => 100 ) ); $items = array(); foreach ( $res['items'] as $e ) { $form = Bylt_Forms_Store::get( $e['form_id'] ); $data = array( array( 'name' => __( 'Form', 'byltcommerce-toolkit' ), 'value' => $form ? $form['name'] : '#' . $e['form_id'] ), array( 'name' => __( 'Submitted', 'byltcommerce-toolkit' ), 'value' => $e['created_gmt'] . ' UTC' ) ); foreach ( Bylt_Forms_Mailer::rows( $form ? $form : array( 'fields' => array() ), $e['data'] ) as $r ) { $data[] = array( 'name' => $r[0], 'value' => $r[1] ); } $items[] = array( 'group_id' => 'bylt-forms', 'group_label' => __( 'Form entries', 'byltcommerce-toolkit' ), 'item_id' => 'bylt-form-entry-' . $e['id'], 'data' => $data ); } return array( 'data' => $items, 'done' => count( $res['items'] ) < 100 ); } public function privacy_erase( $email, $page = 1 ) { $res = Bylt_Forms_Store::entries( array( 'email' => $email, 'per_page' => 100 ) ); $n = Bylt_Forms_Store::delete_entries( wp_list_pluck( $res['items'], 'id' ) ); return array( 'items_removed' => $n, 'items_retained' => false, 'messages' => array(), 'done' => count( $res['items'] ) < 100 ); } }