Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wpmudev-sls/710dfeb74ea99b77eae96505c0b1442d to your computer and use it in GitHub Desktop.
Save wpmudev-sls/710dfeb74ea99b77eae96505c0b1442d to your computer and use it in GitHub Desktop.
[Forminator] - ActiveCampaign Entries. List or Export Entries that were submitted with ActiveCampaign integration
<?php
/**
* Plugin Name: [Forminator] - ActiveCampaign Entries
* Plugin URI: https://premium.wpmudev.org/
* Description: List Entries that were submitted with ActiveCampaign integration plus an additional page to export those entires per form id
* Task: 0/11289012348292/1175920440914534
* Author: Panos Lyrakis @ WPMUDEV
* Author URI: https://premium.wpmudev.org/
* License: GPLv2 or later
*/
if ( ! defined( 'ABSPATH' ) || ( defined( 'WP_CLI' ) && WP_CLI ) ) {
return;
}
if ( ! class_exists( 'WPMUDEV_Forminator_ActiveCampaign_Entries' ) ) {
class WPMUDEV_Forminator_ActiveCampaign_Entries {
private static $_instance = null;
private static $current_step = 0;
private static $limit = 5;
private $entry_table = '';
private $entry_meta_table = '';
private $form_id_to_export = 6;
public static function instance() {
if( is_null( self::$_instance ) ){
self::$_instance = new WPMUDEV_Forminator_ActiveCampaign_Entries();
}
return self::$_instance;
}
private function __construct() {
add_action( 'admin_menu', array( $this, 'admin_menu' ), 99 );
add_action( 'wp_ajax_wpmudev_forminator_activecampaign_entries', array( $this, 'fetch_entries_ajax' ) );
add_action( 'wp_loaded', array( $this, 'listen_for_csv_export' ) );
}
public function fetch_entries_ajax() {
$_post_data = @file_get_contents( 'php://input' );
$post_data = json_decode( $_post_data );
self::$current_step = $post_data->step;
if ( ! class_exists( 'Forminator_Database_Tables' ) ) {
return;
}
$this->entry_table = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$this->entry_meta_table = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
if ( ! isset( $post_data->nonce ) || ! wp_verify_nonce( $post_data->nonce , 'wpmudev_forminator_activecampaign_entries_nonce' ) ) {
$return = array(
'success' => false,
'message' => 'AJAX nonce is nonsence'
);
wp_send_json( $return );
}
$message = $this->fetch_entries();
if ( ! $message || empty( $message ) ) {
self::$current_step = false;
}
$return = array(
'success' => true,
'message' => $message,
'current_step' => self::$current_step
);
wp_send_json( $return );
}
public function fetch_entries() {
global $wpdb;
$query = $wpdb->prepare( "
SELECT entries.*, entries_meta.meta_key, entries_meta.meta_value
FROM {$this->entry_table} as entries
LEFT JOIN
$this->entry_meta_table as entries_meta
ON entries.entry_id = entries_meta.entry_id
WHERE
entries_meta.meta_key LIKE 'forminator_addon_activecampaign_status-activecampaign%'
LIMIT %d, %d
", self::$current_step, self::$limit );
// entries.form_id = 2675 AND
// entries_meta.meta_key LIKE 'forminator_addon_activecampaign_status-activecampaign%' AND
// entries_meta.meta_value NOT LIKE '%Successfully send data to ActiveCampaign%'
self::$current_step += self::$limit;
$results = $wpdb->get_results( $query );
if ( empty( $results ) ) {
return false;
}
return json_encode( $this->preformat_results( $results ) );
}
private function preformat_results( $results ) {
if ( empty( $results ) ) {
return;
}
$return = array();
foreach ( $results as $result ) {
$meta_value = maybe_unserialize( $result->meta_value );
$email = isset( $meta_value[ 'data_sent' ][ 'email' ] ) ? $meta_value[ 'data_sent' ][ 'email' ] : '';
$return[] = array(
'entry_id' => $result->entry_id,
'entry_type' => $result->entry_type,
'form_id' => $result->form_id,
'is_spam' => $result->is_spam,
'date_created' => $result->date_created,
'meta_key' => $result->meta_key,
'meta_value' => $result->meta_value,
'email' => $email
);
}
return $return;
}
public function admin_page() {
?>
<div id="forminator-activecampaign-entries-page">
<h3>ActiveCampaine Entries List</h3>
<form>
<label>Click on the button to start listing entries with ActiveCampaign</label>
<div><button id="wpmudev-forminator-list-activecamp">Start Listing</button></div>
<?php wp_nonce_field( 'wpmudev_forminator_activecampaign_entries_nonce', 'wpmudev_forminator_activecampaign_entries_nonce' ); ?>
<div><em>The list will get fetch entries in batches with remote requests</em></div>
</form>
<div id="forminator-activecampaign-entries-list"><table></table></div>
</div>
<script type="text/javascript">
($=>{
WPMUDEV_Forminator_ActiveCampaign_Entries = {
button : $( '#wpmudev-forminator-list-activecamp' ),
placeholder : $( '#forminator-activecampaign-entries-list' ),
table : '',
table_row_count : 0,
current_step : 0,
meta_keys : {
'entry_id': 'Entry id',
'entry_type': 'Entry type',
'form_id': 'Form id',
'is_spam': 'Is spam',
'date_created': 'Date created',
//'meta_key': 'A/ActiveCampaign key',
//'meta_value': 'Value',
'email': 'Email'
},
init : function(){
this.table = this.placeholder.find( 'table' );
this.button.on( 'click', this.run );
},
run : async function( e ){
let _this = WPMUDEV_Forminator_ActiveCampaign_Entries,
_self = $( this ),
body = {
step : _this.current_step,
nonce : $( '#wpmudev_forminator_activecampaign_entries_nonce' ).val()
};
if ( typeof e !== 'undefined' ) {
e.preventDefault();
_this.placeholder.prepend( '<h3>Please wait while entries are being fetched. It might take a while</h3> <h4>Make sure you don\'t close or refresh this tab until all entries are fetched</h4>' );
_this.prepare_table();
}
_this.button.hide( 300, function(){ $(this).remove(); });
const response = await fetch( `${window.ajaxurl}?action=wpmudev_forminator_activecampaign_entries`, {
method: 'POST', // or 'PUT'
body: JSON.stringify( body )
});
json = await response.json();
if ( json.success ) {
if ( '' === json.message || null === json.message || ! json.current_step ) {
_this.placeholder.find( "h3, h4" ).remove();
_this.placeholder.prepend( '<h3>All entries have been fetched</h3>' );
alert( 'All entries have been fetched' );
return;
}
let message = _this.format_results( JSON.parse( json.message ) );
_this.table.append( message );
_this.current_step = json.current_step;
_this.run();
}
},
format_results: function( content ) {
if ( content.lenth === 0 ) {
return;
}
let _this = WPMUDEV_Forminator_ActiveCampaign_Entries,
response = '';
for ( let key in content ) {
let row = $( '<tr />' );
_this.table_row_count++;
row.append( $( '<td />' ).html( _this.table_row_count ) );
for ( let meta_key in _this.meta_keys ) {
let column = $( '<td />' );
//if ( 'email' === email ) {
// let json =
//}
if ( content[key].hasOwnProperty( meta_key ) ) {
column.html( content[key][ meta_key ] );
}
row.append( column );
}
response += `<tr>${row.html()}</tr>`;
}
return response;
},
prepare_table: function() {
let _this = WPMUDEV_Forminator_ActiveCampaign_Entries,
table_head = $( '<thead />' ),
head_row = $( '<tr />' );
head_row.append( $( '<td />' ).html( 'Count' ) );
for ( let meta_key in WPMUDEV_Forminator_ActiveCampaign_Entries.meta_keys ) {
head_row.append( $( '<td />' ).html( _this.meta_keys[meta_key] ) );
}
table_head.append( head_row );;
_this.table.append( table_head ).addClass( 'wp-list-table widefat fixed striped posts' );
}
};
$(document).ready( WPMUDEV_Forminator_ActiveCampaign_Entries.init() );
})(jQuery);
</script>
<style type="text/css">
#forminator-activecampaign-entries-list table tr {
vertical-align: top;
}
</style>
<?php
}
public function export_entries_page() {
?>
<h2>Export ActiveCampaign Entries to csv</h2>
<?php
if ( isset( $_REQUEST['form_id'] ) ) {
?>
<h3>Export should be downloaded any minute now</h3>
<?php
}
?>
<form method="get">
<input type="hidden" name="page" value="forminator-activecampaign-entries-export" />
<div>
<label>Form id</label>
<input type="number" name="form_id">
</div>
<div>
<input type="submit" name="" value="Download CSV" />
</div>
</form>
<?php
}
public function get_entries_data( $form_id ) {
if ( ! class_exists( 'Forminator_Database_Tables' ) ) {
return;
}
global $wpdb;
$form_id = intval( $form_id );
$entries_data = array();
$this->entry_table = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$this->entry_meta_table = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$query = $wpdb->prepare( "
SELECT entries.entry_id, entries_meta.meta_value
FROM
{$this->entry_table}
as entries
LEFT JOIN
$this->entry_meta_table as entries_meta
ON entries.entry_id = entries_meta.entry_id
WHERE
entries_meta.meta_key LIKE 'forminator_addon_activecampaign_status-activecampaign%'
AND
entries.form_id=%d
", $form_id );
$results = $wpdb->get_results( $query );
$emails_list = array();
if ( ! empty( $results ) ) {
foreach ( $results as $result ) {
$meta_value = maybe_unserialize( $result->meta_value );
$success_key = 'Successfully';
$flag = ( isset( $meta_value[ 'description' ] ) && ( substr( $meta_value[ 'description' ], 0, strlen( $success_key ) ) === $success_key ) ) ? 'success' : 'fail';
$email = isset( $meta_value['data_sent']['email'] ) ? trim( $meta_value['data_sent']['email'] ) : '';
if ( ! empty( $email ) && in_array( $email, $emails_list ) ) {
continue;
}
$emails_list[] = $email;
$entries_data[] = [
'entry_id' => $result->entry_id,
'flag' => $flag,
'email' => $email
];
}
}
return $entries_data;
}
public function export_entries( $form_id ) {
$form_id = intval( $form_id );
$data = $this->get_entries_data( $form_id );
if ( empty( $data ) ) {
exit();
}
$fp = fopen( 'php://output', 'w' );
ob_start();
foreach ( array_values( $data ) as $line ) {
$val = $this->get_formatted_csv_fields( $line );
fputcsv($fp, $val);
}
$filename = 'forminator-activecamp-' . date( 'ymdHis' ) . '.csv';
$output = ob_get_clean();
header( 'Content-Encoding: UTF-8' );
header( 'Content-type: text/csv; charset=UTF-8' );
header( 'Content-Disposition: attachment; filename="' . $filename . '";' );
// print BOM Char for Excel Compatible
echo chr( 239 ) . chr( 187 ) . chr( 191 );// wpcs xss ok. excel generated content
// make php send the generated csv lines to the browser
exit( $output );
}
public function get_formatted_csv_fields( $fields ) {
if ( empty( $fields ) || ! is_array( $fields ) ) {
return $fields;
}
$formatted_fields = array();
foreach ( $fields as $field ) {
if ( ! is_scalar( $field ) ) {
$formatted_fields[] = '';
continue;
}
if ( is_scalar( $field ) ) {
$formatted_fields[] = $this->escape_csv_data( $field );
}
}
return $formatted_fields;
}
public function escape_csv_data( $data ) {
$active_content_triggers = array( '=', '+', '-', '@' );
if ( in_array( mb_substr( $data, 0, 1 ), $active_content_triggers, true ) ) {
$data = "'" . $data . "'";
}
return $data;
}
public function listen_for_csv_export() {
if ( ! isset( $_REQUEST['page'] ) || 'forminator-activecampaign-entries-export' !== $_REQUEST['page'] || ! isset( $_REQUEST['form_id'] ) ) {
return;
}
$form_id = intval( $_REQUEST['form_id'] );
$this->export_entries( $form_id );
}
public function admin_menu() {
add_submenu_page(
'forminator' ,
'ActiveCampaing Entries',
'ActiveCampaing Entries',
'manage_options',
'forminator-activecampaign-entries',
array( $this, 'admin_page' )
);
add_submenu_page(
'forminator' ,
'Export ActiveCampaing Entries',
'Export ActiveCampaing Entries',
'manage_options',
'forminator-activecampaign-entries-export',
array( $this, 'export_entries_page' )
);
}
}
if ( ! function_exists( 'wpmudev_forminator_activecampaign_entries' ) ) {
function wpmudev_forminator_activecampaign_entries(){
return WPMUDEV_Forminator_ActiveCampaign_Entries::instance();
};
add_action( 'plugins_loaded', 'wpmudev_forminator_activecampaign_entries', 10 );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment