From bc5d04528800740e4c1322b94e099ec18125dd2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lucas=20Garc=C3=ADa?= <lucas@codeccoop.org>
Date: Fri, 19 Jan 2024 18:48:32 +0100
Subject: [PATCH] feat: add api endpoints on options page

---
 includes/options-page.php            |  93 ---------------
 includes/settings/Menu.php           |  45 +++++++
 includes/settings/Setting.php        | 169 +++++++++++++++++++++++++++
 includes/settings/fieldsetControl.js |  42 +++++++
 includes/settings/index.php          |  18 +++
 includes/webhooks.php                |   4 +-
 wpct-erp-forms.php                   |   7 +-
 7 files changed, 280 insertions(+), 98 deletions(-)
 delete mode 100644 includes/options-page.php
 create mode 100644 includes/settings/Menu.php
 create mode 100644 includes/settings/Setting.php
 create mode 100644 includes/settings/fieldsetControl.js
 create mode 100644 includes/settings/index.php

diff --git a/includes/options-page.php b/includes/options-page.php
deleted file mode 100644
index a74816a..0000000
--- a/includes/options-page.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-
-/**
- * Define menu page.
- */
-add_action('admin_menu', 'wpct_erp_forms_add_admin_menu');
-function wpct_erp_forms_add_admin_menu()
-{
-    add_options_page(
-        'WPCT ERP Forms',
-        'WPCT ERP Forms',
-        'manage_options',
-        'wpct_erp_forms',
-        'wpct_erp_forms_render'
-    );
-}
-
-/**
- * Paint the settings page
- */
-function wpct_erp_forms_render()
-{
-    echo '<div class="wrap">';
-    echo '<h1>WPCT ERP Forms</h1>';
-    echo '<form action="options.php" method="post">';
-    settings_fields('wpct_erp_forms');
-    do_settings_sections('wpct_erp_forms');
-    submit_button();
-    echo '</form>';
-    echo '</div>';
-}
-
-/**
- * Define settings.
- */
-add_action('admin_init', 'wpct_erp_forms_init_settings', 50);
-function wpct_erp_forms_init_settings()
-{
-    register_setting(
-        'wpct_erp_forms',
-        'wpct_erp_forms_general',
-        array(
-            'type' => 'array',
-            'description' => __('Configuració global dels formularis', 'wpct-erp-forms'),
-            'show_in_rest' => false,
-            'default' => array(
-                'coord_id' => 0,
-                'notification_receiver' => 'admin@example.com'
-            )
-        )
-    );
-
-    // Secció general
-    add_settings_section(
-        'wpct_erp_forms_general_section',
-        __('Global', 'wpct-erp-forms'),
-        'wpct_erp_forms_general_section_render',
-        'wpct_erp_forms'
-    );
-    add_settings_field(
-        'notification_receiver',
-        __('Error notification receiver', 'wpct-erp-forms'),
-        fn () => wpct_erp_forms_option_render('notification_receiver'),
-        'wpct_erp_forms',
-        'wpct_erp_forms_general_section'
-    );
-    add_settings_field(
-        'coord_id',
-        __('ID de la coordinadora', 'wpct-erp-forms'),
-        fn () => wpct_erp_forms_option_render('coord_id'),
-        'wpct_erp_forms',
-        'wpct_erp_forms_general_section'
-    );
-}
-
-function wpct_erp_forms_option_getter($group, $option)
-{
-    $options = get_option($group) ? get_option($group) : [];
-    return key_exists($option, $options) ? $options[$option] : '';
-}
-
-function wpct_erp_forms_option_render($option)
-{
-    echo '<input type="text" name="wpct_erp_forms_general[' . $option . ']" value="' . wpct_erp_forms_option_getter('wpct_erp_forms_general', $option) . '">';
-}
-
-/**
- * Callbacks for the settings sections
- */
-function wpct_erp_forms_general_section_render()
-{
-    echo __('General settings', 'wpct-erp-forms');
-}
diff --git a/includes/settings/Menu.php b/includes/settings/Menu.php
new file mode 100644
index 0000000..84a8cf4
--- /dev/null
+++ b/includes/settings/Menu.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace WPCT_ERP_FORMS\Settings;
+
+class Menu
+{
+
+    private $setting = null;
+
+    public function __construct($setting)
+    {
+        $this->setting = $setting;
+    }
+
+    public function register()
+    {
+        add_options_page(
+            'WPCT ERP Forms',
+            'WPCT ERP Forms',
+            'manage_options',
+            $this->setting->getName(),
+            function () {
+                $this->render_page();
+            }
+        );
+    }
+
+    private function render_page()
+    {
+        ob_start();
+?>
+        <div class="wrap">
+            <h1>WPCT ERP Forms</h1>
+            <form action="options.php" method="post">
+                <?php
+                settings_fields($this->setting->getName());
+                do_settings_sections($this->setting->getName());
+                submit_button();
+                ?>
+            </form>
+        </div>
+<?php
+        echo ob_get_clean();
+    }
+}
diff --git a/includes/settings/Setting.php b/includes/settings/Setting.php
new file mode 100644
index 0000000..8eeaf42
--- /dev/null
+++ b/includes/settings/Setting.php
@@ -0,0 +1,169 @@
+<?php
+
+namespace WPCT_ERP_FORMS\Settings;
+
+class Setting
+{
+
+    private $_name = 'wpct_erp_forms';
+    private $_default_endpoint = '/api/private/crm-lead';
+
+    public function getName()
+    {
+        return $this->_name;
+    }
+
+    public function register()
+    {
+        /* General group  */
+        register_setting(
+            $this->_name,
+            'wpct_erp_forms_general',
+            [
+                'type' => 'array',
+                'description' => __('Configuració global dels formularis', 'wpct-erp-forms'),
+                'show_in_rest' => false,
+                'default' => [
+                    'coord_id' => 0,
+                    'notification_receiver' => 'admin@example.com',
+                ],
+            ]
+        );
+
+        /* General section */
+        add_settings_section(
+            'wpct_erp_forms_general_section',
+            __('General', 'wpct-erp-forms'),
+            function () {
+                echo '<p>' . __('General settings', 'wpct-erp-forms') . '</p>';
+            },
+            $this->_name,
+        );
+
+        /* General fields */
+        add_settings_field(
+            'notification_receiver',
+            __('Error notification receiver', 'wpct-erp-forms'),
+            function () {
+                echo $this->field_render('wpct_erp_forms_general', 'notification_receiver');
+            },
+            $this->_name,
+            'wpct_erp_forms_general_section'
+        );
+
+        add_settings_field(
+            'coord_id',
+            __('ID de la coordinadora', 'wpct-erp-forms'),
+            function () {
+                echo $this->field_render('wpct_erp_forms_general', 'coord_id');
+            },
+            $this->_name,
+            'wpct_erp_forms_general_section'
+        );
+
+        /* API group */
+        register_setting(
+            $this->_name,
+            'wpct_erp_forms_api',
+            [
+                'type' => 'array',
+                'description' => __('Configuració de la API dels formularis', 'wpct-erp-forms'),
+                'show_in_rest' => false,
+                'default' => [
+                    'endpoints' => [
+                        [
+                            'form_id' => 0,
+                            'endpoint' => $this->_default_endpoint
+                        ],
+                    ],
+                ]
+            ]
+        );
+
+        /* API section */
+        add_settings_section(
+            'wpct_erp_forms_api_section',
+            __('API', 'wpct-erp-forms'),
+            function () {
+                echo '<p>' . __('API settings', 'wpct-erp-forms') . '</p>';
+            },
+            $this->_name,
+        );
+
+        /* API fields */
+        add_settings_field(
+            'api_endpoints',
+            __('Endpoints', 'wpct-erp-forms'),
+            function () {
+                echo $this->field_render('wpct_erp_forms_api', 'endpoints');
+                echo $this->control_render('wpct_erp_forms_api', 'endpoints');
+            },
+            $this->_name,
+            'wpct_erp_forms_api_section',
+            [
+                'class' => 'wpct_erp_forms_api_endpoints'
+            ]
+        );
+    }
+
+    private function field_render($setting, $field, $value = null)
+    {
+        if ($value === null) $value = $this->option_getter($setting, $field);
+
+        if (!is_array($value)) {
+            return $this->input_render($setting, $field, $value);
+        } else {
+            return $this->fieldset_render($setting, $field, $value);
+        }
+    }
+
+    private function input_render($setting, $field, $value)
+    {
+        return "<input type='text' name='{$setting}[{$field}]' value='{$value}' />";
+    }
+
+    private function fieldset_render($setting, $field, $data)
+    {
+        $fieldset = "<table id='{$setting}[{$field}]'>";
+        $is_list = is_list($data);
+        foreach (array_keys($data) as $key) {
+            $fieldset .= '<tr>';
+            if (!$is_list) $fieldset .= "<th>{$key}</th>";
+            $_field = $field . '][' . $key;
+            $fieldset .= "<td>{$this->field_render($setting,$_field,$data[$key])}</td>";
+            $fieldset .= '</tr>';
+        }
+        $fieldset .= '</table>';
+
+        return $fieldset;
+    }
+
+    private function control_render($setting, $field)
+    {
+        ob_start();
+?>
+        <div class="<?= $setting; ?>[<?= $field ?>]--controls">
+            <button class="button button-primary" data-action="add">Add</button>
+            <button class="button button-secondary" data-action="remove">Remove</button>
+        </div>
+        <script>
+            <?php include 'fieldsetControl.js' ?>
+        </script>
+<?php
+        return ob_get_clean();
+    }
+
+    private function option_getter($setting, $option)
+    {
+        $setting = get_option($setting) ? get_option($setting) : [];
+        if (!key_exists($option, $setting)) return null;
+        return $setting[$option];
+    }
+}
+
+function is_list($arr)
+{
+    if (!is_array($arr)) return false;
+    if (sizeof($arr) === 0) return true;
+    return array_keys($arr) === range(0, count($arr) - 1);
+}
diff --git a/includes/settings/fieldsetControl.js b/includes/settings/fieldsetControl.js
new file mode 100644
index 0000000..09122d8
--- /dev/null
+++ b/includes/settings/fieldsetControl.js
@@ -0,0 +1,42 @@
+// Script to be buffered from settings class
+(function () {
+	function renderRowContent(key) {
+		return `<table id="<?= $setting ?>[<?= $field ?>][${key}]">
+                <tr>
+                    <th>form_id</th>
+                    <td><input type="text" name="<?= $setting ?>[<?= $field ?>][${key}][form_id]" value="0"></td>
+                </tr>
+                <tr>
+                    <th>endpoint</th>
+                    <td><input type="text" name="<?= $setting ?>[<?= $field ?>][${key}][endpoint]" value="<?= $this->_default_endpoint ?>"></td>
+                </tr>
+            </table>`;
+	}
+
+	function addItem(ev) {
+		ev.preventDefault();
+		const table = document.getElementById("<?= $setting ?>[<?= $field ?>]")
+			.children[0];
+		const tr = document.createElement("tr");
+		tr.innerHTML =
+			"<td>" + renderRowContent(table.children.length) + "</td>";
+		table.appendChild(tr);
+	}
+
+	function removeItem(ev) {
+		ev.preventDefault();
+		const table = document.getElementById("<?= $setting ?>[<?= $field ?>]")
+			.children[0];
+		const rows = table.children;
+		table.removeChild(rows[rows.length - 1]);
+	}
+
+	const buttons =
+		document.currentScript.previousElementSibling.querySelectorAll(
+			"button"
+		);
+	buttons.forEach((btn) => {
+		const callback = btn.dataset.action === "add" ? addItem : removeItem;
+		btn.addEventListener("click", callback);
+	});
+})();
diff --git a/includes/settings/index.php b/includes/settings/index.php
new file mode 100644
index 0000000..245fec4
--- /dev/null
+++ b/includes/settings/index.php
@@ -0,0 +1,18 @@
+<?php
+
+use WPCT_ERP_FORMS\Settings\Setting;
+use WPCT_ERP_FORMS\Settings\Menu;
+
+require_once 'Setting.php';
+require_once 'Menu.php';
+
+$wpct_erp_forms_setting = new Setting();
+$wpct_erp_forms_menu = new Menu($wpct_erp_forms_setting);
+
+add_action('admin_menu', function () use ($wpct_erp_forms_menu) {
+    $wpct_erp_forms_menu->register();
+});
+
+add_action('admin_init', function () use ($wpct_erp_forms_setting) {
+    $wpct_erp_forms_setting->register();
+});
diff --git a/includes/webhooks.php b/includes/webhooks.php
index 620128a..d958ba5 100644
--- a/includes/webhooks.php
+++ b/includes/webhooks.php
@@ -1,6 +1,6 @@
 <?php
