]> _ Git - ccv-wordpress.git/commitdiff
Form processing, email generation + Elementor widget. WIP #3445 @8
authorStephen Cameron <stephen@cubedesigners.com>
Tue, 28 Apr 2020 16:53:41 +0000 (18:53 +0200)
committerStephen Cameron <stephen@cubedesigners.com>
Tue, 28 Apr 2020 16:53:41 +0000 (18:53 +0200)
15 files changed:
wp-content/mu-plugins/cube/src/Elementor/Setup.php
wp-content/mu-plugins/cube/src/Elementor/Widgets/Form.php [new file with mode: 0644]
wp-content/mu-plugins/cube/src/Elementor/Widgets/_Base.php
wp-content/mu-plugins/cube/src/Forms/Base.php
wp-content/mu-plugins/cube/src/Forms/Consultation.php
wp-content/mu-plugins/cube/src/Forms/Training.php
wp-content/mu-plugins/cube/src/Init.php
wp-content/mu-plugins/cube/src/Shortcodes/CCVForm.php [deleted file]
wp-content/themes/CCV/app/Composers/FormEmail.php [new file with mode: 0644]
wp-content/themes/CCV/resources/assets/styles/common/mixins.styl
wp-content/themes/CCV/resources/assets/styles/components/forms.styl
wp-content/themes/CCV/resources/views/forms/common/email.blade.php [new file with mode: 0644]
wp-content/themes/CCV/resources/views/forms/common/wrapper.blade.php [new file with mode: 0644]
wp-content/themes/CCV/resources/views/forms/consultation.blade.php
wp-content/themes/CCV/resources/views/forms/wrapper.blade.php [deleted file]

index 91d1732575965dbaeabd8ff0e80f2780f298186c..cbf6fc838756b4025549002175fc8bf4d809d9d9 100644 (file)
@@ -13,6 +13,9 @@ class Setup {
         // Customise Elementor "section" element to allow layout options (via CSS classes applied to main section element)
         $this->register_customisations();
 
+        // Register widget category with Elementor
+        add_action('elementor/elements/categories_registered', [$this, 'register_widgets_category']);
+
         // Register widgets with Elementor
         add_action('elementor/widgets/widgets_registered', [$this, 'register_widgets']);
     }
@@ -25,6 +28,12 @@ class Setup {
 
     }
 
