PluginProbe
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification / 3.1.0
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification v3.1.0
5.12.0 5.13.0 5.13.1 5.11.0 5.10.0 5.9.0 5.8.0 5.8.1 5.7.0 5.6.2 5.6.3 5.6.1 5.6.0 5.5.0 5.4.0 5.3.2 5.3.1 5.1.6 5.1.5 trunk 2.1.5 2.11 2.12 2.13 2.15 All 47 releases
double-opt-in / ui / UICategories.class.php

UICategories.class.php in Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification 3.1.0, at ui/UICategories.class.php

362 lines 12.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace forge12\contactform7\CF7DoubleOptIn {
4
5 use Forge12\Shared\LoggerInterface;
6
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit;
9 }
10
11 /**
12 * Class UICategories
13 *
14 * @package forge12\contactform7\CF7DoubleOptIn
15 */
16 class UICategories extends UIPageForm {
17 /**
18 * Constructor for the class.
19 *
20 * @param TemplateHandler $templateHandler The template handler object.
21 * @param string $domain The domain.
22 *
23 * @return void
24 */
25 public function __construct(LoggerInterface $logger, TemplateHandler $templateHandler, string $domain ) {
26 parent::__construct($logger, $templateHandler, $domain, 'categories', __( 'Categories', 'double-opt-in' ) );
27
28 $this->hideSubmitButton( true );
29 $this->get_logger()->debug( 'Submit button is hidden for this page.', [
30 'plugin' => $domain,
31 ] );
32
33 // Check for status messages in the URL
34 if ( isset( $_GET['status'] ) ) {
35 $status = sanitize_text_field( $_GET['status'] );
36
37 $this->get_logger()->info( 'URL status parameter found: ' . $status, [
38 'plugin' => $domain,
39 ] );
40
41 switch ( $status ) {
42 case 'category-deleted':
43 Messages::getInstance()->add( __( 'Category deleted', 'double-opt-in' ), 'success' );
44 $this->get_logger()->notice( 'Added "Category deleted" success message.', [
45 'plugin' => $domain,
46 ] );
47 break;
48 case 'category-not-deleted':
49 Messages::getInstance()->add( __( 'Category not-deleted', 'double-opt-in' ), 'error' );
50 $this->get_logger()->error( 'Added "Category not-deleted" error message.', [
51 'plugin' => $domain,
52 ] );
53 break;
54 default:
55 $this->get_logger()->warning( 'Unknown status parameter value: ' . $status, [
56 'plugin' => $domain,
57 ] );
58 break;
59 }
60 }
61 }
62
63 /**
64 * Check if the category should be deleted
65 */
66 private function maybeDelete() {
67 $this->get_logger()->info( 'Attempting to delete a category based on URL parameters.', [
68 'plugin' => $this->domain,
69 ] );
70
71 // Check for required parameters
72 if ( ! isset( $_GET['id'], $_GET['nonce'], $_GET['option'] ) ) {
73 $this->get_logger()->warning( 'Missing required URL parameters (id, nonce, or option). Aborting delete attempt.', [
74 'plugin' => $this->domain,
75 ] );
76 return;
77 }
78
79 $option = sanitize_text_field( $_GET['option'] );
80 $id = (int) $_GET['id'];
81 $nonce = sanitize_text_field( $_GET['nonce'] );
82
83 $this->get_logger()->debug( 'Parameters received: ' . json_encode( ['option' => $option, 'id' => $id] ), [
84 'plugin' => $this->domain,
85 ] );
86
87 if ( 'delete' !== $option ) {
88 $this->get_logger()->warning( 'Option parameter is not "delete". Aborting.', [
89 'plugin' => $this->domain,
90 'option_value' => $option,
91 ] );
92 return;
93 }
94
95 $page = (int) ($_GET['pageNum'] ?? 1); // Use a default page number if not set
96
97 // Nonce verification
98 if ( ! wp_verify_nonce( $nonce, 'doi-delete-category-' . $id ) ) {
99 $this->get_logger()->error( 'Nonce verification failed for category deletion.', [
100 'plugin' => $this->domain,
101 'category_id' => $id,
102 'provided_nonce' => $nonce,
103 ] );
104 wp_redirect( admin_url( 'admin.php' ) . '?page=f12-cf7-doubleoptin_categories&pageNum=' . esc_attr( $page ) . '&status=category-not-deleted' );
105 wp_die();
106 }
107
108 $this->get_logger()->notice( 'Nonce verification successful. Attempting to delete category with ID: ' . $id, [
109 'plugin' => $this->domain,
110 'category_id' => $id,
111 ] );
112
113 // Attempt to delete the category
114 if ( Category::delete_by_id( $id ) ) {
115 $this->get_logger()->info( 'Category deleted successfully. Redirecting.', [
116 'plugin' => $this->domain,
117 'category_id' => $id,
118 ] );
119 wp_redirect( admin_url( 'admin.php' ) . '?page=f12-cf7-doubleoptin_categories&pageNum=' . esc_attr( $page ) . '&status=category-deleted' );
120 } else {
121 $this->get_logger()->error( 'Failed to delete category.', [
122 'plugin' => $this->domain,
123 'category_id' => $id,
124 ] );
125 wp_redirect( admin_url( 'admin.php' ) . '?page=f12-cf7-doubleoptin_categories&pageNum=' . esc_attr( $page ) . '&status=category-not-deleted' );
126 }
127
128 // Terminate script execution after redirect
129 wp_die();
130 }
131
132 /**
133 * Render the license subpage content
134 */
135 protected function theContent( $slug, $page, $settings ) {
136 $this->get_logger()->info( 'Rendering the main content for the "Categories" UI page.', [
137 'plugin' => $this->domain,
138 'page_slug' => $page,
139 ] );
140
141 // Check for and handle a category deletion request
142 $this->maybeDelete();
143
144 ?>
145 <h2>
146 <?php _e( 'Categories', 'double-opt-in' ); ?>
147 </h2>
148
149 <?php
150 $atts = array(
151 'perPage' => 10,
152 'page' => 1,
153 'order' => 'DESC'
154 );
155
156 // Get the current page number from the URL
157 if ( isset( $_GET['pageNum'] ) ) {
158 $atts['page'] = (int) $_GET['pageNum'];
159 $this->get_logger()->debug( 'Page number set from URL: ' . $atts['page'], [
160 'plugin' => $this->domain,
161 ] );
162 }
163
164 $numberOfPages = 0;
165 $this->get_logger()->info( 'Fetching a list of categories from the database.', [
166 'plugin' => $this->domain,
167 'query_atts' => $atts,
168 ] );
169 $listOfCategories = Category::get_list( $atts, $numberOfPages );
170
171 $this->get_logger()->notice( 'Found ' . count($listOfCategories) . ' categories across ' . $numberOfPages . ' pages.', [
172 'plugin' => $this->domain,
173 ] );
174 ?>
175
176 <table>
177 <tr>
178 <th>
179 <?php _e( 'ID', 'double-opt-in' ); ?>
180 </th>
181 <th>
182 <?php _e( 'Name', 'double-opt-in' ); ?>
183 </th>
184 <th>
185 <?php _e( 'Registration Date', 'double-opt-in' ); ?>
186 </th>
187 <th>
188 <?php _e( 'Update Date', 'double-opt-in' ); ?>
189 </th>
190 <th></th>
191 </tr>
192 <?php foreach ( $listOfCategories as $Category /** @var Category $Category */ ) : ?>
193 <?php
194 $this->get_logger()->debug( 'Rendering row for category ID: ' . $Category->get_id(), [
195 'plugin' => $this->domain,
196 ] );
197 ?>
198 <tr>
199 <td>
200 <div>
201 <?php echo esc_html( $Category->get_id() ); ?>
202 </div>
203 </td>
204 <td>
205 <a href="<?php echo admin_url( 'admin.php' ); ?>?page=f12-cf7-doubleoptin_categories_view&id=<?php esc_attr_e( $Category->get_id() ); ?>"
206 title="<?php _e( 'Show details', 'double-opt-in' ); ?>"><?php echo esc_attr( $Category->get_name() ); ?></a>
207 </td>
208 <td>
209 <?php
210 echo esc_html( $Category->get_createtime( 'formatted' ) );
211 ?>
212 </td>
213 <td>
214 <?php
215 echo esc_html( $Category->get_updatetime( 'formatted' ) );
216 ?>
217 </td>
218 <td>
219 <a href="<?php echo esc_url( admin_url( 'admin.php' ) ); ?>?page=<?php esc_attr_e( $slug . '_' . $page ); ?>&pageNum=<?php esc_attr_e( $atts['page'] ); ?>&option=delete&id=<?php esc_attr_e( $Category->get_id() ); ?>&nonce=<?php echo wp_create_nonce( 'doi-delete-category-' . $Category->get_id() ); ?>">
220 <?php _e( 'Delete', 'double-opt-in' ); ?>
221 </a>
222 </td>
223 </tr>
224 <?php endforeach; ?>
225 </table>
226
227 <div class="tablenav-pages">
228 <?php
229 $this->get_logger()->info( 'Rendering pagination links.', [
230 'plugin' => $this->domain,
231 'number_of_pages' => $numberOfPages,
232 'current_page' => $atts['page'],
233 ] );
234 ?>
235 <?php for ( $i = 1; $i <= $numberOfPages; $i ++ ): ?>
236 <a href="<?php echo esc_url( admin_url( 'admin.php' ) ); ?>?page=<?php echo esc_attr( $slug . '_' . $page ); ?>&pageNum=<?php echo esc_attr( $i ); ?>"
237 class="button <?php echo ( $atts['page'] ) == $i ? 'active' : ''; ?>">
238 <?php echo esc_html( $i ); ?>
239 </a>
240 <?php endfor; ?>
241 </div>
242 <?php
243 $this->get_logger()->notice( 'Finished rendering the "Categories" page content.', [
244 'plugin' => $this->domain,
245 ] );
246 }
247
248 protected function theSidebar( $slug, $page ) {
249 $this->get_logger()->info( 'Rendering the sidebar content for the "Categories" UI page.', [
250 'plugin' => $this->domain,
251 'page_slug' => $page,
252 ] );
253 ?>
254 <div class="box">
255 <h2>
256 <?php _e( 'New Category:', 'double-opt-in' ); ?>
257 </h2>
258
259 <form action="" method="post">
260 <div class="option">
261 <div class="input">
262 <input type="text" name="categorie_name" value=""
263 placeholder="<?php _e( 'Please enter the Name of the Categorie', 'double-opt-in' ); ?>"/>
264 <p>
265 <?php _e( 'Enter the name of the Categorie and submit.', 'double-opt-in' ); ?>
266 </p>
267 </div>
268 </div>
269 <?php
270 $this->get_logger()->debug( 'Rendering nonce field for category creation form.', [
271 'plugin' => $this->domain,
272 ] );
273 wp_nonce_field( 'doi_settings_action', 'doi_settings_nonce' );
274 ?>
275
276 <input type="submit" name="doubleoptin-settings-submit" class="button button-primary"
277 value=" <?php _e( 'Add', 'double-opt-in' ); ?>"/>
278 </form>
279 </div>
280 <?php
281 $this->get_logger()->notice( 'Sidebar content for "Categories" page rendered successfully.', [
282 'plugin' => $this->domain,
283 ] );
284 }
285
286 public function getSettings( $settings ) {
287 $this->get_logger()->info( 'getSettings method called. Returning the provided settings array without modification.', [
288 'plugin' => $this->domain,
289 'page_slug' => $this->slug,
290 'settings_keys' => is_array($settings) ? array_keys($settings) : 'not an array',
291 ] );
292
293 // This method is intentionally designed to be a pass-through
294 // It's part of a filter chain and simply returns the value it receives.
295 // Future subclasses can override this to inject or modify settings.
296 return $settings;
297 }
298
299 /**
300 * Create a new Category
301 *
302 * @return void
303 */
304 private function maybeAddCategory() {
305 $this->get_logger()->info( 'Attempting to add a new category.', [
306 'plugin' => $this->domain,
307 ] );
308
309 $name = sanitize_text_field( $_POST['categorie_name'] ?? '' );
310
311 // Validate the category name
312 if ( empty( $name ) ) {
313 Messages::getInstance()->add( __( 'Please enter a valid name for the categorie.', 'double-opt-in' ), 'error' );
314 $this->get_logger()->warning( 'Category name is empty. Cannot add category.', [
315 'plugin' => $this->domain,
316 ] );
317 return;
318 }
319
320 $this->get_logger()->debug( 'Category name sanitized: ' . $name, [
321 'plugin' => $this->domain,
322 ] );
323
324 $Category = new Category($this->get_logger());
325 $Category->set_name( $name );
326
327 // Attempt to save the new category
328 if ( $Category->save() ) {
329 Messages::getInstance()->add( __( 'New Category added', 'double-opt-in' ), 'success' );
330 $this->get_logger()->notice( 'New category successfully added to the database.', [
331 'plugin' => $this->domain,
332 'category_name' => $name,
333 'category_id' => $Category->get_id(),
334 ] );
335 } else {
336 Messages::getInstance()->add( __( 'Something went wrong', 'double-opt-in' ), 'error' );
337 $this->get_logger()->error( 'Failed to save the new category to the database.', [
338 'plugin' => $this->domain,
339 'category_name' => $name,
340 ] );
341 }
342 }
343
344 protected function onSave( $settings ) {
345 $this->get_logger()->info( 'Executing onSave method for the "Categories" UI page.', [
346 'plugin' => $this->domain,
347 ] );
348
349 // Call the method to handle adding a new category, if applicable.
350 // This function will handle its own validation and messaging.
351 $this->maybeAddCategory();
352
353 $this->get_logger()->notice( 'onSave method completed. Returning the original settings array.', [
354 'plugin' => $this->domain,
355 ] );
356
357 // This method does not modify the $settings array. It's used for
358 // handling form submissions that create new data rather than updating settings.
359 return $settings;
360 }
361 }
362 }