Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
437 changes: 437 additions & 0 deletions admin-modern.css

Large diffs are not rendered by default.

148 changes: 148 additions & 0 deletions blocks/cforms-block.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/**
* cforms2 Gutenberg Block
* Modern block editor integration for cforms2
*/

const { registerBlockType } = wp.blocks;
const { SelectControl } = wp.components;
const { useSelect } = wp.data;
const { __ } = wp.i18n;

registerBlockType('cforms2/form', {
title: __('cforms2 Form', 'cforms2'),
description: __('Insert a cforms2 contact form', 'cforms2'),
category: 'widgets',
icon: 'feedback',
keywords: [
__('form', 'cforms2'),
__('contact', 'cforms2'),
__('cforms', 'cforms2')
],
attributes: {
formId: {
type: 'string',
default: '1'
},
formName: {
type: 'string',
default: ''
}
},
supports: {
html: false,
customClassName: false
},

edit: function(props) {
const { attributes, setAttributes } = props;
const { formId, formName } = attributes;

// Get available forms from cforms2 settings
const forms = useSelect((select) => {
// This would need to be populated via REST API or localized script
return window.cforms2_forms || [
{ id: '1', name: 'Contact Form' },
{ id: '2', name: 'Newsletter Signup' }
];
}, []);

const formOptions = forms.map(form => ({
label: form.name,
value: form.id
}));

return wp.element.createElement(
'div',
{ className: 'cforms2-block-editor' },
[
wp.element.createElement(
'div',
{
key: 'icon',
className: 'cforms2-block-icon',
style: {
textAlign: 'center',
padding: '20px',
border: '2px dashed #ccc',
borderRadius: '4px',
backgroundColor: '#f9f9f9'
}
},
[
wp.element.createElement(
'span',
{
key: 'dashicon',
className: 'dashicons dashicons-feedback',
style: { fontSize: '48px', color: '#666' }
}
),
wp.element.createElement(
'h3',
{ key: 'title' },
__('cforms2 Form', 'cforms2')
)
]
),
wp.element.createElement(
SelectControl,
{
key: 'select',
label: __('Select Form', 'cforms2'),
value: formId,
options: [
{ label: __('Choose a form...', 'cforms2'), value: '' },
...formOptions
],
onChange: (newFormId) => {
const selectedForm = forms.find(form => form.id === newFormId);
setAttributes({
formId: newFormId,
formName: selectedForm ? selectedForm.name : ''
});
}
}
),
formId && wp.element.createElement(
'div',
{
key: 'preview',
className: 'cforms2-block-preview',
style: {
marginTop: '15px',
padding: '15px',
backgroundColor: '#e8f4fd',
border: '1px solid #0073aa',
borderRadius: '4px'
}
},
[
wp.element.createElement(
'strong',
{ key: 'preview-label' },
__('Form Preview:', 'cforms2')
),
wp.element.createElement(
'p',
{ key: 'preview-text' },
__('Form ID:', 'cforms2') + ' ' + formId + (formName ? ' (' + formName + ')' : '')
),
wp.element.createElement(
'p',
{
key: 'preview-note',
style: { fontSize: '12px', color: '#666' }
},
__('The actual form will be displayed on the frontend.', 'cforms2')
)
]
)
]
);
},

save: function() {
// Return null for server-side rendering
return null;
}
});
9 changes: 5 additions & 4 deletions cforms.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
* Plugin URI: https://wordpress.org/plugins/cforms2/
* Description: cformsII is a customizable, flexible and powerful form plugin including simple spam protection, multi-step forms, role manager support and custom themes.
* Author: Oliver Seidel
* Version: 15.1.4
* Version: 16.0.0
* Requires at least: 6.9
* Text Domain: cforms2
*/
namespace Cforms2;

define('CFORMS2_VERSION', '15.1.4');
define('CFORMS2_VERSION', '16.0.0');

// Debug message handling.
if (!defined('WP_DEBUG_CFORMS2')) {
Expand Down Expand Up @@ -55,6 +55,7 @@
require_once plugin_dir_path(__FILE__) . 'lib_activate.php';
require_once plugin_dir_path(__FILE__) . 'lib_ajax.php';
require_once plugin_dir_path(__FILE__) . 'lib_aux.php';
require_once plugin_dir_path(__FILE__) . 'lib_blocks.php';
require_once plugin_dir_path(__FILE__) . 'lib_functions.php';
require_once plugin_dir_path(__FILE__) . 'lib_render.php';
require_once plugin_dir_path(__FILE__) . 'lib_validate.php';
Expand Down Expand Up @@ -96,8 +97,8 @@
}
}

