Skip to content

Commit

Permalink
Add deletion of events on the Forms page.
Browse files Browse the repository at this point in the history
  • Loading branch information
kagg-design committed Jan 31, 2025
1 parent 9b5860d commit 89b4f9b
Show file tree
Hide file tree
Showing 12 changed files with 373 additions and 89 deletions.
6 changes: 3 additions & 3 deletions assets/css/settings-base.css
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ body.settings_page_hcaptcha {
position: relative;
}

#hcaptcha-options table tr td input[type="checkbox"] {
#hcaptcha-options table tr td fieldset input[type="checkbox"] {
display: inline;
border: none;
box-shadow: none;
Expand All @@ -98,7 +98,7 @@ body.settings_page_hcaptcha {
margin-inline-start: 0;
}

#hcaptcha-options table tr td input[type="checkbox"]::before {
#hcaptcha-options table tr td fieldset input[type="checkbox"]::before {
background: url('../images/checkbox-off.svg');
background-size: cover;
margin: 0;
Expand All @@ -108,7 +108,7 @@ body.settings_page_hcaptcha {
display: inline-block;
}

#hcaptcha-options table tr td input[type="checkbox"]:checked::before {
#hcaptcha-options table tr td fieldset input[type="checkbox"]:checked::before {
background: no-repeat url('../images/checkbox-on.svg');
background-size: cover;
}
Expand Down
214 changes: 169 additions & 45 deletions assets/js/forms.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,180 @@
/* global Chart, HCaptchaFormsObject */
/* global jQuery, Chart, hCaptchaSettingsBase, HCaptchaListPageBaseObject, HCaptchaFormsObject */

