Contact Form DB – Elementor - Version 1.8.0

Version Description

= * Bug Fixes

Download this release

Release Info

Developer webacetechs
Plugin Icon Contact Form DB – Elementor
Version 1.8.0
Comparing to
See all releases

Version 1.8.0

CHANGELOG.txt ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Changelog
2
+
3
+ V1.8.0
4
+ - Bug Fixes
5
+
6
+ V1.7 (2021-02-12)
7
+ - Added options to settings page which allow you to change the labels on the admin menu. Better for white labelling
8
+
9
+ V1.6 (2021-01-12)
10
+ - Added better handling of back end admin pages based on a report of a security exploit. Suggest update to a minimum of this plugin version asap
11
+
12
+ V1.5 (2019-11-07)
13
+ - Vastly improved the speed of the exports. Better for databases of more than 1000 submissions. Tested on a DB of 37k
14
+
15
+ V1.4 (2019-05-21)
16
+ - Minor preventative security related fixes
17
+
18
+ V1.3 (2019-05-13)
19
+ - Fixed conflict with new Elementor versions
20
+ - Added ability to show Export page to non admins (new setting on the settings page)
21
+ - Fixed issue whereby if more than one email was specified as an action then it would save two records
22
+
23
+ V1.2 (2018-09-15)
24
+ - Added export functionality by Form ID and by page submitted on
25
+ - Removed limiting CSS so that paging and bulk delete is possible
26
+ - Added settings page housing an option to hide the "nag", the red bar notifying of submissions
27
+
28
+ V1.0
29
+ - Initial Version
cat.png ADDED
Binary file
index.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php //nothing here! ?>
languages/elementor-contact-form-db.pot ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #, fuzzy
2
+ msgid ""
3
+ msgstr ""
4
+ "Project-Id-Version: Elementor Contact Form DB\n"
5
+ "Report-Msgid-Bugs-To: \n"
6
+ "POT-Creation-Date: 2022-07-26 13:31+0000\n"
7
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
+ "Language-Team: \n"
10
+ "Language: \n"
11
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
12
+ "MIME-Version: 1.0\n"
13
+ "Content-Type: text/plain; charset=UTF-8\n"
14
+ "Content-Transfer-Encoding: 8bit\n"
15
+ "X-Generator: Loco https://localise.biz/\n"
16
+ "X-Loco-Version: 2.6.2; wp-6.0.1\n"
17
+ "X-Domain: elementor-contact-form-db"
18
+
19
+ #. Description of the plugin
20
+ msgid ""
21
+ "A simple plugin to save contact form submissions in the database, designed "
22
+ "for the Elementor Form Module"
23
+ msgstr ""
24
+
25
+ #: sb_elementor_contact_form_db.php:838
26
+ msgid "Actions"
27
+ msgstr ""
28
+
29
+ #: sb_elementor_contact_form_db.php:888
30
+ msgid "Add New"
31
+ msgstr ""
32
+
33
+ #: sb_elementor_contact_form_db.php:892
34
+ msgid "All"
35
+ msgstr ""
36
+
37
+ #: sb_elementor_contact_form_db.php:194
38
+ msgid "By form_id (additional options in the form module)"
39
+ msgstr ""
40
+
41
+ #: sb_elementor_contact_form_db.php:180
42
+ msgid "By Page Submitted"
43
+ msgstr ""
44
+
45
+ #: sb_elementor_contact_form_db.php:797
46
+ msgid "Copy to another Post Type"
47
+ msgstr ""
48
+
49
+ #: sb_elementor_contact_form_db.php:228
50
+ msgid "CSV Content (by Form ID)"
51
+ msgstr ""
52
+
53
+ #: sb_elementor_contact_form_db.php:214
54
+ msgid "CSV Content (by Submitted Page)"
55
+ msgstr ""
56
+
57
+ #: sb_elementor_contact_form_db.php:170
58
+ msgid "Data Structure Updated. Refresh the page for a faster interface"
59
+ msgstr ""
60
+
61
+ #: sb_elementor_contact_form_db.php:837
62
+ msgid "Date Cloned"
63
+ msgstr ""
64
+
65
+ #: sb_elementor_contact_form_db.php:280
66
+ msgid "Disable Admin Nag?"
67
+ msgstr ""
68
+
69
+ #: sb_elementor_contact_form_db.php:890
70
+ msgid "Edit"
71
+ msgstr ""
72
+
73
+ #: sb_elementor_contact_form_db.php:633
74
+ msgid "Edit Page"
75
+ msgstr ""
76
+
77
+ #. Name of the plugin
78
+ msgid "Elementor Contact Form DB"
79
+ msgstr ""
80
+
81
+ #: sb_elementor_contact_form_db.php:887
82
+ msgctxt "Elementor DB"
83
+ msgid "Add New"
84
+ msgstr ""
85
+
86
+ #: sb_elementor_contact_form_db.php:901
87
+ msgid "For storing Elementor contact form submissions."
88
+ msgstr ""
89
+
90
+ #. Author URI of the plugin
91
+ msgid "https://webacetechs.in"
92
+ msgstr ""
93
+
94
+ #. URI of the plugin
95
+ msgid ""
96
+ "https://www.sean-barton.co.uk/2017/04/elementor-contact-form-db-free-plugin/"
97
+ msgstr ""
98
+
99
+ #: sb_elementor_contact_form_db.php:296
100
+ msgid "Minimum role to view records"
101
+ msgstr ""
102
+
103
+ #: sb_elementor_contact_form_db.php:889
104
+ msgid "New"
105
+ msgstr ""
106
+
107
+ #: sb_elementor_contact_form_db.php:835
108
+ msgid "New Post Title"
109
+ msgstr ""
110
+
111
+ #: sb_elementor_contact_form_db.php:896
112
+ msgid "No contact form submissions found in Trash."
113
+ msgstr ""
114
+
115
+ #: sb_elementor_contact_form_db.php:895
116
+ msgid "No contact form submissions found."
117
+ msgstr ""
118
+
119
+ #: sb_elementor_contact_form_db.php:665
120
+ msgid "Not a registered user"
121
+ msgstr ""
122
+
123
+ #: sb_elementor_contact_form_db.php:755
124
+ msgid "Oops something went wrong. This error message may be helpful:"
125
+ msgstr ""
126
+
127
+ #: sb_elementor_contact_form_db.php:653
128
+ msgid "Other submissions made by the same person"
129
+ msgstr ""
130
+
131
+ #: sb_elementor_contact_form_db.php:894
132
+ msgid "Parent:"
133
+ msgstr ""
134
+
135
+ #: sb_elementor_contact_form_db.php:215 sb_elementor_contact_form_db.php:229
136
+ msgid ""
137
+ "Please review the data below and press \"Download CSV File\" to start the "
138
+ "download. This list will show up to 50 submissions. The export will show the "
139
+ "full list."
140
+ msgstr ""
141
+
142
+ #: sb_elementor_contact_form_db.php:836
143
+ msgid "Post Type"
144
+ msgstr ""
145
+
146
+ #: sb_elementor_contact_form_db.php:879
147
+ msgctxt "post type singular name"
148
+ msgid "Elementor DB"
149
+ msgstr ""
150
+
151
+ #: sb_elementor_contact_form_db.php:893
152
+ msgid "Search"
153
+ msgstr ""
154
+
155
+ #: sb_elementor_contact_form_db.php:808
156
+ msgid "Select Field Mappings:"
157
+ msgstr ""
158
+
159
+ #: sb_elementor_contact_form_db.php:264
160
+ msgid "Settings saved successfully"
161
+ msgstr ""
162
+
163
+ #: sb_elementor_contact_form_db.php:742
164
+ msgid ""
165
+ "Successfully copied the content of this contact form submission to another "
166
+ "post type. Click here to"
167
+ msgstr ""
168
+
169
+ #: sb_elementor_contact_form_db.php:285
170
+ msgid ""
171
+ "The admin nag is the red box that shows at the top of your admin pages when "
172
+ "there is a contact submission to review. If you would prefer to use the "
173
+ "plugin as a backup only then just check this box to turn the nag off.."
174
+ msgstr ""
175
+
176
+ #: sb_elementor_contact_form_db.php:298
177
+ msgid ""
178
+ "The minimum role needed to export the records. Normally administrator but "
179
+ "some sites may use editor or other roles. Note that this settings page is "
180
+ "only ever usable by administrators."
181
+ msgstr ""
182
+
183
+ #: sb_elementor_contact_form_db.php:304
184
+ msgid "The name of the menu item to show. Good for white labelling for clients"
185
+ msgstr ""
186
+
187
+ #: sb_elementor_contact_form_db.php:310
188
+ msgid ""
189
+ "The secondary (singular) name of the post type to show. Good for white "
190
+ "labelling for clients"
191
+ msgstr ""
192
+
193
+ #: sb_elementor_contact_form_db.php:239
194
+ msgid ""
195
+ "This page will show a form when you have at least one submission. Until then,"
196
+ " enjoy this picture of a cat!"
197
+ msgstr ""
198
+
199
+ #: sb_elementor_contact_form_db.php:273
200
+ msgid ""
201
+ "This simple form will provide some handy switches and settings for the "
202
+ "plugin."
203
+ msgstr ""
204
+
205
+ #: sb_elementor_contact_form_db.php:139
206
+ msgid ""
207
+ "Use this simple form to export your contact data to CSV file. This is fairly "
208
+ "crude but we don\\'t have names for forms but we do have the page it was "
209
+ "submitted from. Elementor has the facility to give a form an ID (in the "
210
+ "additional tab of the builder). If set then you can also export by Form ID "
211
+ "which is perhaps more useful!"
212
+ msgstr ""
213
+
214
+ #: sb_elementor_contact_form_db.php:891
215
+ msgid "View"
216
+ msgstr ""
217
+
218
+ #: sb_elementor_contact_form_db.php:640
219
+ msgid "View User Profiile"
220
+ msgstr ""
221
+
222
+ #. Author of the plugin
223
+ msgid "Web Ace Tech Services"
224
+ msgstr ""
225
+
226
+ #: sb_elementor_contact_form_db.php:761
227
+ msgid ""
228
+ "You need to choose at least one field to map against for the clone to work."
229
+ msgstr ""
readme.txt ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Plugin Name ===
2
+ Contributors: webacetechs
3
+ Tags: elementor, elementor forms
4
+ Requires at least: 4.0
5
+ Tested up to: 6.0.1
6
+ Stable tag: 1.8.0
7
+ Requires PHP: 7.2 or higher
8
+ License: GPLv3 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
+
11
+ == Description ==
12
+
13
+ A simple plugin to store Elementor Pro Form submissions
14
+
15
+ This plugin stores contact form submissions from the Elementor Pro Form Module in a handy interface on the back end of WP.
16
+
17
+ To make things even better, this plugin both notifies admin users of unread messages via a banner but also allows you to convert these contact form requests into any other post type. This means you could use a contact form to get people to submit testimonials, case studies or even front end submitted content.
18
+
19
+ It makes a simple contact form into a very versatile module indeed.
20
+
21
+ You can also export your stored contact form data to a CSV file by page submitted on or by form name (if specified in the form module).
22
+
23
+ == Installation ==
24
+
25
+ Install the plugin like any other. All contact forms using the Elementor Pro Form module will thereafter automatically be recorded in the system. Emails will still be sent as normal so don't worry about that either!
26
+ Visit the admin page and you'll see a list of form submissions with their dates, page they were submitted on, number of times cloned, etc...
27
+
28
+
29
+ == Screenshots ==
30
+
31
+ 1. Submission List
32
+ 2. Individual Submission
33
+ 3. Copy to post type options
34
+ 4. Settings Page
35
+ 5. Export Page
36
+ 6. Interface
37
+
38
+ == Changelog ==
39
+
40
+
41
+ = V1.8.0 =
42
+ * Bug Fixes
43
+
44
+ = V1.7 (2021-02-12) =
45
+ * Added options to settings page which allow you to change the labels on the admin menu. Better for white labelling
46
+
47
+ = V1.6 (2021-01-12) =
48
+ * Added better handling of back end admin pages based on a report of a security exploit (CSRF). Suggest update to a minimum of this plugin version asap
49
+
50
+ = V1.5 (2019-11-07) =
51
+ * Vastly improved the speed of the exports. Better for databases of more than 1000 submissions. Tested on a DB of 37k
52
+
53
+ = V1.4 (2019-05-21) =
54
+ * Minor preventative security related fixes
55
+
56
+ = V1.3 (2019-05-13) =
57
+ * Fixed conflict with new Elementor versions
58
+ * Added ability to show Export page to non admins (new setting on the settings page)
59
+ * Fixed issue whereby if more than one email was specified as an action then it would save two records
60
+
61
+ = V1.2 (2018-09-15) =
62
+ * Added export functionality by Form ID and by page submitted on
63
+ * Removed limiting CSS so that paging and bulk delete is possible
64
+ * Added settings page housing an option to hide the "nag", the red bar notifying of submissions
65
+
66
+ = V1.1 =
67
+ * Fixed for latest version of Elementor Pro
68
+
sb_elementor_contact_form_db.php ADDED
@@ -0,0 +1,1006 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Plugin Name: Contact Form DB - Elementor
5
+ * Plugin URI: https://webacetechs.in
6
+ * Description: A simple plugin to save contact form submissions in the database, designed for the Elementor Form Module
7
+ * Author: Web Ace Tech Services
8
+ * Version: 1.8.0
9
+ * Author URI: https://webacetechs.in
10
+ * Text Domain: elementor-contact-form-db
11
+ * Domain Path: /languages
12
+ */
13
+
14
+ if(!defined( 'WPINC' )) {
15
+ die;
16
+ }
17
+
18
+ define( 'SB_ELEM_CFD_DB_ITEM_NAME', 'Elementor Contact Form DB' );
19
+ define( 'SB_ELEM_CFD_DB_VERSION', '1.8.0' );
20
+
21
+ add_action( 'plugins_loaded', 'sb_elem_cfd_init' );
22
+
23
+ function sb_elem_cfd_init() {
24
+ add_action( 'admin_enqueue_scripts', 'sb_elem_cfd_css_enqueue', 9999 );
25
+
26
+ add_action( 'elementor_pro/forms/new_record', 'sb_elem_cfd_new_record', 10, 10 );
27
+
28
+ add_action( 'add_meta_boxes', 'sb_elem_cfd_register_meta_box' );
29
+ add_action( 'init', 'sb_elem_cfd_pt_init' );
30
+ add_action( 'admin_notices', 'sb_elem_cfd_admin_notice' );
31
+ add_action( 'admin_head', 'sb_elem_cfd_admin_head' );
32
+ add_action( 'admin_menu', 'sb_elem_cfd_submenu' );
33
+ add_action( 'admin_init', 'sb_elem_cfd_download_csv', 1, 1 );
34
+
35
+ add_filter( 'manage_elementor_cf_db_posts_columns', 'sb_elem_cfd_columns_head', 100 );
36
+ add_action( 'manage_elementor_cf_db_posts_custom_column', 'sb_elem_cfd_columns_content', 100, 2 );
37
+ }
38
+
39
+ function sb_elem_cfd_submenu() {
40
+
41
+ $sb_elem_cfd = get_option( 'sb_elem_cfd' ) ? get_option( 'sb_elem_cfd' ) : '';
42
+ $min_role = (isset( $sb_elem_cfd['records_min_role'] ) ? sanitize_text_field($sb_elem_cfd['records_min_role']) : 'administrator');
43
+
44
+ add_submenu_page( 'edit.php?post_type=elementor_cf_db', 'Export', 'Export', $min_role, 'sb_elem_cfd', 'sb_elem_cfd_submenu_cb' );
45
+ add_submenu_page( 'edit.php?post_type=elementor_cf_db', 'Settings', 'Settings', 'manage_options', 'sb_elem_cfd_settings', 'sb_elem_cfd_settings_submenu_cb' );
46
+
47
+ sb_elem_cfd_disable_add_new();
48
+ }
49
+
50
+ function sb_elem_cfd_disable_add_new() {
51
+ // Hide sidebar link
52
+ global $submenu;
53
+ if(isset($submenu['edit.php?post_type=elementor_cf_db'][10])) unset( $submenu['edit.php?post_type=elementor_cf_db'][10] );
54
+
55
+ }
56
+
57
+ function sb_elem_cfd_box_start($title) {
58
+ return '<div class="postbox">
59
+ <h2 class="hndle">' . esc_attr($title) . '</h2>
60
+ <div class="inside">';
61
+ }
62
+
63
+ function sb_elem_cfd_download_csv() {
64
+
65
+ if(isset( $_REQUEST['download_csv'] )) {
66
+ if(!empty( $_POST['sb_elem_cfd_export'] )) {
67
+ if(wp_verify_nonce( $_POST['sb_elem_cfd_export'], 'sb_elem_cfd_export' )) {
68
+ echo '<input name="sb_elem_cfd_export" type="hidden" value="' . wp_create_nonce( 'sb_elem_cfd_export' ) . '" />';
69
+
70
+ if(isset( $_REQUEST['form_name'] )) {
71
+ $form_name = sanitize_text_field($_REQUEST['form_name']);
72
+ if($rows = sb_elem_cfd_get_export_rows( $form_name )) {
73
+
74
+ header( 'Content-Type: application/csv' );
75
+ header( 'Content-Disposition: attachment; filename=' . sanitize_title( $form_name ) . '.csv' );
76
+ header( 'Pragma: no-cache' );
77
+ $rows_html = implode( "\n", $rows );
78
+ echo esc_attr($rows_html);
79
+ die;
80
+ }
81
+ }
82
+
83
+ if(isset( $_REQUEST['form_id'] )) {
84
+ $form_id = sanitize_text_field($_REQUEST['form_id']);
85
+ if($rows = sb_elem_cfd_get_export_rows_by_form_id( $form_id )) {
86
+
87
+ header( 'Content-Type: application/csv' );
88
+ header( 'Content-Disposition: attachment; filename=' . sanitize_title( $form_id ) . '.csv' );
89
+ header( 'Pragma: no-cache' );
90
+ $rows_html = implode( "\n", $rows );
91
+ echo esc_attr($rows_html);
92
+ die;
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ function sb_elem_cfd_box_end() {
101
+ return ' <div style="clear: both;">&nbsp;</div></div>
102
+ </div>';
103
+ }
104
+
105
+
106
+ function sb_elem_cfd_submenu_cb() {
107
+ global $wpdb;
108
+
109
+ $forms = $forms2 = array();
110
+
111
+ $sql = 'SELECT DISTINCT(pm.meta_value) AS form_name
112
+ FROM
113
+ ' . $wpdb->posts . ' p
114
+ JOIN ' . $wpdb->postmeta . ' pm ON (
115
+ p.ID = pm.post_id AND
116
+ pm.meta_key = "sb_elem_cfd_form_id"
117
+ )
118
+ WHERE
119
+ p.post_type = "elementor_cf_db"
120
+ AND p.post_status = "publish"';
121
+
122
+
123
+ $sql2 = 'SELECT DISTINCT(pm.meta_value) AS submitted_id
124
+ FROM
125
+ ' . $wpdb->posts . ' p
126
+ JOIN ' . $wpdb->postmeta . ' pm ON (
127
+ p.ID = pm.post_id AND
128
+ pm.meta_key = "sb_elem_cfd_submitted_on_id"
129
+ )
130
+ WHERE
131
+ p.post_type = "elementor_cf_db"
132
+ AND p.post_status = "publish"';
133
+
134
+ echo '<div class="wrap"><div id="icon-tools" class="icon32"></div>';
135
+ $sb_item_name = SB_ELEM_CFD_DB_ITEM_NAME ? sanitize_text_field(SB_ELEM_CFD_DB_ITEM_NAME) : '';
136
+ $sb_version = SB_ELEM_CFD_DB_VERSION ? sanitize_text_field(SB_ELEM_CFD_DB_VERSION) : '';
137
+ echo '<h2>' . esc_attr($sb_item_name) . ' - Version ' . esc_attr($sb_version) . '</h2>';
138
+
139
+ echo '<div id="poststuff">';
140
+
141
+ echo '<div id="post-body" class="metabox-holder columns-2">';
142
+
143
+ echo sb_elem_cfd_box_start( 'Export Results' );
144
+
145
+ echo '<p>'.__("Use this simple form to export your contact data to CSV file. This is fairly crude but we don\'t have names for forms but we do have the page it was submitted from. Elementor has the facility to give a form an ID (in the additional tab of the builder). If set then you can also export by Form ID which is perhaps more useful!", "elementor-contact-form-db").'</p>';
146
+
147
+ if($form_names = $wpdb->get_results( $sql )) {
148
+ foreach($form_names as $form_name) {
149
+ $forms2[$form_name->form_name] = $form_name->form_name;
150
+ }
151
+ }
152
+
153
+ if($submitted_ids = $wpdb->get_results( $sql2 )) {
154
+ foreach($submitted_ids as $submitted_id) {
155
+ $forms[$submitted_id->submitted_id] = get_the_title( $submitted_id->submitted_id );
156
+ }
157
+ }
158
+
159
+ if(get_posts( 'post_type=elementor_cf_db&posts_per_page=1' )) { //get one record only. we don't need it but just to show there is a single submission
160
+
161
+ set_time_limit( 0 );
162
+ //delete_option('sb_elem_cfd_record_update_v15'); //debug
163
+
164
+ //updating old data for a faster structure
165
+ if(!get_option( 'sb_elem_cfd_record_update_v15' )) {
166
+ if($posts = get_posts( 'post_type=elementor_cf_db&posts_per_page=4000&meta_key=sb_elem_cfd_submitted_on_id&meta_compare=NOT EXISTS' )) {
167
+ echo __('Found ', 'elementor-contact-form-db') . esc_attr(count( $posts )) . __(' Items to convert.<br />', 'elementor-contact-form-db');
168
+
169
+ foreach($posts as $post) {
170
+ if($data = sb_elem_cfd_get_meta( $post->ID )) {
171
+ $forms[$data['extra']['submitted_on_id']] = $data['extra']['submitted_on'];
172
+ $k_submit_id = isset($data['extra']['submitted_on_id']) ? sanitize_text_field($data['extra']['submitted_on_id']) : '';
173
+ update_post_meta( $post->ID, 'sb_elem_cfd_submitted_on_id', $k_submit_id );
174
+ }
175
+ }
176
+
177
+ echo '<p>'.__('Data Structure Updated. Refresh the page for a faster interface', 'elementor-contact-form-db').'</p>';
178
+ } else {
179
+ update_option( 'sb_elem_cfd_record_update_v15', time() );
180
+ }
181
+
182
+ }
183
+
184
+ echo '<h3>'.__('Select a form to export', 'elementor-contact-form-db').'</h3>';
185
+
186
+ echo '<form method="POST" style="width: 48%; float: left;">';
187
+ echo '<p><strong>'.__('By Page Submitted', 'elementor-contact-form-db').'</strong></p>';
188
+ echo '<select style="margin-right: 10px; width: 200px;" name="form_name">';
189
+
190
+ ksort( $forms );
191
+ foreach($forms as $form => $label) {
192
+ echo '<option ' . (isset( $_REQUEST['form_name'] ) && $_REQUEST['form_name'] == $form ? 'selected="selected"' : '') . ' value="' . esc_attr($form) . '">' . esc_attr($label) . '</option>';
193
+ }
194
+
195
+ echo '</select>';
196
+ echo '<input type="submit" name="" class="button-primary" value="Export Form" />';
197
+ echo '<input name="sb_elem_cfd_export" type="hidden" value="' . wp_create_nonce( 'sb_elem_cfd_export' ) . '" />';
198
+ echo '</form>';
199
+
200
+ echo '<form method="POST" style="width: 48%; float: left;">';
201
+ echo '<p><strong>'.__('By form_id (additional options in the form module)', 'elementor-contact-form-db').'</strong></p>';
202
+ echo '<select style="margin-right: 10px; width: 200px;" name="form_id">';
203
+
204
+ ksort( $forms2 );
205
+ foreach($forms2 as $form) {
206
+ echo '<option ' . (isset( $_REQUEST['form_id'] ) && $_REQUEST['form_id'] == $form ? 'selected="selected"' : '') . ' value="' . esc_attr($form) . '">' . esc_attr($form) . '</option>';
207
+ }
208
+
209
+ echo '</select>';
210
+ echo '<input type="submit" name="" class="button-primary" value="Export Form" />';
211
+ echo '<input name="sb_elem_cfd_export" type="hidden" value="' . wp_create_nonce( 'sb_elem_cfd_export' ) . '" />';
212
+ echo '</form>';
213
+
214
+ echo '<div style="clear: both;">&nbsp;</div>';
215
+
216
+ if(isset( $_REQUEST['form_name'] )) {
217
+
218
+ $form_name = sanitize_text_field($_REQUEST['form_name']);
219
+ $rows = sb_elem_cfd_get_export_rows( $form_name, 50 );
220
+
221
+ echo '<h3>'.__('CSV Content (by Submitted Page)', 'elementor-contact-form-db').'</h3>';
222
+ echo '<p>'.__('Please review the data below and press "Download CSV File" to start the download. This list will show up to 50 submissions. The export will show the full list.', 'elementor-contact-form-db').'</p>';
223
+ $rows_html = implode( '<br />', $rows );
224
+ echo '<div style="margin-top: 20px; min-height: 150px; max-height: 350px; overflow: scroll; margin-bottom: 10px; border: 1px solid #EEE; padding: 20px;">' . esc_attr($rows_html) . '</div>';
225
+
226
+ echo '<form method="POST">';
227
+ echo '<input type="hidden" name="form_name" value="' . esc_attr($form_name) . '" />';
228
+ echo '<input type="submit" name="download_csv" class="button-primary" value="Download CSV File" />';
229
+ echo '<input name="sb_elem_cfd_export" type="hidden" value="' . wp_create_nonce( 'sb_elem_cfd_export' ) . '" />';
230
+ echo '</form>';
231
+ } elseif(isset( $_REQUEST['form_id'] )) {
232
+
233
+ $form_id = sanitize_text_field($_REQUEST['form_id']);
234
+ $rows = sb_elem_cfd_get_export_rows_by_form_id( $form_id, 50 );
235
+
236
+ echo '<h3>'.__('CSV Content (by Form ID)', 'elementor-contact-form-db').'</h3>';
237
+ echo '<p>'.__('Please review the data below and press "Download CSV File" to start the download. This list will show up to 50 submissions. The export will show the full list.', 'elementor-contact-form-db').'</p>';
238
+ $rows_html = implode( '<br />', $rows );
239
+ echo '<div style="margin-top: 20px; min-height: 150px; max-height: 350px; overflow: scroll; margin-bottom: 10px; border: 1px solid #EEE; padding: 20px;">' . esc_attr($rows_html) . '</div>';
240
+
241
+ echo '<form method="POST">';
242
+ echo '<input type="hidden" name="form_id" value="' . esc_attr($form_id) . '" />';
243
+ echo '<input type="submit" name="download_csv" class="button-primary" value="Download CSV File" />';
244
+ echo '<input name="sb_elem_cfd_export" type="hidden" value="' . wp_create_nonce( 'sb_elem_cfd_export' ) . '" />';
245
+ echo '</form>';
246
+ }
247
+ } else {
248
+ echo '<p>'.__('This page will show a form when you have at least one submission. Until then, enjoy this picture of a cat!', 'elementor-contact-form-db').'</p>';
249
+ echo '<img src="'.plugin_dir_url( __FILE__ ).'cat.png" />';
250
+ }
251
+
252
+ echo sb_elem_cfd_box_end();
253
+
254
+ echo '</div>';
255
+
256
+ echo '</div>';
257
+ echo '</div>';
258
+ }
259
+
260
+ function sb_elem_cfd_settings_submenu_cb() {
261
+
262
+ $sb_item_name = SB_ELEM_CFD_DB_ITEM_NAME ? sanitize_text_field(SB_ELEM_CFD_DB_ITEM_NAME) : '';
263
+ $sb_version = SB_ELEM_CFD_DB_VERSION ? sanitize_text_field(SB_ELEM_CFD_DB_VERSION) : '';
264
+
265
+ echo '<div class="wrap"><div id="icon-tools" class="icon32"></div>';
266
+ echo '<h2>' . esc_attr($sb_item_name) . ' - Version ' . esc_attr($sb_version) . '</h2>';
267
+
268
+ echo '<div id="poststuff">';
269
+
270
+ echo '<div id="post-body" class="metabox-holder columns-2">';
271
+
272
+ if(isset( $_POST['sb_elem_cfd_save'] )) {
273
+ if(!empty( $_POST['sb_elem_cfd_save_settings'] )) {
274
+ if(wp_verify_nonce( $_POST['sb_elem_cfd_save_settings'], 'sb_elem_cfd_save_settings' )) {
275
+ $k_elem_cfd = isset($_POST['sb_elem_cfd']) ? sanitize_text_field($_POST['sb_elem_cfd']) : '';
276
+ update_option( 'sb_elem_cfd', $k_elem_cfd );
277
+ echo '<div id="message" class="updated fade"><p>'.__('Settings saved successfully', 'elementor-contact-form-db').'</p></div>';
278
+ }
279
+ }
280
+ }
281
+
282
+ $sb_elem_cfd = get_option( 'sb_elem_cfd' ) ? get_option( 'sb_elem_cfd' ) : '';
283
+
284
+ echo sb_elem_cfd_box_start( 'Settings' );
285
+
286
+ echo '<p>'.__('This simple form will provide some handy switches and settings for the plugin.', 'elementor-contact-form-db').'</p>';
287
+
288
+
289
+ echo '<form method="POST">';
290
+ echo '<table class="form-table widefat">';
291
+
292
+ echo '<tr>
293
+ <td>'.__('Disable Admin Nag?', 'elementor-contact-form-db').'</td>
294
+ <td>
295
+ <input type="checkbox" name="sb_elem_cfd[disable_admin_nag]" ' . checked( 1, (isset( $sb_elem_cfd['disable_admin_nag'] ) ? 1 : 0), false ) . ' value="1" />
296
+ </td>
297
+ <td>
298
+ <small>'.__('The admin nag is the red box that shows at the top of your admin pages when there is a contact submission to review. If you would prefer to use the plugin as a backup only then just check this box to turn the nag off..', 'elementor-contact-form-db').'</small>
299
+ </td>
300
+ </tr>';
301
+
302
+ ob_start();
303
+ wp_dropdown_roles( isset( $sb_elem_cfd['records_min_role'] ) ? $sb_elem_cfd['records_min_role'] : esc_html_e('administrator', 'elementor-contact-form-db') );
304
+ $role_options = ob_get_clean();
305
+
306
+ $select = '<select name="sb_elem_cfd[records_min_role]">' . esc_attr($role_options) . '</select>';
307
+
308
+ $title_plural = isset( $sb_elem_cfd['title_plural'] ) ? sanitize_text_field($sb_elem_cfd['title_plural']) : __('Elementor DB', 'elementor-contact-form-db') ;
309
+ $title_singular = isset( $sb_elem_cfd['title_singular'] ) ? sanitize_text_field($sb_elem_cfd['title_singular']) : __('Elementor DB', 'elementor-contact-form-db') ;
310
+
311
+ echo '<tr>
312
+ <td>'.__('Minimum role to view records', 'elementor-contact-form-db').'</td>
313
+ <td>' . esc_attr($select) . '</td>
314
+ <td><small>'.__('The minimum role needed to export the records. Normally administrator but some sites may use editor or other roles. Note that this settings page is only ever usable by administrators.', 'elementor-contact-form-db').'</small></td>
315
+ </tr>';
316
+
317
+ echo '<tr>
318
+ <td>Menu / Plural Label</td>
319
+ <td><input type="text" name="sb_elem_cfd[title_plural]" value="' . esc_attr($title_plural) . '" /></td>
320
+ <td><small>'.__('The name of the menu item to show. Good for white labelling for clients', 'elementor-contact-form-db').'</small></td>
321
+ </tr>';
322
+
323
+ echo '<tr>
324
+ <td>Secondary / Singular Label</td>
325
+ <td><input type="text" name="sb_elem_cfd[title_singular]" value="' . esc_attr($title_singular) . '" /></td>
326
+ <td><small>'.__('The secondary (singular) name of the post type to show. Good for white labelling for clients', 'elementor-contact-form-db').'</small></td>
327
+ </tr>';
328
+
329
+ echo '</table>';
330
+
331
+ echo '<p>';
332
+ echo '<input name="sb_elem_cfd_save_settings" type="hidden" value="' . wp_create_nonce( 'sb_elem_cfd_save_settings' ) . '" />';
333
+ echo '<input type="submit" name="sb_elem_cfd_save" class="button-primary" value="'.__("Save Settings", "elementor-contact-form-db").' />';
334
+ echo '</p>';
335
+
336
+ echo '</form>';
337
+
338
+ echo sb_elem_cfd_box_end();
339
+
340
+ echo '</div>';
341
+
342
+ echo '</div>';
343
+ echo '</div>';
344
+ }
345
+
346
+ function sb_elem_cfd_get_export_rows($submitted_id, $limit = - 1) {
347
+ $rows = array();
348
+ $args = 'post_type=elementor_cf_db&meta_key=sb_elem_cfd_submitted_on_id&posts_per_page=' . $limit . '&meta_value=' . $submitted_id;
349
+
350
+ if($posts = get_posts( $args )) {
351
+
352
+ $first_post = current( $posts );
353
+
354
+ $row = '';
355
+ $row .= esc_html_e('"Date","Submitted On","Form ID","Submitted By",', 'elementor-contact-form-db');
356
+
357
+ if($data = sb_elem_cfd_get_meta( $first_post->ID )) {
358
+ foreach($data['data'] as $field) {
359
+ $row .= '"' . esc_attr($field['label']) . '",';
360
+ }
361
+ }
362
+
363
+ $rows[] = rtrim( $row, ',' );
364
+
365
+ foreach($posts as $post) {
366
+ if($data = sb_elem_cfd_get_meta( $post->ID )) {
367
+ $row = '';
368
+
369
+ $form_id = get_post_meta( $post->ID, 'sb_elem_cfd_form_id', true ) ? get_post_meta( $post->ID, 'sb_elem_cfd_form_id', true ) : '';
370
+ $k_date = $post->post_date ? $post->post_date : '';
371
+ $k_submit_on = isset($data['extra']['submitted_on']) ? sanitize_text_field($data['extra']['submitted_on']) : '';
372
+ $k_submit_by = isset($data['extra']['submitted_by']) ? sanitize_text_field($data['extra']['submitted_by']) : '';
373
+ $row .= '"' . esc_attr($k_date) . '","' . esc_attr($k_submit_on) . '","' . esc_attr($form_id) . '","' . esc_attr($k_submit_by) . '",';
374
+
375
+ foreach($data['data'] as $field) {
376
+ $row .= '"' . addslashes( $field['value'] ) . '",';
377
+ }
378
+
379
+ $rows[] = rtrim( $row, ',' );
380
+ }
381
+ }
382
+ }
383
+
384
+ return $rows;
385
+ }
386
+
387
+ function sb_elem_cfd_get_meta($sub_id) {
388
+ global $wpdb;
389
+
390
+ $return = false;
391
+
392
+ $sql = 'SELECT meta_value
393
+ FROM ' . $wpdb->postmeta . '
394
+ WHERE
395
+ meta_key = "sb_elem_cfd"
396
+ AND post_id = ' . $sub_id;
397
+
398
+ if($meta = $wpdb->get_var( $sql )) {
399
+ $return = unserialize( $meta );
400
+ }
401
+
402
+ return $return;
403
+ }
404
+
405
+ function sb_elem_cfd_get_export_rows_by_form_id($form_id, $limit = - 1) {
406
+
407
+ $rows = array();
408
+
409
+ if($posts = get_posts( 'post_type=elementor_cf_db&posts_per_page=' . $limit . '&meta_key=sb_elem_cfd_form_id&meta_value=' . $form_id )) {
410
+ $row = '';
411
+ $row .= esc_html_e('"Date","Submitted On","Form ID","Submitted By",', 'elementor-contact-form-db');
412
+
413
+ //labels. loop once
414
+ $first_post = current( $posts );
415
+ $data = sb_elem_cfd_get_meta( $first_post->ID );
416
+
417
+ foreach($data['data'] as $field) {
418
+ $row .= '"' . esc_attr($field['label']) . '",';
419
+ }
420
+
421
+ $rows[] = rtrim( $row, ',' );
422
+
423
+ //fields
424
+ foreach($posts as $post) {
425
+ $data = sb_elem_cfd_get_meta( $post->ID );
426
+
427
+ $row = '';
428
+ $k_date = $post->post_date ? $post->post_date : '';
429
+ $k_submit_on = isset($data['extra']['submitted_on']) ? sanitize_text_field($data['extra']['submitted_on']) : '';
430
+ $k_submit_by = isset($data['extra']['submitted_by']) ? sanitize_text_field($data['extra']['submitted_by']) : '';
431
+ $row .= '"' . esc_attr($k_date) . '","' . esc_attr($k_submit_on) . '","' . esc_attr($form_id) . '","' . esc_attr($k_submit_by) . '",';
432
+
433
+ foreach($data['data'] as $field) {
434
+ $row .= '"' . addslashes( $field['value'] ) . '",';
435
+ }
436
+
437
+ $rows[] = rtrim( $row, ',' );
438
+ }
439
+ }
440
+
441
+ return $rows;
442
+ }
443
+
444
+ function sb_elem_cfd_css_enqueue() {
445
+ global $current_screen;
446
+
447
+ if($current_screen->id == 'elementor_cf_db') {
448
+ wp_enqueue_script( 'sb_elem_cfd_js', plugins_url( '/script.js', __FILE__ ) );
449
+ }
450
+ }
451
+
452
+ function sb_elem_cfd_columns_head($defaults) {
453
+ if($defaults['date']) unset( $defaults['date'] );
454
+ //unset($defaults['cb']);
455
+ if($defaults['title']) unset( $defaults['title'] );
456
+
457
+ $defaults['cf_elementor_title'] = __('View', 'elementor-contact-form-db');
458
+ $defaults['form_id'] = __('Form ID', 'elementor-contact-form-db');
459
+ $defaults['email'] = __('Email', 'elementor-contact-form-db');
460
+ $defaults['read'] = __('Read/Unread', 'elementor-contact-form-db');
461
+ $defaults['cloned'] = __('Cloned', 'elementor-contact-form-db');
462
+ $defaults['sub_on'] = __('Submitted On', 'elementor-contact-form-db');
463
+ $defaults['sub_date'] = __('Submission Date', 'elementor-contact-form-db');
464
+
465
+ return $defaults;
466
+ }
467
+
468
+ // SHOW THE FEATURED IMAGE
469
+ function sb_elem_cfd_columns_content($column_name, $post_id) {
470
+ $contact = get_post( $post_id );
471
+ $data = get_post_meta( $post_id, 'sb_elem_cfd', true ) ? get_post_meta( $post_id, 'sb_elem_cfd', true ) : '';
472
+
473
+ if($column_name == 'cf_elementor_title') {
474
+ echo '<a href="' . esc_url(admin_url( 'post.php?action=edit&post=' . $post_id )) . '">'.__('View Submission', 'elementor-contact-form-db').'</a>';
475
+ } elseif($column_name == 'read') {
476
+ if($read = get_post_meta( $post_id, 'sb_elem_cfd_read', true )) {
477
+ echo '<span style="color: green;">' . esc_attr($read['by_name']) . '<br />' . date( 'Y-m-d H:i', $read['on'] ) . '</span>';
478
+ } else {
479
+ echo '<span class="dashicons dashicons-email-alt"></span>';
480
+ }
481
+ } elseif($column_name == 'sub_on') {
482
+ if($data['extra']['submitted_on']) {
483
+ $k_submit_id = isset($data['extra']['submitted_on_id']) ? sanitize_text_field($data['extra']['submitted_on_id']) : '';
484
+ echo '<a href="' . esc_url(get_permalink( $k_submit_id )) . '">' . esc_attr($data['extra']['submitted_on']) . '</a>';
485
+ }
486
+ } elseif($column_name == 'sub_date') {
487
+ echo esc_attr($contact->post_date);
488
+ } elseif($column_name == 'cloned') {
489
+ if($cloned = get_post_meta( $post_id, 'sb_elem_cfd_cloned', true )) {
490
+ $cloned_count = count( $cloned );
491
+
492
+ echo '<span class="dashicons dashicons-yes"></span> (' . esc_attr($cloned_count) . ')';
493
+ } else {
494
+ echo '<span class="dashicons dashicons-no-alt"></span>';
495
+ }
496
+ } elseif($column_name == 'email') {
497
+ if($email = get_post_meta( $post_id, 'sb_elem_cfd_email', true )) {
498
+ $email = '<a href="mailto:' . esc_attr($email) . '" target="_blank">' . esc_attr($email) . '</a>';
499
+ } else {
500
+ $email = '-';
501
+ }
502
+ echo esc_attr($email);
503
+ } elseif($column_name == 'form_id') {
504
+ if(!$form_id = get_post_meta( $post_id, 'sb_elem_cfd_form_id', true )) {
505
+ $form_id = '-';
506
+ }
507
+
508
+ echo esc_attr($form_id);
509
+ }
510
+ }
511
+
512
+ function sb_elem_cfd_admin_head() {
513
+ global $current_user;
514
+
515
+ // Hide link on listing page
516
+ if((isset( $_GET['post_type'] ) && $_GET['post_type'] == 'elementor_cf_db') || (isset( $_GET['post'] ) && get_post_type( $_GET['post'] ) == 'elementor_cf_db')) {
517
+ echo '<style type="text/css">
518
+ .page-title-action, #favorite-actions, .add-new-h2 { display:none; }
519
+ </style>';
520
+ }
521
+
522
+ if(isset( $_GET['sb-action'] )) {
523
+ $action = sanitize_text_field($_GET['sb-action']);
524
+
525
+ if($action == 'mark-all-read') {
526
+ $args = array(
527
+ 'posts_per_page' => - 1,
528
+ 'meta_key' => 'sb_elem_cfd_read',
529
+ 'meta_value' => 0,
530
+ 'post_type' => 'elementor_cf_db',
531
+ 'post_status' => 'publish',
532
+ );
533
+
534
+ if($other_contacts = get_posts( $args )) {
535
+ foreach($other_contacts as $other_contact) {
536
+ $read = array(
537
+ 'by_name' => $current_user->display_name,
538
+ 'by' => $current_user->ID,
539
+ 'on' => time()
540
+ );
541
+ update_post_meta( $other_contact->ID, 'sb_elem_cfd_read', $read );
542
+ }
543
+ }
544
+ }
545
+ }
546
+ }
547
+
548
+ function sb_elem_cfd_admin_notice() {
549
+ if(!current_user_can( 'administrator' )) {
550
+ return;
551
+ }
552
+
553
+ $sb_elem_cfd = get_option( 'sb_elem_cfd' ) ? get_option( 'sb_elem_cfd' ) : '';
554
+
555
+ if(isset( $sb_elem_cfd['disable_admin_nag'] ) && $sb_elem_cfd['disable_admin_nag']) {
556
+ return;
557
+ }
558
+
559
+ $args = array(
560
+ 'posts_per_page' => - 1,
561
+ 'meta_key' => 'sb_elem_cfd_read',
562
+ 'meta_value' => 0,
563
+ 'post_type' => 'elementor_cf_db',
564
+ 'post_status' => 'publish',
565
+ );
566
+
567
+ if($other_contacts = get_posts( $args )) {
568
+ //Use notice-warning for a yellow/orange, and notice-info for a blue left border.
569
+ $class = 'notice notice-error is-dismissible';
570
+ $message = __( 'You have ' . count( $other_contacts ) . ' unread contact form submissions. Click <a href="' . esc_url(admin_url( 'edit.php?post_type=elementor_cf_db' )) . '">here</a> to visit them or click <a href="' . esc_url(admin_url( 'edit.php?post_type=elementor_cf_db&sb-action=mark-all-read' )) . '">here</a> to mark all as read', 'elementor-contact-form-db' );
571
+
572
+ printf( '<div class="%1$s"><p>%2$s</p></div>', $class, $message );
573
+ }
574
+ }
575
+
576
+ function sb_elem_cfd_register_meta_box() {
577
+ add_meta_box( 'sb_elem_cfd', esc_html__( 'Form Submission', 'elementor-contact-form-db' ), 'sb_elem_cfd_meta_box_callback', 'elementor_cf_db', 'normal', 'high' );
578
+ add_meta_box( 'sb_elem_cfd_extra', esc_html__( 'Extra Information', 'elementor-contact-form-db' ), 'sb_elem_cfd_meta_box_callback_extra', 'elementor_cf_db', 'normal', 'high' );
579
+ add_meta_box( 'sb_elem_cfd_actions', esc_html__( 'Actions', 'elementor-contact-form-db' ), 'sb_elem_cfd_meta_box_callback_actions', 'elementor_cf_db', 'normal', 'high' );
580
+ }
581
+
582
+ function sb_elem_cfd_meta_box_callback() {
583
+ global $current_user;
584
+
585
+ $submission = get_post( get_the_ID() );
586
+
587
+ if(!$read = get_post_meta( get_the_ID(), 'sb_elem_cfd_read', true )) {
588
+ $read = array('by_name' => $current_user->display_name, 'by' => $current_user->ID, 'on' => time());
589
+ update_post_meta( get_the_ID(), 'sb_elem_cfd_read', $read );
590
+ }
591
+
592
+ $class = 'notice notice-info';
593
+ $message = 'First read by ' . esc_attr($read['by_name']) . ' at ' . date( 'Y-m-d H:i', $read['on'] );
594
+ printf( '<div class="%1$s"><p>%2$s</p></div>', $class, $message );
595
+
596
+ if($data = get_post_meta( get_the_ID(), 'sb_elem_cfd', true )) {
597
+
598
+ if($fields = $data['data']) {
599
+ echo '<table class="widefat">
600
+ <thead>
601
+ <tr>
602
+ <th>'.__('Label', 'elementor-contact-form-db').'</th>
603
+ <th>'.__('Value', 'elementor-contact-form-db').'</th>
604
+ </tr>
605
+ </thead>
606
+ <tbody>';
607
+
608
+ foreach($fields as $field) {
609
+ $value = $field['value'] ? $field['value'] : '';
610
+
611
+ if(is_email( $value )) {
612
+ $value = '<a href="mailto:' . esc_attr($value) . '" target="_blank">' . esc_attr($value) . '</a>';
613
+ }
614
+
615
+ echo '<tr>
616
+ <td><strong>' . esc_attr($field['label']) . '</strong></td>
617
+ <td>' . wpautop( esc_attr( $value ) ) . '</td>
618
+ </tr>';
619
+ }
620
+
621
+ echo '<tr>
622
+ <td><strong>Date of Submission</strong></td>
623
+ <td>' . esc_attr($submission->post_date) . '</td>
624
+ </tr>';
625
+
626
+ echo '</tbody>
627
+ </table>';
628
+ }
629
+ }
630
+
631
+ }
632
+
633
+ function sb_elem_cfd_meta_box_callback_extra() {
634
+ $other_submissions = '';
635
+
636
+ if($data = get_post_meta( get_the_ID(), 'sb_elem_cfd', true )) {
637
+ if($extra = $data['extra']) {
638
+ echo '<table class="widefat">
639
+ <thead>
640
+ <tr>
641
+ <th>'.__('Label', 'elementor-contact-form-db').'</th>
642
+ <th>'.__('Value', 'elementor-contact-form-db').'</th>
643
+ </tr>
644
+ </thead>
645
+ <tbody>';
646
+
647
+ foreach($extra as $key => $value) {
648
+
649
+ switch($key) {
650
+ case 'submitted_on_id':
651
+ case 'submitted_by_id':
652
+ continue(2); //we don't really care about these ones
653
+ break;
654
+ case 'submitted_on':
655
+ if($extra['submitted_on_id']) {
656
+ $value = $value . ' (<a href="' . esc_url(get_permalink( $extra['submitted_on_id'] )) . '" target="_blank">View Page</a> | <a href="' . esc_url(admin_url( 'post.php?action=edit&post=' . $extra['submitted_on_id'] )) . '" target="_blank">'.__('Edit Page', 'elementor-contact-form-db').'</a>)';
657
+ } else {
658
+ $value = '<em>'.__('Unknown', 'elementor-contact-form-db').'</em>';
659
+ }
660
+ break;
661
+ case 'submitted_by':
662
+ if($extra['submitted_by_id']) {
663
+ $value = $value . ' (<a href="' . esc_url(admin_url( 'user-edit.php?user_id=' . $extra['submitted_by_id'] )) . '" target="_blank">'.__('View User Profiile', 'elementor-contact-form-db').'</a>';
664
+
665
+ $args = array(
666
+ 'posts_per_page' => - 1,
667
+ 'meta_key' => 'sb_elem_cfd_submitted_by',
668
+ 'meta_value' => $extra['submitted_by_id'],
669
+ 'post_type' => 'elementor_cf_db',
670
+ 'post_status' => 'publish',
671
+ );
672
+
673
+ if($other_contacts = get_posts( $args )) {
674
+ $value .= ' | <a style="cursor: pointer;" onclick="jQuery(\'.other_submissions\').slideToggle();">View ' . esc_attr(count( $other_contacts )) . ' more submissions by this user</a>';
675
+ $other_submissions .= '<div style="display: none;" class="other_submissions">
676
+ <h3>'.__('Other submissions made by the same person', 'elementor-contact-form-db').'</h3>';
677
+ $other_submissions .= '<table class="widefat">';
678
+
679
+ foreach($other_contacts as $other_contact) {
680
+ $other_submissions .= '<tr><td><a href="' . esc_url(admin_url( 'post.php?action=edit&post=' . $other_contact->ID )) . '">' . $other_contact->post_title . '</a></td></tr>';
681
+ }
682
+
683
+ $other_submissions .= '</table></div>';
684
+ }
685
+
686
+ $value .= ')';
687
+ } else {
688
+ $value = '<em>'.__('Not a registered user', 'elementor-contact-form-db').'</em>';
689
+ }
690
+
691
+ break;
692
+ }
693
+
694
+ $key_label = ucwords( str_replace( '_', ' ', $key ) );
695
+
696
+ echo '<tr>
697
+ <td><strong>' . esc_attr($key_label) . '</strong></td>
698
+ <td>' . esc_attr($value) . '</td>
699
+ </tr>';
700
+ }
701
+
702
+ echo '</tbody>
703
+ </table>';
704
+
705
+ echo esc_attr($other_submissions);
706
+ }
707
+
708
+ }
709
+
710
+ }
711
+
712
+ function sb_elem_cfd_meta_box_callback_actions() {
713
+ $submission = get_post( get_the_ID() );
714
+ $data = get_post_meta( get_the_ID(), 'sb_elem_cfd', true ) ? get_post_meta( get_the_ID(), 'sb_elem_cfd', true ) : '';
715
+
716
+ $w_post = isset($_GET['post']) ? sanitize_text_field($_GET['post']) : '';
717
+ if(isset( $_POST['sb_elem_cfd_map_to'] )) {
718
+ $map_to = sanitize_text_field($_POST['sb_elem_cfd_map_to']);
719
+ $map_to_other = isset($_POST['sb_elem_cfd_map_to_other']) ? sanitize_text_field($_POST['sb_elem_cfd_map_to_other']) : '';
720
+
721
+ if($fields = $data['data']) {
722
+ $mapped_fields = array();
723
+ $custom_fields = array();
724
+
725
+ foreach($fields as $field) {
726
+ $mapped_fields[$field['label']] = isset($field['value']) ? sanitize_text_field($field['value']) : '';
727
+ }
728
+
729
+ $k_pt = isset($_POST['sb_elem_cfd_pt']) ? sanitize_text_field($_POST['sb_elem_cfd_pt']) : '';
730
+
731
+ $db_ins = array(
732
+ 'post_title' => esc_html_e('Cloned from contact form', 'elementor-contact-form-db'),
733
+ 'post_content' => esc_html_e('Cloned from contact form', 'elementor-contact-form-db'),
734
+ 'post_status' => 'draft',
735
+ 'post_type' => $k_pt,
736
+ );
737
+
738
+ if(isset( $_POST['sb_elem_cfd_date'] )) {
739
+ $db_ins['post_date'] = sanitize_text_field($_POST['sb_elem_cfd_date']);
740
+ }
741
+
742
+ $found = 0;
743
+
744
+ foreach($map_to as $key => $field) {
745
+ if($field) {
746
+ $found ++;
747
+
748
+ if($field == 'custom_field') {
749
+ if($map_to_other[$key]) {
750
+ $custom_fields[$map_to_other[$key]] = $mapped_fields[$key];
751
+ }
752
+ } else {
753
+ $db_ins[$field] = $mapped_fields[$key];
754
+ }
755
+ }
756
+ }
757
+
758
+ if($found) {
759
+ // Insert the post into the database
760
+ if($post_id = wp_insert_post( $db_ins )) {
761
+ if(!is_wp_error( $post_id )) {
762
+ foreach($custom_fields as $key => $value) {
763
+ update_post_meta( $post_id, $key, $value );
764
+ }
765
+
766
+ echo '<div id="message" class="updated fade">
767
+ <p>'.__('Successfully copied the content of this contact form submission to another post type. Click here to', 'elementor-contact-form-db').' <a href="' . esc_url(get_permalink( $post_id )) . '">View</a> or <a href="' . esc_url(admin_url( 'post.php?action=edit&post=' . $post_id )) . '">'.__('Edit', 'elementor-contact-form-db').'</a></p>
768
+ </div>';
769
+
770
+ if(!$cloned = get_post_meta( $w_post, 'sb_elem_cfd_cloned', true )) {
771
+ $cloned = array();
772
+ }
773
+
774
+ $cloned[$post_id] = time();
775
+
776
+ update_post_meta( $w_post, 'sb_elem_cfd_cloned', $cloned );
777
+
778
+ } else {
779
+ echo '<div id="message" class="error fade">
780
+ <p>'.__('Oops something went wrong. This error message may be helpful:', 'elementor-contact-form-db').' ' . print_r( $post_id, true ) . '</p>
781
+ </div>';
782
+ }
783
+ }
784
+ } else {
785
+ echo '<div id="message" class="error fade">
786
+ <p>'.__('You need to choose at least one field to map against for the clone to work.', 'elementor-contact-form-db').'</p>
787
+ </div>';
788
+ }
789
+ }
790
+ }
791
+
792
+ $map_to_options = array();
793
+ $maps = array(
794
+ 'post_title' => esc_html_e('Title', 'elementor-contact-form-db'),
795
+ 'post_content' => esc_html_e('Content', 'elementor-contact-form-db'),
796
+ 'custom_field' => 'Custom Field'
797
+ );
798
+
799
+ foreach($maps as $key => $value) {
800
+ $map_to_options[] = '<option value="' . esc_attr($key) . '">' . esc_attr($value) . '</option>';
801
+ }
802
+
803
+ $types = get_post_types();
804
+ $type_options = array();
805
+
806
+ foreach($types as $type2) {
807
+ $type_obj2 = get_post_type_object( $type2 );
808
+
809
+ if(!$type_obj2->public) {
810
+ continue;
811
+ }
812
+
813
+ $type_options[] = '<option value="' . esc_attr($type2) . '">' . esc_attr($type_obj2->labels->name) . '</option>';
814
+ }
815
+
816
+ echo '<p>';
817
+
818
+ if($email = get_post_meta( get_the_ID(), 'sb_elem_cfd_email', true )) {
819
+ echo '<a style="margin-right: 10px;" class="button-primary" target="_blank" href="mailto:' . esc_attr($email) . '">'.__('Reply via Email', 'elementor-contact-form-db').'</a>';
820
+ }
821
+
822
+ echo '<a onclick="jQuery(\'.sb_elem_cfd_convert\').slideToggle();" class="button-secondary">'.__('Copy to another Post Type', 'elementor-contact-form-db').'</a>';
823
+
824
+ echo '</p>';
825
+
826
+ ///////////////////////////////////
827
+
828
+ echo '<div style="display: none; overflow: scroll;" class="sb_elem_cfd_convert">';
829
+
830
+ echo '<h3>'.__('Copy to another post type', 'elementor-contact-form-db').'</h3>';
831
+
832
+ $type_options_ht = implode( '', $type_options );
833
+
834
+ echo '<p><label>'.__('Select Post Type: ', 'elementor-contact-form-db').'<select name="sb_elem_cfd_pt">' . esc_attr($type_options_ht) . '</select></label></p>';
835
+ echo '<p>'.__('Select Field Mappings:', 'elementor-contact-form-db').'</p>';
836
+
837
+ echo '<table class="widefat">';
838
+
839
+ foreach($data['fields_original']['form_fields'] as $field) {
840
+ $map_to_options_ht = implode( '', $map_to_options );
841
+ echo '<tr>
842
+ <td>' . esc_attr($field['field_label']) . '</td>
843
+ <td>
844
+ <select name="sb_elem_cfd_map_to[' . esc_attr($field['field_label']) . ']"><option value="">-- Unused --</option>' . esc_attr($map_to_options_ht) . '</select>
845
+ <span style="margin-left: 20px; display: inline-block;">(If "Custom Field" selected, enter field name: <input type="text" name="sb_elem_cfd_map_to_other[' . esc_attr($field['field_label']) . ']" />)</span>
846
+ </td>
847
+ </tr>';
848
+ }
849
+
850
+ echo '</table>';
851
+
852
+ echo '<p><label><input type="checkbox" name="sb_elem_cfd_date" value="' . esc_attr($submission->post_date) . '" />&nbsp;Keep date of original submission? (' . esc_attr($submission->post_date) . ')</label></p>';
853
+ echo '<p><input type="submit" class="button-primary sb_elem_cfd_copy" value="Copy" /></p>';
854
+
855
+ echo '</div>';
856
+
857
+ if($cloned = get_post_meta( $w_post, 'sb_elem_cfd_cloned', true )) {
858
+ echo '<h3>'.__('Clone History', 'elementor-contact-form-db').'</h3>';
859
+
860
+ echo '<table class="widefat">
861
+ <thead>
862
+ <tr>
863
+ <th>'.__('New Post Title', 'elementor-contact-form-db').'</th>
864
+ <th>'.__('Post Type', 'elementor-contact-form-db').'</th>
865
+ <th>'.__('Date Cloned', 'elementor-contact-form-db').'</th>
866
+ <th>'.__('Actions', 'elementor-contact-form-db').'</th>
867
+ </tr>
868
+ </thead>';
869
+
870
+ foreach($cloned as $cloned_id => $date) {
871
+ if($cloned_post = get_post( $cloned_id )) {
872
+ $type_obj = get_post_type_object( $cloned_post->post_type );
873
+ $type_name = $type_obj->labels->name ? $type_obj->labels->name : '';
874
+
875
+ echo '<tr>
876
+ <td>' . esc_attr($cloned_post->post_title) . '</td>
877
+ <td>' . esc_attr($type_name) . '</td>
878
+ <td>' . date( 'Y-m-d H:i', $date ) . '</td>
879
+ <td><a href="' . esc_url(get_permalink( $cloned_id )) . '">View</a> | <a href="' . esc_url(admin_url( 'post.php?action=edit&post=' . $post_id )) . '">Edit</a></td>
880
+ </tr>';
881
+ }
882
+ }
883
+
884
+ echo '</table>';
885
+
886
+ }
887
+ }
888
+
889
+ function sb_elem_cfd_meta_box_callback_debug() {
890
+
891
+ if($data = get_post_meta( get_the_ID(), 'sb_elem_cfd', true )) {
892
+ echo '<div style="display: none; overflow: scroll;" class="sb_elem_cfd_debug">';
893
+
894
+ echo '<pre>';
895
+ print_r( esc_attr($data) );
896
+ echo '</pre>';
897
+
898
+ echo '</div>';
899
+
900
+ echo '<p><a onclick="jQuery(\'.sb_elem_cfd_debug\').slideToggle();" class="button-secondary">'.__('Reveal Debug/Server Information', 'elementor-contact-form-db').'</a></p>';
901
+ }
902
+
903
+ }
904
+
905
+ function sb_elem_cfd_pt_init() {
906
+ $sb_elem_cfd = get_option( 'sb_elem_cfd' ) ? get_option( 'sb_elem_cfd' ) : '';
907
+ $title_singular = (isset( $sb_elem_cfd['title_singular'] ) ? $sb_elem_cfd['title_singular'] : _x( 'Elementor DB', 'post type singular name', 'elementor-contact-form-db' ));
908
+ $title_plural = isset( $sb_elem_cfd['title_plural'] ) ? $sb_elem_cfd['title_plural'] : $title_singular;
909
+
910
+ $labels = array(
911
+ 'name' => $title_plural,
912
+ 'singular_name' => $title_singular,
913
+ 'menu_name' => $title_plural,
914
+ 'name_admin_bar' => $title_plural,
915
+ 'add_new' => _x( 'Add New', 'Elementor DB', 'elementor-contact-form-db' ),
916
+ 'add_new_item' => __( 'Add New', 'elementor-contact-form-db' ),
917
+ 'new_item' => __( 'New', 'elementor-contact-form-db' ) . ' ' . $title_singular,
918
+ 'edit_item' => __( 'Edit', 'elementor-contact-form-db' ) . ' ' . $title_singular,
919
+ 'view_item' => __( 'View', 'elementor-contact-form-db' ) . ' ' . $title_singular,
920
+ 'all_items' => __( 'All', 'elementor-contact-form-db' ) . ' ' . $title_singular,
921
+ 'search_items' => __( 'Search', 'elementor-contact-form-db' ) . ' ' . $title_singular,
922
+ 'parent_item_colon' => __( 'Parent:', 'elementor-contact-form-db' ) . ' ' . $title_singular,
923
+ 'not_found' => __( 'No contact form submissions found.', 'elementor-contact-form-db' ),
924
+ 'not_found_in_trash' => __( 'No contact form submissions found in Trash.', 'elementor-contact-form-db' )
925
+ );
926
+
927
+ $args = array(
928
+ 'labels' => $labels,
929
+ 'description' => __( 'For storing Elementor contact form submissions.', 'elementor-contact-form-db' ),
930
+ 'public' => false,
931
+ 'publicly_queryable' => false,
932
+ 'show_ui' => true,
933
+ 'show_in_menu' => true,
934
+ 'query_var' => true,
935
+ 'rewrite' => false,
936
+ 'capability_type' => 'post',
937
+ 'has_archive' => false,
938
+ 'hierarchical' => false,
939
+ 'menu_position' => null,
940
+ 'menu_icon' => 'dashicons-admin-comments',
941
+ 'supports' => array('title')
942
+ );
943
+
944
+ register_post_type( 'elementor_cf_db', $args );
945
+ }
946
+
947
+ function sb_elem_cfd_new_record($record, $form_class) {
948
+
949
+ if($fields = $record->get_formatted_data()) {
950
+ $data = array();
951
+ $email = false;
952
+
953
+ foreach($fields as $label => $value) {
954
+
955
+ if(stripos( $label, 'email' ) !== false) {
956
+ $email = $value;
957
+ }
958
+
959
+ $data[] = array('label' => $label, 'value' => sanitize_text_field( $value ));
960
+ }
961
+
962
+ $this_pageid = isset($_POST['post_id']) ? sanitize_text_field($_POST['post_id']) : '';
963
+ $this_page = get_post( $this_pageid );
964
+ $this_user = false;
965
+ $current_user = get_current_user_id();
966
+
967
+ if($this_user_id = ($current_user ? $current_user : 0)) {
968
+ if($this_user = get_userdata( $this_user_id )) {
969
+ $this_user = $this_user->display_name;
970
+ }
971
+ }
972
+
973
+ $extra = array(
974
+ 'submitted_on' => $this_page->post_title,
975
+ 'submitted_on_id' => $this_page->ID,
976
+ 'submitted_by' => $this_user,
977
+ 'submitted_by_id' => $this_user_id
978
+ );
979
+
980
+ $db_ins = array(
981
+ 'post_title' => $record->get_form_settings( 'form_name' ) . ' - ' . date( 'Y-m-d H:i:s' ),
982
+ 'post_status' => 'publish',
983
+ 'post_type' => 'elementor_cf_db',
984
+ );
985
+
986
+ // Insert the post into the database
987
+ if($post_id = wp_insert_post( $db_ins )) {
988
+ update_post_meta( $post_id, 'sb_elem_cfd', array(
989
+ 'data' => $data,
990
+ 'extra' => $extra,
991
+ 'fields_original' => array('form_fields' => $record->get_form_settings( 'form_fields' )),
992
+ 'record_original' => $record,
993
+ ) );
994
+
995
+ if($this_user_id) {
996
+ update_post_meta( $post_id, 'sb_elem_cfd_submitted_by', $this_user_id );
997
+ }
998
+
999
+ update_post_meta( $post_id, 'sb_elem_cfd_read', 0 );
1000
+ update_post_meta( $post_id, 'sb_elem_cfd_email', $email );
1001
+ update_post_meta( $post_id, 'sb_elem_cfd_form_id', $record->get_form_settings( 'form_name' ) );
1002
+ update_post_meta( $post_id, 'sb_elem_cfd_submitted_on_id', $this_page->ID );
1003
+
1004
+ }
1005
+ }
1006
+ }
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
screenshot-3.png ADDED
Binary file
screenshot-4.png ADDED
Binary file
screenshot-5.png ADDED
Binary file
screenshot-6.png ADDED
Binary file
script.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($) {
2
+
3
+ var sb_elementor_cfd_div = jQuery('#poststuff').detach();
4
+
5
+ sb_elementor_cfd_div.insertAfter('form#post');
6
+
7
+ jQuery('form#post').remove();
8
+
9
+ jQuery( ".sb_elem_cfd_convert" ).wrap( '<form class="sb_elem_cfd_copy_form" method="POST"></form>' );
10
+ });