+    // Ref: https://developers.elementor.com/widget-categories/
+    /* @var $manager \Elementor\Elements_Manager */
+    public function register_widgets_category($manager) {
+        $manager->add_category('cube', ['title' => 'Cubedesigners']);
+    }
+
 
     public function register_widgets() {
 
@@ -45,6 +54,7 @@ class Setup {
         $elementor->widgets_manager->register_widget_type( new Widgets\DynamicTable() );
         $elementor->widgets_manager->register_widget_type( new Widgets\FancyList() );
         $elementor->widgets_manager->register_widget_type( new Widgets\JustifiedList() );
+        $elementor->widgets_manager->register_widget_type( new Widgets\Form() );
     }
 
     protected function _customise_sections() {
diff --git a/wp-content/mu-plugins/cube/src/Elementor/Widgets/Form.php b/wp-content/mu-plugins/cube/src/Elementor/Widgets/Form.php
new file mode 100644 (file)
index 0000000..a712206
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+
+namespace Cube\Elementor\Widgets;
+
+use Elementor\Controls_Manager;
+use Cube\Forms\Base as BaseForm;
+
+use function Roots\view;
+
+class Form extends _Base {
+
+    protected $_has_template_content = false; // Tell Elementor that content is all rendered dynamically
+
+    // Widget name / ID
+    public function get_name() {
+        return 'cube-form';
+    }
+
+    // Elementor widget title
+    public function get_title() {
+        return __( 'Formulaire', 'cube' );
+    }
+
+    // Elementor interface icon
+    public function get_icon() {
+        return 'eicon-form-horizontal';
+    }
+
+    /**
+     * List of scripts the widget depends on.
+     * Used to set scripts dependencies required to run the widget.
+     *
+     * @since 1.0.0
+     * @access public
+     * @return array Widget scripts dependencies.
+     */
+    public function get_script_depends() {
+        return [];
+    }
+    /**
+     * Register the widget controls.
+     * Adds different input fields to allow the user to change and customize the widget settings.
+     *
+     * @since 1.0.0
+     * @access protected
+     */
+    protected function _register_controls() {
+
+        $form_base = new BaseForm();
+        $forms = $form_base->get_forms();
+
+        $this->start_controls_section(
+            'section_content',
+            [
+                'label' => __( 'Formulaire', 'cube' ),
+            ]
+        );
+
+        $this->add_control(
+            'form_name',
+            [
+                'type' => Controls_Manager::SELECT,
+                'label' => __( 'Formulaire', 'cube' ),
+                'label_block' => true,
+                'default' => '',
+                'options' => ['' => __('Sélectionner', 'cube')]
+                    + array_combine(array_keys($forms), array_map('ucfirst', array_keys($forms)))
+            ]
+        );
+
+        $this->add_control(
+            'destination',
+            [
+                'type' => Controls_Manager::TEXT,
+                'label' => __("L'adresse e-mail de destination", 'cube'),
+                'label_block' => true,
+                'default' => '',
+                'placeholder' => $form_base->get_destination(),
+            ]
+        );
+        
+        $this->end_controls_section();
+
+        $this->common_controls();
+    }
+    /**
+     * Render the widget output on the frontend.
+     * Written in PHP and used to generate the final HTML.
+     *
+     * @since 1.0.0
+     * @access protected
+     */
+    protected function render() {
+
+        $form_name = $this->get_settings('form_name');
+        $destination = $this->get_settings('destination');
+
+        // Serialize and encode configuration for use in hidden field
+        // Currently only the form name and destination address is set but this might be extended in the future
+        $config = base64_encode(serialize(compact('form_name', 'destination')));
+
+        $base_form = new BaseForm();
+        $forms = $base_form->get_forms();
+
+        if (!empty($form_name) && array_key_exists($form_name, $forms)) {
+            /* @var $form BaseForm */
+            $form = new $forms[$form_name];
+            $form->init();
+            echo view("forms.common.wrapper", compact('form', 'form_name', 'config'));
+        }
+
+        echo '';
+    }
+}
index 8f89208795f742c161345a325fd16b41ca14cf08..8ec94b34235aa2bc56bb69bd205a3596ead39c85 100644 (file)
@@ -9,8 +9,9 @@ abstract class _Base extends Widget_Base {
 
     // Where to display the widgets in the Elementor interface
     // Ref: https://developers.elementor.com/widget-categories/
+    // See Elementor/Setup.php for definition of the category
     public function get_categories() {
-        return [ 'theme-elements' ];
+        return ['cube'];
     }
 
     // Wrapper for including all common controls
index 533b4d8f419efb21f78873a5523f8b63d7fd116f..4a4c5d581e9747c3fae8112cd600dc7a6f13e0d6 100644 (file)
@@ -3,11 +3,12 @@
 namespace Cube\Forms;
 
 use function Roots\asset;
+use function Roots\view;
 
 class Base
 {
     private $action_name = 'cube_forms_process'; // Name of the AJAX action
-    private $destination = 'avis-medical@ccv-montpellier.fr'; // Default, can be overridden
+    private $destination = 'ccv@ccv-montpellier.fr'; // Default, can be overridden
 
     private $forms = [ // All available forms
         'consultation' => Consultation::class,
@@ -17,6 +18,8 @@ class Base
     private $fields = [];
     private $data;
 
+    public $form_title = '';
+
     // Field types
     const BINARY = 'binary';
     const CHECKBOX = 'checkbox';
@@ -117,8 +120,11 @@ class Base
             wp_send_json_error(new \WP_Error('nonce', 'Failed security validation'));
         }
 
-        // Next, check which form is being sent and if it is valid
-        $form_name = $_POST['_form_name'] ?? null;
+        // Next, get the form configuration and decode + unserialize it
+        $config = unserialize(base64_decode($_POST['config']));
+
+        //check which form is being sent and if it is valid
+        $form_name = $config['form_name'] ?? null;
 
         if (!($form_name && array_key_exists($form_name, $this->forms))) {
             wp_send_json_error(new \WP_Error('invalid_form', "Unknown form ($form_name)"));
@@ -128,6 +134,7 @@ class Base
         /* @var $form Base */
         $form = new $this->forms[$form_name];
         $form->register_fields();
+        $form->set_destination($config['destination']);
         $form->data = $this->get_form_data();
         $form->process();
         exit;
@@ -139,16 +146,34 @@ class Base
 
         $this->pre_process();
 
-        echo "SENDING FORM TO: {$this->destination}\n\n";
+        $headers = [];
+        $data = [];
+
+        $to           = $this->destination;
+        $from         = 'CCV <no-reply@ccv-montpellier.fr';
+        $subject      = $this->form_title;
+        $content_type = 'text/html';
+        $charset      = get_bloginfo('charset');
+        $headers[]    = sprintf('Content-Type: %s; charset=%s', $content_type, $charset);
+        $headers[]    = sprintf('From: %s', $from);
 
+        // Gather filled fields into label/value pairs
         foreach ($this->fields as $field_name => $field) {
+            // TODO: handle file upload fields - should it be removed from HTML and just attached? Or include the filename reference?
             if ($value = $this->data($field_name)) {
-                if (is_array($value)) $value = "\n- " . implode("\n- ", $value);
-                echo "{$field['title']} {$value}\n";
+                $data[$field['title']] = $value;
             }
         }
 
-        // ...
+        $message = view('forms.common.email', compact('data'));
+
+        $success = wp_mail($to, $subject, $message, $headers);
+
+        if ($success) {
+            wp_send_json_success(__('Success !', 'ccv'));
+        } else {
+            wp_send_json_error();
+        }
 
         $this->post_process();
     }
@@ -412,8 +437,15 @@ class Base
         return '<button type="'. $settings['type'] .'" class="'. $settings['class'] .'">'. $text .'</button>';
     }
 
-    function set_destination($address) {
-        $this->destination = $address;
+
+    public function get_destination() {
+        return $this->destination;
+    }
+
+    public function set_destination($address = '') {
+        if (!empty($address)) {
+            $this->destination = $address;
+        }
     }
 
     /**
index fac8333310b0a50d3c3c6243e52ca882e8272a20..f4aed020eec41082278240063dcb2e6b2af70ed9 100644 (file)
@@ -6,6 +6,10 @@ use function Roots\asset;
 
 class Consultation extends Base
 {
+    public function __construct() {
+        $this->form_title = __('Formulaire de consultation', 'ccv');
+    }
+
     public function register_scripts() {
 
         parent::register_scripts();
index 34aa422158516d3e34fa6dfda977bd2bcc2a03eb..49ae6157dabe22c183b612a2fb2b3afa947f4798 100644 (file)
@@ -4,6 +4,10 @@ namespace Cube\Forms;
 
 class Training extends Base
 {
+    public function __construct() {
+        $this->form_title = __('Demande de formation', 'ccv');
+    }
+
     public function register_scripts() {
         parent::register_scripts();
     }
index a34dd1a55392ac0f2c3b311a43563400d7bd4a5b..1ee6d4e63020828236b734b157f2ca7e79326153 100644 (file)
@@ -17,7 +17,6 @@ final class Init { // Marked as final because this class should never be extende
             Elementor\Setup::class,
             CPT\Person::class,
             CPT\ScientificNews::class,
-            Shortcodes\CCVForm::class,
             Forms\Base::class,
         ];
     }
diff --git a/wp-content/mu-plugins/cube/src/Shortcodes/CCVForm.php b/wp-content/mu-plugins/cube/src/Shortcodes/CCVForm.php
deleted file mode 100644 (file)
index 01768a4..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-namespace Cube\Shortcodes;
-
-use Cube\Forms;
-use function Roots\view;
-
-class CCVForm {
-
-    public $forms = [];
-
-    /**
-     * Common setup, will be automatically triggered by Init class if included
-     */
-    public function register() {
-
-        // Declare available forms (the key is the template name and the value is the form class)
-        $this->forms = [
-            'consultation' => Forms\Consultation::class,
-            'training' => Forms\Training::class,
-        ];
-
-        // Register [ccv_form] shortcode
-        add_shortcode('ccv_form', [$this, 'shortcode']);
-    }
-
-    public function shortcode($attributes) {
-
-        extract(shortcode_atts([
-            'name' => '', // Name of the form template
-        ], $attributes));
-
-        if (array_key_exists($name, $this->forms)) {
-            /* @var $form Forms\Base */
-            $form = new $this->forms[$name];
-            $form->init();
-            return view("forms/wrapper", compact('form', 'name'));
-        }
-
-        return false;
-    }
-
-}
diff --git a/wp-content/themes/CCV/app/Composers/FormEmail.php b/wp-content/themes/CCV/app/Composers/FormEmail.php
new file mode 100644 (file)
index 0000000..9eaa20c
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Composers;
+
+use Roots\Acorn\View\Composer;
+
+class FormEmail extends Composer
+{
+    protected static $views = [
+        'forms.common.email',
+    ];
+
+    public function with() {
+
+        $current_language = 'fr'; // Default fallback
+
+        // Fetch languages from Polylang
+        if (function_exists('pll_current_language')) {
+            $current_language = pll_current_language('slug'); // Get the two letter language code
+        }
+
+        return compact('current_language');
+    }
+}
index 900149e53e451f5cffa7f4c19f3b1a8a9e00eb26..bae3a8c391b5c6cc7802dec661d38950f868f6b6 100644 (file)
@@ -14,10 +14,10 @@ constrain(property, value = $horizontal-gutter, max-width = $base-width) {
   }
 
   // Prevent vw / % units from getting too small
-  +below(700px) {
+  +below(600px) {
     // Only do this if we are dealing with a percentage or vw unit
     if (unit(value) is '%' || unit(value) is 'vw') {
-      $min = 700px * unit(value / 100, '') // Convert percentage to a decimal
+      $min = 600px * unit(value / 100, '') // Convert percentage to a decimal
       {property}: round($min)
     }
   }
index d7e7bc2ab8131676de68b69fc9514b8ba7fc5510..49a283f575bb60f669077125022c84996e5ba77f 100644 (file)
@@ -25,6 +25,9 @@ input, textarea, select
   outline: none
   background-color: transparent
 
+textarea
+  @apply bg-white
+
 input[type="text"], input[type="email"], input[type="number"], select
   appearance: none
   border: none
diff --git a/wp-content/themes/CCV/resources/views/forms/common/email.blade.php b/wp-content/themes/CCV/resources/views/forms/common/email.blade.php
new file mode 100644 (file)
index 0000000..6ff73b7
--- /dev/null
@@ -0,0 +1,32 @@
+{{-- EMAIL TEMPLATE --}}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html lang="{{ $current_language }}" xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>CCV Formulaire</title>
+    <style type="text/css">
+      body {
+        font-family: Arial, sans-serif;
+      }
+    </style>
+  </head>
+  <body>
+    <table cellpadding="10" cellspacing="0" border="0">
+      @foreach($data as $label => $value)
+        <tr @if ($loop->even) bgcolor="#eeeeee" @endif>
+          <td valign="top"><strong>{{ $label }}</strong></td>
+          <td>
+            @if (is_array($value))
+              <ul style="margin-left: 0">
+                <li>{!! implode('</li><li>', $value) !!}</li>
+              </ul>
+            @else
+              {!! nl2br($value) !!}
+            @endif
+          </td>
+        </tr>
+      @endforeach
+    </table>
+  </body>
+</html>
diff --git a/wp-content/themes/CCV/resources/views/forms/common/wrapper.blade.php b/wp-content/themes/CCV/resources/views/forms/common/wrapper.blade.php
new file mode 100644 (file)
index 0000000..3f46456
--- /dev/null
@@ -0,0 +1,14 @@
+{{-- FORM WRAPPER--}}
+<form class="cube-form">
+
+  <noscript>
+    <div class="px-4v py-1v text-red font-bold italic">
+      {{ __("Cette demande nécessite l'emploi de JavaScript qui, soit a été désactivé, soit n'est pas reconnu par votre fureteur.", 'ccv') }}
+    </div>
+  </noscript>
+
+  <input type="hidden" name="config" value="{{ $config }}">
+
+  @includeIf("forms/$form_name")
+
+</form>
index ecf68795b56568f85f4267446023916a53772eb8..b44d8c39bfd43dd3e597c5cac5d4225b7e8c87b4 100644 (file)
           // Once the form is processed, this will be used to look up the e-mail address.
           'options' => array_combine(array_keys($form->get_field_options('surgeon')), array_keys($form->get_field_options('surgeon'))),
           'placeholder' => [
-            '' => __('Sélectionner') // First select option
+            '' => __('Sélectionner', 'ccv') // First select option
           ]
         ]) !!}
       </div>
diff --git a/wp-content/themes/CCV/resources/views/forms/wrapper.blade.php b/wp-content/themes/CCV/resources/views/forms/wrapper.blade.php
deleted file mode 100644 (file)
index fdf33c6..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{{-- FORM WRAPPER--}}
-<form class="cube-form">
-
-  <noscript>
-    <div class="px-4v py-1v text-red font-bold italic">
-      {{ __("Cette demande nécessite l'emploi de JavaScript qui, soit a été désactivé, soit n'est pas reconnu par votre fureteur.", 'ccv') }}
-    </div>
-  </noscript>
-
-  <input type="hidden" name="_form_name" value="{{ $name }}">
-
-  @includeIf("forms/$name")
-
-</form>