/**
* @param HCaptchaFormsObject.served
* @param HCaptchaFormsObject.servedLabel
* @param HCaptchaFormsObject.unit
* @param HCaptchaListPageBaseObject.ajaxUrl
* @param HCaptchaListPageBaseObject.bulkAction
* @param HCaptchaListPageBaseObject.bulkNonce
* @param HCaptchaListPageBaseObject.noAction
* @param HCaptchaListPageBaseObject.noItems
* @param HCaptchaListPageBaseObject.DoingBulk
*/
document.addEventListener( 'DOMContentLoaded', function() {
const ctx = document.getElementById( 'formsChart' );
const aspectRatio = window.innerWidth > 600 ? 3 : 2;

new Chart( ctx, {
type: 'bar',
data: {
datasets: [
{
label: HCaptchaFormsObject.servedLabel,
backgroundColor: 'rgba(2,101,147,0.5)',
data: HCaptchaFormsObject.served,
borderWidth: 1,
},
],
},
options: {
responsive: true,
maintainAspectRatio: true,
aspectRatio,
scales: {
x: {
type: 'time',
time: {
displayFormats: {
millisecond: 'HH:mm:ss',
second: 'HH:mm:ss',
minute: 'HH:mm',
hour: 'HH:mm',
day: 'dd.MM.yyyy',
week: 'dd.MM.yyyy',
month: 'dd.MM.yyyy',
quarter: 'dd.MM.yyyy',
year: 'dd.MM.yyyy',

/**
* General settings page logic.
*
* @param {Object} $ jQuery instance.
*/
const forms = function( $ ) {
const headerBarSelector = '.hcaptcha-header-bar';
const msgSelector = '#hcaptcha-message';
let $message = $( msgSelector );

function initChart() {
const ctx = document.getElementById( 'formsChart' );
const aspectRatio = window.innerWidth > 600 ? 3 : 2;

new Chart( ctx, {
type: 'bar',
data: {
datasets: [
{
label: HCaptchaFormsObject.servedLabel,
backgroundColor: 'rgba(2,101,147,0.5)',
data: HCaptchaFormsObject.served,
borderWidth: 1,
},
],
},
options: {
responsive: true,
maintainAspectRatio: true,
aspectRatio,
scales: {
x: {
type: 'time',
time: {
displayFormats: {
millisecond: 'HH:mm:ss',
second: 'HH:mm:ss',
minute: 'HH:mm',
hour: 'HH:mm',
day: 'dd.MM.yyyy',
week: 'dd.MM.yyyy',
month: 'dd.MM.yyyy',
quarter: 'dd.MM.yyyy',
year: 'dd.MM.yyyy',
},
tooltipFormat: 'dd.MM.yyyy HH:mm',
unit: HCaptchaFormsObject.unit,
},
tooltipFormat: 'dd.MM.yyyy HH:mm',
unit: HCaptchaFormsObject.unit,
},
},
y: {
beginAtZero: true,
ticks: {
precision: 0,
y: {
beginAtZero: true,
ticks: {
precision: 0,
},
},
},
},
},
} );
} );
} );
}

function clearMessage() {
$message.remove();
// Concat below to avoid an inspection message.
$( '<div id="hcaptcha-message">' + '</div>' ).insertAfter( headerBarSelector );
$message = $( msgSelector );
}

function showMessage( message = '', msgClass = '' ) {
message = message === undefined ? '' : String( message );

if ( ! message ) {
return;
}

clearMessage();
$message.addClass( msgClass + ' notice is-dismissible' );

const messageLines = message.split( '\n' ).map( function( line ) {
return `<p>${ line }</p>`;
} );

$message.html( messageLines.join( '' ) );

$( document ).trigger( 'wp-updates-notice-added' );

$( 'html, body' ).animate(
{
scrollTop: $message.offset().top - hCaptchaSettingsBase.getStickyHeight(),
},
1000,
);
}

function showSuccessMessage( message = '' ) {
showMessage( message, 'notice-success' );
}

function showErrorMessage( message = '' ) {
showMessage( message, 'notice-error' );
}

function handleFormSubmit( event ) {
event.preventDefault();

const form = event.target.closest( 'form' );
const formData = new FormData( form );

const bulk = formData.get( 'action' );

if ( bulk === '-1' ) {
showErrorMessage( HCaptchaListPageBaseObject.noAction );

return;
}

const ids = formData.getAll( 'bulk-checkbox[]' ).map(
( id ) => {
const row = form.querySelector( `input[name="bulk-checkbox[]"][value="${ id }"]` ).closest( 'tr' );
const source = row.querySelector( 'td.name .hcaptcha-excerpt' ).dataset.source;
const formId = row.querySelector( 'td.form_id' ).textContent;

return { source, formId };
},
);

if ( ! ids.length ) {
showErrorMessage( HCaptchaListPageBaseObject.noItems );

return;
}

const data = {
action: HCaptchaListPageBaseObject.bulkAction,
nonce: HCaptchaListPageBaseObject.bulkNonce,
bulk,
ids: JSON.stringify( ids ),
};

$.post( {
url: HCaptchaListPageBaseObject.ajaxUrl,
data,
beforeSend: () => showSuccessMessage( HCaptchaListPageBaseObject.DoingBulk ),
} )
.done( function( response ) {
if ( ! response.success ) {
showErrorMessage( response.data );

return;
}

window.location.reload();
} )
.fail(
function( response ) {
showErrorMessage( response.statusText );
},
);
}

initChart();
document.getElementById( 'doaction' ).addEventListener( 'click', handleFormSubmit );
};

window.hCaptchaGeneral = forms;

jQuery( document ).ready( forms );
2 changes: 1 addition & 1 deletion assets/js/general.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ const general = function( $ ) {

function clearMessage() {
$message.remove();
// Concat below to avoid inspection message.
// Concat below to avoid an inspection message.
$( '<div id="hcaptcha-message">' + '</div>' ).insertAfter( headerBarSelector );
$message = $( msgSelector );
}
Expand Down
6 changes: 3 additions & 3 deletions assets/js/settings-list-page-base.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global HCaptchaFlatPickerObject, flatpickr */
/* global HCaptchaListPageBaseObject, flatpickr */

/**
* @param flatpickr.l10ns
Expand All @@ -17,8 +17,8 @@ document.addEventListener( 'DOMContentLoaded', function() {
hide: 'hcaptcha-hide',
selected: 'hcaptcha-is-selected',
};
const delimiter = HCaptchaFlatPickerObject.delimiter;
const locale = HCaptchaFlatPickerObject.locale;
const delimiter = HCaptchaListPageBaseObject.delimiter;
const locale = HCaptchaListPageBaseObject.locale;
let flatPickerObj;

const wrapper = document.getElementById( 'hcaptcha-options' );
Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ Instructions for popular native integrations are below:
* Added support for custom nonce action and name in the [hcaptcha] shortcode.
* Added compatibility with Cookies and Content Security Policy plugin.
* Added auto-verification of arbitrary forms in ajax.
* Added deletion of events on the Forms page.
* Improved error messaging for hCaptcha verification.
* Fixed IP detection in the WordPress core via filter, to sync with hCaptcha events information when the IP collection is activated.
* Fixed fatal error with the WPForms plugin in rare cases.
Expand Down
2 changes: 1 addition & 1 deletion src/php/Admin/Events/Events.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ public static function get_forms( array $args = [] ): array {
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
"SELECT
SQL_CALC_FOUND_ROWS
source, form_id, COUNT(*) as served
id, source, form_id, COUNT(*) as served
FROM $table_name
WHERE $where_date
GROUP BY source, form_id
Expand Down
39 changes: 36 additions & 3 deletions src/php/Admin/Events/FormsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public function __construct( string $plugin_page_hook ) {
*/
public function init(): void {
$this->columns = [
'cb' => '<input type="checkbox" />',
'name' => __( 'Source', 'hcaptcha-for-forms-and-more' ),
'form_id' => __( 'Form Id', 'hcaptcha-for-forms-and-more' ),
'served' => __( 'Served', 'hcaptcha-for-forms-and-more' ),
Expand Down Expand Up @@ -220,6 +221,36 @@ public function prepare_items(): void {
);
}

/**
* @global string $comment_status
*
* @return array
* @noinspection PhpMissingReturnTypeInspection
* @noinspection ReturnTypeCanBeDeclaredInspection
*/
protected function get_bulk_actions() {
$actions = [];

$actions['trash'] = __( 'Delete', 'hcaptcha-for-forms-and-more' );

return $actions;
}

/**
* Generate content for the checkbox column.
*
* @param object $item The current item.
* @return string The checkbox HTML.
*/
protected function column_cb( $item ): string {
$id = isset( $item->id ) ? (int) $item->id : 0;

return sprintf(
'<input type="checkbox" name="bulk-checkbox[]" value="%d" />',
$id
);
}

/**
* Column Source.
* Has 'name' slug not to be hidden.
Expand Down Expand Up @@ -248,7 +279,7 @@ protected function column_name( object $item ): string {

unset( $slug );

return $this->excerpt( implode( ', ', $source ), 15 );
return $this->excerpt( implode( ', ', $source ), 15, $item->source );
}

/**
Expand All @@ -266,16 +297,18 @@ protected function column_default( $item, $column_name ): string {
*
* @param string $text Text.
* @param int $length Excerpt length.
* @param string $source Source.
*
* @return string
*/
private function excerpt( string $text, int $length = 35 ): string {
private function excerpt( string $text, int $length = 35, string $source = '' ): string {
$excerpt = mb_substr( $text, 0, $length );

ob_start();

?>
<span class="hcaptcha-excerpt"><?php echo esc_html( $excerpt ); ?>
<span class="hcaptcha-excerpt" data-source="<?php echo esc_attr( $source); ?>">
<?php echo esc_html( $excerpt ); ?>
<span class="hcaptcha-hide"><?php echo esc_html( $text ); ?></span>
</span>
<?php
Expand Down
Loading

0 comments on commit 89b4f9b

Please sign in to comment.