// Attaching to hooks.
add_action('template_redirect', 'cforms2_start_session');
// Attaching to hooks - optimized session handling.
add_action('template_redirect', 'cforms2_conditional_start_session');
add_action('wp_ajax_submitcform', 'cforms2_submitcform');
add_action('wp_ajax_nopriv_submitcform', 'cforms2_submitcform');
add_action('plugins_loaded', function() {
Expand Down
21 changes: 16 additions & 5 deletions js/cforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,24 @@ function cforms_validate(no, directFormSubmission) {
var post_data = 'action=submitcform&_wpnonce='
+ cforms2_ajax.nonces['submitcform']
+ '&cforms_id=' + no + '&' + params;
jQuery.post(
cforms2_ajax.url,
post_data,
function (data) {
jQuery.ajax({
url: cforms2_ajax.url,
type: 'POST',
data: post_data,
dataType: 'json',
success: function(data) {
if (data && typeof data === 'object' && data.no !== undefined) {
cforms_setsuccessmessage(data);
} else {
// Invalid response format - use configured failure message
call_err(no, document.getElementById('cf_failure' + no).value, '');
}
);
},
error: function(jqXHR, textStatus, errorThrown) {
// Handle AJAX errors - use configured failure message
call_err(no, document.getElementById('cf_failure' + no).value, '');
}
});
};

var cforms_setsuccessmessage = function (message) {
Expand Down
5 changes: 5 additions & 0 deletions lib_ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
*/

function cforms2_json_die($no, $result, $html, $hide = false, $redirection = null) {
// Clear any previous output to ensure clean JSON
if (ob_get_length()) {
ob_clean();
}

header('Content-Type: application/json');
echo json_encode(array(
'no' => $no,
Expand Down
159 changes: 159 additions & 0 deletions lib_blocks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<?php
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* Gutenberg Block Integration for cforms2
* Provides modern block editor support
*/

/**
* Register cforms2 Gutenberg block
*/
function cforms2_register_gutenberg_block() {
// Check if Gutenberg is available
if (!function_exists('register_block_type')) {
return;
}

// Register block script
wp_register_script(
'cforms2-block',
plugin_dir_url(__FILE__) . 'blocks/cforms-block.js',
array(
'wp-blocks',
'wp-components',
'wp-data',
'wp-element',
'wp-i18n'
),
CFORMS2_VERSION,
true
);

// Localize script with available forms
$forms = cforms2_get_available_forms_for_block();
wp_localize_script('cforms2-block', 'cforms2_forms', $forms);

// Register block type
register_block_type('cforms2/form', array(
'editor_script' => 'cforms2-block',
'render_callback' => 'cforms2_render_block',
'attributes' => array(
'formId' => array(
'type' => 'string',
'default' => '1'
),
'formName' => array(
'type' => 'string',
'default' => ''
)
)
));
}

/**
* Get available forms for block editor
*/
function cforms2_get_available_forms_for_block() {
$forms = array();

try {
$form_settings = Cforms2\FormSettings::forms();

foreach ($form_settings as $form_id => $form) {
$id = $form_id === '' ? '1' : $form_id;
$forms[] = array(
'id' => $id,
'name' => $form->name() ?: sprintf(__('Form %s', 'cforms2'), $id)
);
}
} catch (Exception $e) {
// Fallback if forms can't be loaded
$forms[] = array(
'id' => '1',
'name' => __('Default Form', 'cforms2')
);
}

return $forms;
}

/**
* Render cforms2 block on frontend
*/
function cforms2_render_block($attributes) {
$form_id = isset($attributes['formId']) ? sanitize_text_field($attributes['formId']) : '1';

// Validate form ID
if (!cforms2_form_exists($form_id)) {
return '<div class="cforms2-error">' .
sprintf(__('cforms2: Form with ID "%s" not found.', 'cforms2'), esc_html($form_id)) .
'</div>';
}

// Use existing cforms2 shortcode functionality
return cforms2_shortcode(array('name' => $form_id));
}

/**
* Check if a form exists
*/
function cforms2_form_exists($form_id) {
try {
$form = Cforms2\FormSettings::form($form_id);
return $form !== null;
} catch (Exception $e) {
return false;
}
}

/**
* Add block category for cforms2
*/
function cforms2_add_block_category($categories, $post) {
return array_merge(
$categories,
array(
array(
'slug' => 'cforms2',
'title' => __('cforms2', 'cforms2'),
'icon' => 'feedback'
)
)
);
}

/**
* Initialize Gutenberg integration
*/
function cforms2_init_gutenberg() {
// Only load in admin and if Gutenberg is available
if (!is_admin() || !function_exists('register_block_type')) {
return;
}

add_action('init', 'cforms2_register_gutenberg_block');

// Add custom block category (WordPress 5.8+)
if (version_compare(get_bloginfo('version'), '5.8', '>=')) {
add_filter('block_categories_all', 'cforms2_add_block_category', 10, 2);
} else {
add_filter('block_categories', 'cforms2_add_block_category', 10, 2);
}
}

// Initialize Gutenberg integration
cforms2_init_gutenberg();
Loading