-add_action('gform_after_submission', 'wpct_erp_forms_api_submissions', 10, 2);
-function wpct_erp_forms_api_submissions($entry, $form)
+add_action('wpct_erp_after_submission', 'wpct_erp_forms_do_submissions', 10, 2);
+function wpct_erp_forms_do_submissions($entry, $form)
 {
     $form_vals = wpct_erp_forms_parse_form_entry($entry, $form);
 
diff --git a/wpct-erp-forms.php b/wpct-erp-forms.php
index 0c71526..ab35c9e 100755
--- a/wpct-erp-forms.php
+++ b/wpct-erp-forms.php
@@ -8,13 +8,13 @@
  * Author URI:      https://www.codeccoop.org
  * Text Domain:     wpct-erp-forms
  * Domain Path:     /languages
- * Version:         1.0.3
+ * Version:         1.0.0
  *
  * @package         WPCT_ERP_Forms
  */
 
-/* Options Page */
-require_once "includes/options-page.php";
+/* Settings */
+require_once "includes/settings/index.php";
 
 /* Webhooks */
 require_once "includes/webhooks.php";
@@ -29,6 +29,7 @@ require_once "includes/fields/iban/index.php";
 
 /* Dependencies */
 add_filter('wpct_dependencies_check', function ($dependencies) {
+    $dependencies['Gravity Forms'] = '<a href="https://www.gravityforms.com/">Gravity Forms</a>';
     $dependencies['Wpct Odoo Connect'] = '<a href="https://git.coopdevs.org/coopdevs/website/wp/wp-plugins/wpct-odoo-connect">Wpct Odoo Connect</a>';
     return $dependencies;
 });
-- 
GitLab