PluginProbe
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification / 5.5.0
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification v5.5.0
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 3.0.0 3.0.1 3.0.2 3.0.3 3.0.5 3.0.51 3.0.60 3.0.61 3.0.62 3.0.70 3.0.71 3.0.72 All 35 releases
← All changes | core/Category.class.php +514 -259 2.135.5.0 View file →
@@ -1,302 +1,557 @@
1 1 <?php
2 2
3 3 namespace forge12\contactform7\CF7DoubleOptIn {
4 - if (!defined('ABSPATH')) {
5 - exit;
6 - }
7 4
8 - /**
9 - * Class Category
10 - * Handle the Categories
11 - *
12 - * @package forge12\contactform7\CF7DoubleOptIn
13 - */
14 - class Category
15 - {
16 - /**
17 - * Stores the DB ID for the entry
18 - *
19 - * @var int
20 - */
21 - private $id = 0;
5 + use Forge12\Shared\Logger;
6 + use Forge12\Shared\LoggerInterface;
22 7
23 - /**
24 - * The name of the category
25 - *
26 - * @var string
27 - */
28 - private $name = '';
29 - /**
30 - * Stores the timestamp the opt-in mail has been sent to the user.
31 - *
32 - * @var string
33 - */
34 - private $createtime = "";
35 - /**
36 - * Stores the timestamp the opt-in has been confirmed by the user.
37 - */
38 - private $updatetime = "";
8 + if ( ! defined( 'ABSPATH' ) ) {
9 + exit;
10 + }
39 11
40 - /**
41 - * The constructor
42 - */
43 - public function __construct(array $properties = array())
44 - {
45 - foreach ($properties as $name => $value) {
46 - if (isset($this->{$name})) {
47 - $this->{$name} = $value;
48 - }
49 - }
50 - }
12 + /**
13 + * Class Category
14 + * Handle the Categories
15 + *
16 + * @package forge12\contactform7\CF7DoubleOptIn
17 + */
18 + class Category {
19 + /**
20 + * Stores the DB ID for the entry
21 + *
22 + * @var int
23 + */
24 + private $id = 0;
51 25
52 - /**
53 - * Return the ID of the Optin
54 - *
55 - * @return int
56 - */
57 - public function get_id()
58 - {
59 - return $this->id;
60 - }
26 + /**
27 + * The name of the category
28 + *
29 + * @var string
30 + */
31 + private $name = '';
32 + /**
33 + * Stores the timestamp the opt-in mail has been sent to the user.
34 + *
35 + * @var string
36 + */
37 + private $createtime = "";
38 + /**
39 + * Stores the timestamp the opt-in has been confirmed by the user.
40 + */
41 + private $updatetime = "";
42 + private LoggerInterface $logger;
61 43
62 - /**
63 - * Return the name of the category
64 - *
65 - * @return string
66 - */
67 - public function get_name()
68 - {
69 - return $this->name;
70 - }
44 + /**
45 + * The constructor
46 + */
47 + public function __construct( LoggerInterface $logger, array $properties = array() ) {
48 + $this->logger = $logger;
49 + $this->get_logger()->info( 'Constructor started.', [ 'plugin' => 'double-opt-in' ] );
71 50
72 - /**
73 - * Set the name of the category
74 - *
75 - * @param string $name
76 - *
77 - * @return void
78 - */
79 - public function set_name($name)
80 - {
81 - $this->name = $name;
82 - }
51 + foreach ( $properties as $name => $value ) {
52 + if ( isset( $this->{$name} ) ) {
53 + $this->{$name} = $value;
54 + $this->get_logger()->debug( 'Property ' . $name . ' set.', [
55 + 'plugin' => 'double-opt-in',
56 + 'property' => $name,
57 + 'value' => $value,
58 + ] );
59 + } else {
60 + $this->get_logger()->warning( 'Attempted to set a non-existent property.', [
61 + 'plugin' => 'double-opt-in',
62 + 'property' => $name,
63 + ] );
64 + }
65 + }
83 66
84 - /**
85 - * @param string $timestamp
86 - */
87 - public function set_createtime($timestamp)
88 - {
89 - $this->createtime = $timestamp;
90 - }
67 + $this->get_logger()->info( 'Constructor finished successfully.', [ 'plugin' => 'double-opt-in' ] );
68 + }
91 69
92 - /**
93 - * Return a timestamp
94 - *
95 - * @param string $view Select how to return the content. raw is the stored db value. use formatted to return a
96 - * formatted string.
97 - *
98 - * @return string
99 - */
100 - public function get_createtime($view = "raw")
101 - {
102 - if (empty($this->createtime)) {
103 - $this->set_createtime(time());
104 - }
70 + public function get_logger() {
71 + return $this->logger;
72 + }
105 73
106 - if ($view != "raw") {
107 - if (!is_numeric($this->createtime)) {
108 - $date = date('d.m.Y', strtotime($this->createtime));
109 - $time = date('H:i:s', strtotime($this->createtime));
110 - } else {
111 - $date = date('d.m.Y', $this->createtime);
112 - $time = date('H:i:s', $this->createtime);
113 - }
74 + /**
75 + * Return the ID of the Optin
76 + *
77 + * @return int
78 + */
79 + public function get_id() {
80 + return $this->id;
81 + }
114 82
115 - return $date . ' ' . __('/', 'double-opt-in') . ' ' . $time;
116 - } else {
117 - return $this->createtime;
118 - }
119 - }
83 + /**
84 + * Return the name of the category
85 + *
86 + * @return string
87 + */
88 + public function get_name() {
89 + return $this->name;
90 + }
120 91
121 - /**
122 - * @param string $timestamp
123 - */
124 - public function set_updatetime($timestamp)
125 - {
126 - $this->updatetime = $timestamp;
127 - }
92 + /**
93 + * Set the name of the category
94 + *
95 + * @param string $name
96 + *
97 + * @return void
98 + */
99 + public function set_name( $name ) {
100 + $this->name = $name;
101 + }
128 102
129 - /**
130 - * Return a timestamp
131 - *
132 - * @param string $view Select how to return the content. raw is the stored db value. use formatted to return a
133 - * formatted string.
134 - *
135 - * @return string
136 - */
137 - public function get_updatetime($view = 'raw')
138 - {
139 - if (empty($this->updatetime)) {
140 - $this->set_updatetime(time());
141 - }
103 + /**
104 + * @param string $timestamp
105 + */
106 + public function set_createtime( $timestamp ) {
107 + $this->createtime = $timestamp;
108 + }
142 109
143 - if ($view != "raw") {
144 - if (!is_numeric($this->updatetime)) {
145 - $date = date('d.m.Y', strtotime($this->updatetime));
146 - $time = date('H:i:s', strtotime($this->updatetime));
147 - } else {
148 - $date = date('d.m.Y', $this->updatetime);
149 - $time = date('H:i:s', $this->updatetime);
150 - }
151 - return $date . ' ' . __('/', 'double-opt-in') . ' ' . $time;
152 - } else {
153 - return $this->updatetime;
154 - }
155 - }
110 + /**
111 + * Return a timestamp
112 + *
113 + * @param string $view Select how to return the content. raw is the stored db value. use formatted to return a
114 + * formatted string.
115 + *
116 + * @return string
117 + */
118 + public function get_createtime( $view = "raw" ) {
119 + $this->get_logger()->info( 'Getting creation time.', [
120 + 'plugin' => 'double-opt-in',
121 + 'view' => $view
122 + ] );
156 123
157 - /**
158 - * Return the link to the category
159 - * @return string
160 - */
161 - public function get_link_ui(){
162 - return admin_url('admin.php?page=f12-cf7-doubleoptin_categories_view&id='.$this->get_id());
163 - }
124 + if ( empty( $this->createtime ) ) {
125 + $this->get_logger()->warning( 'Creation time is empty. Setting to current time.', [
126 + 'plugin' => 'double-opt-in'
127 + ] );
128 + $this->set_createtime( time() );
129 + }
164 130
165 - /**
166 - * Return a list of opt ins stored in the database.
167 - *
168 - * @param $atts array (
169 - * 'perPage' => 10, // Posts per page
170 - * 'page' => 0, // Current page
171 - * 'order' => DESC, // Order (ASC/DESC)
172 - * );
173 - *
174 - * @param null $numberOfPages - Stores the number of pages found if limited
175 - *
176 - * @return array<Category>
177 - */
178 - public static function get_list($atts = array(), &$numberOfPages = null)
179 - {
180 - global $wpdb;
131 + if ( $view != "raw" ) {
132 + $this->get_logger()->debug( 'Processing creation time for formatted view.', [
133 + 'plugin' => 'double-opt-in',
134 + 'time_value' => $this->createtime
135 + ] );
181 136
182 - $attr = array(
183 - 'perPage' => 10,
184 - 'page' => 1,
185 - 'order' => 'DESC',
186 - 'orderBy' => 'ID',
187 - );
137 + if ( ! is_numeric( $this->createtime ) ) {
138 + $date = date( 'd.m.Y', strtotime( $this->createtime ) );
139 + $time = date( 'H:i:s', strtotime( $this->createtime ) );
140 + $this->get_logger()->debug( 'Creation time is not numeric. Converting from string.', [
141 + 'plugin' => 'double-opt-in'
142 + ] );
143 + } else {
144 + $date = date( 'd.m.Y', $this->createtime );
145 + $time = date( 'H:i:s', $this->createtime );
146 + $this->get_logger()->debug( 'Creation time is numeric. Converting from timestamp.', [
147 + 'plugin' => 'double-opt-in'
148 + ] );
149 + }
188 150
189 - foreach ($atts as $key => $value) {
190 - if (isset($attr[$key])) {
191 - $attr[$key] = $atts[$key];
192 - }
193 - }
151 + $formatted_time = $date . ' ' . __( '/', 'double-opt-in' ) . ' ' . $time;
152 + $this->get_logger()->info( 'Returning formatted creation time.', [
153 + 'plugin' => 'double-opt-in',
154 + 'formatted_value' => $formatted_time
155 + ] );
156 + return $formatted_time;
157 + } else {
158 + $this->get_logger()->info( 'Returning raw creation time.', [
159 + 'plugin' => 'double-opt-in',
160 + 'raw_value' => $this->createtime
161 + ] );
162 + return $this->createtime;
163 + }
164 + }
194 165
195 - $tableName = $wpdb->prefix . 'f12_cf7_doubleoptin_categories';
196 - $pageNum = (int)$attr['page'] - 1;
166 + /**
167 + * @param string $timestamp
168 + */
169 + public function set_updatetime( $timestamp ) {
170 + $this->updatetime = $timestamp;
171 + }
197 172
198 - if ($numberOfPages !== null) {
199 - $result = $wpdb->get_row('SELECT count(*) AS counter FROM ' . $tableName);
173 + /**
174 + * Return a timestamp
175 + *
176 + * @param string $view Select how to return the content. raw is the stored db value. use formatted to return a
177 + * formatted string.
178 + *
179 + * @return string
180 + */
181 + public function get_updatetime( $view = 'raw' ) {
182 + $this->get_logger()->info( 'Retrieving update time.', [
183 + 'plugin' => 'double-opt-in',
184 + 'view' => $view
185 + ] );
200 186
201 - $itemCounter = $result->counter;
187 + if ( empty( $this->updatetime ) ) {
188 + $this->get_logger()->warning( 'Update time is empty. Setting to current time.', [
189 + 'plugin' => 'double-opt-in'
190 + ] );
191 + $this->set_updatetime( time() );
192 + }
202 193
203 - $numberOfPages = 1;
194 + if ( $view != "raw" ) {
195 + $this->get_logger()->debug( 'Processing update time for formatted view.', [
196 + 'plugin' => 'double-opt-in'
197 + ] );
204 198
205 - if ($attr['perPage'] != -1) {
206 - $numberOfPages = ceil($itemCounter / (int)$attr['perPage']);
207 - }
208 - }
199 + if ( ! is_numeric( $this->updatetime ) ) {
200 + $date = date( 'd.m.Y', strtotime( $this->updatetime ) );
201 + $time = date( 'H:i:s', strtotime( $this->updatetime ) );
202 + $this->get_logger()->debug( 'Update time is not numeric; converting from string.', [
203 + 'plugin' => 'double-opt-in'
204 + ] );
205 + } else {
206 + $date = date( 'd.m.Y', $this->updatetime );
207 + $time = date( 'H:i:s', $this->updatetime );
208 + $this->get_logger()->debug( 'Update time is numeric; converting from timestamp.', [
209 + 'plugin' => 'double-opt-in'
210 + ] );
211 + }
209 212
210 - $offset = $pageNum * (int)$attr['perPage'];
213 + $formatted_time = $date . ' ' . __( '/', 'double-opt-in' ) . ' ' . $time;
214 + $this->get_logger()->info( 'Returning formatted update time.', [
215 + 'plugin' => 'double-opt-in',
216 + 'formatted_value' => $formatted_time
217 + ] );
218 + return $formatted_time;
219 + } else {
220 + $this->get_logger()->info( 'Returning raw update time.', [
221 + 'plugin' => 'double-opt-in',
222 + 'raw_value' => $this->updatetime
223 + ] );
224 + return $this->updatetime;
225 + }
226 + }
211 227
212 - $limit = '';
228 + /**
229 + * Return the link to the category
230 + *
231 + * @return string
232 + */
233 + public function get_link_ui() {
234 + $link = admin_url( 'admin.php?page=f12-cf7-doubleoptin_categories_view&id=' . $this->get_id() );
213 235
214 - if ($attr['perPage'] != -1) {
215 - $limit = ' LIMIT ' . (int)$attr['perPage'] . ' OFFSET ' . $offset;
216 - }
236 + $this->get_logger()->info( 'Generating UI link for admin page.', [
237 + 'plugin' => 'double-opt-in',
238 + 'link' => $link,
239 + 'id' => $this->get_id(),
240 + ] );
217 241
218 - $rows = $wpdb->get_results('SELECT * FROM ' . $tableName . ' ORDER BY ' . $attr['orderBy'] . ' ' . $attr['order'] . $limit, ARRAY_A);
242 + return $link;
243 + }
219 244
220 - $list = array();
221 - foreach ($rows as $row) {
222 - $list[] = new Category($row);
223 - }
224 - return $list;
225 - }
245 + /**
246 + * Return a list of opt ins stored in the database.
247 + *
248 + * @param $atts array (
249 + * 'perPage' => 10, // Posts per page
250 + * 'page' => 0, // Current page
251 + * 'order' => DESC, // Order (ASC/DESC)
252 + * );
253 + *
254 + * @param null $numberOfPages - Stores the number of pages found if limited
255 + *
256 + * @return array<Category>
257 + */
258 + public static function get_list( $atts = array(), &$numberOfPages = null ) {
259 + global $wpdb;
226 260
227 - /**
228 - * Return a Category by the given ID
229 - *
230 - * @param $id
231 - *
232 - * @return Category|null
233 - */
234 - public static function get_by_id($id)
235 - {
236 - global $wpdb;
237 - $table = $wpdb->prefix . 'f12_cf7_doubleoptin_categories';
261 + // Log the start of the get_list function.
262 + Logger::getInstance()->info( 'Fetching a list of categories.', [
263 + 'plugin' => 'double-opt-in',
264 + 'atts' => $atts,
265 + ] );
238 266
239 - $rows = $wpdb->get_results($wpdb->prepare('SELECT * FROM ' . $table . ' WHERE id=%d', $id), ARRAY_A);
267 + $attr = array(
268 + 'perPage' => 10,
269 + 'page' => 1,
270 + 'order' => 'DESC',
271 + 'orderBy' => 'ID',
272 + );
240 273
241 - if (is_array($rows) && !empty($rows)) {
242 - $rows = $rows[0];
243 - return new Category($rows);
244 - }
274 + foreach ( $atts as $key => $value ) {
275 + if ( isset( $attr[ $key ] ) ) {
276 + $attr[ $key ] = $atts[ $key ];
277 + }
278 + }
245 279
246 - return null;
247 - }
280 + // Whitelist allowed columns for ORDER BY to prevent SQL injection
281 + $allowed_order_by = array( 'ID', 'id', 'name', 'createtime', 'updatetime' );
248 282
249 - /**
250 - * Delete a Category by the given id. All assigned Opt-Ins will be changed to be uncategorized.
251 - *
252 - * @param $id
253 - *
254 - * @return bool|int|\mysqli_result|resource|null
255 - */
256 - public static function delete_by_id($id)
257 - {
258 - global $wpdb;
283 + // Validate orderBy against whitelist
284 + if ( ! in_array( $attr['orderBy'], $allowed_order_by, true ) ) {
285 + $attr['orderBy'] = 'ID';
286 + }
259 287
260 - $table = $wpdb->prefix . 'f12_cf7_doubleoptin_categories';
288 + // Validate order against whitelist
289 + if ( ! in_array( strtoupper( $attr['order'] ), array( 'ASC', 'DESC' ), true ) ) {
290 + $attr['order'] = 'DESC';
291 + }
261 292
262 - // Ensure that the opt in class exists otherwise do nothing.
263 - if (class_exists('forge12\contactform7\CF7DoubleOptIn\OptIn')) {
264 - OptIn::bulk_update_category($id, 0);
293 + // Log the final attributes used for the query.
294 + Logger::getInstance()->debug( 'Using the following attributes for the query.', [
295 + 'plugin' => 'double-opt-in',
296 + 'attributes' => $attr,
297 + ] );
265 298
266 - return $wpdb->delete($table, array('id' => $id), array('%d'));
267 - }
299 + $tableName = $wpdb->prefix . 'f12_cf7_doubleoptin_categories';
300 + $pageNum = (int) $attr['page'] - 1;
268 301
269 - return false;
270 - }
302 + if ( $numberOfPages !== null ) {
303 + // Log the start of counting items for pagination.
304 + Logger::getInstance()->info( 'Counting total items for pagination.', [
305 + 'plugin' => 'double-opt-in',
306 + ] );
271 307
272 - /**
273 - * Update or create the given Object
274 - */
275 - public function save()
276 - {
277 - global $wpdb;
278 - $table = $wpdb->prefix . 'f12_cf7_doubleoptin_categories';
308 + $result = $wpdb->get_row( 'SELECT count(*) AS counter FROM ' . $tableName );
279 309
280 - if (!empty($this->get_id()) || 0 < $this->get_id()) {
281 - return $wpdb->update($table, array(
282 - 'name' => $this->get_name(),
283 - 'updatetime' => $this->get_updatetime()
284 - ), array(
285 - 'id' => $this->get_id()
286 - ));
287 - } else {
288 - $result = $wpdb->insert($table, array(
289 - 'name' => $this->get_name(),
290 - 'createtime' => $this->get_createtime(),
291 - 'updatetime' => $this->get_updatetime(),
292 - ));
310 + if ( $result ) {
311 + $itemCounter = $result->counter;
293 312
294 - if ($result > 0) {
295 - $this->id = $wpdb->insert_id;
296 - return $this->id;
297 - }
298 - }
299 - return false;
300 - }
301 - }
313 + $numberOfPages = 1;
314 +
315 + if ( $attr['perPage'] != - 1 ) {
316 + $numberOfPages = ceil( $itemCounter / (int) $attr['perPage'] );
317 + }
318 + // Log the calculated number of pages.
319 + Logger::getInstance()->info( 'Calculated number of pages.', [
320 + 'plugin' => 'double-opt-in',
321 + 'total_items' => $itemCounter,
322 + 'items_per_page' => $attr['perPage'],
323 + 'total_pages' => $numberOfPages,
324 + ] );
325 + } else {
326 + // Log a potential error if the count query fails.
327 + Logger::getInstance()->error( 'Failed to count total items for pagination.', [
328 + 'plugin' => 'double-opt-in',
329 + 'query' => $wpdb->last_query,
330 + 'error' => $wpdb->last_error,
331 + ] );
332 + }
333 + }
334 +
335 + $offset = $pageNum * (int) $attr['perPage'];
336 +
337 + $limit = '';
338 +
339 + if ( $attr['perPage'] != - 1 ) {
340 + $limit = ' LIMIT ' . (int) $attr['perPage'] . ' OFFSET ' . $offset;
341 + }
342 +
343 + $query = 'SELECT * FROM ' . $tableName . ' ORDER BY ' . $attr['orderBy'] . ' ' . $attr['order'] . $limit;
344 + // Log the final query before execution.
345 + Logger::getInstance()->debug( 'Executing database query to fetch categories.', [
346 + 'plugin' => 'double-opt-in',
347 + 'query' => $query,
348 + ] );
349 +
350 + $rows = $wpdb->get_results( $query, ARRAY_A );
351 +
352 + if ( $rows === null ) {
353 + // Log a potential error if the main query fails.
354 + Logger::getInstance()->error( 'Failed to fetch categories from the database.', [
355 + 'plugin' => 'double-opt-in',
356 + 'query' => $wpdb->last_query,
357 + 'error' => $wpdb->last_error,
358 + ] );
359 + }
360 +
361 + $list = array();
362 + foreach ( $rows as $row ) {
363 + $list[] = new Category( Logger::getInstance(), $row );
364 + }
365 +
366 + // Log the number of items retrieved.
367 + Logger::getInstance()->info( 'Successfully retrieved ' . count($list) . ' categories.', [
368 + 'plugin' => 'double-opt-in',
369 + 'count' => count( $list ),
370 + ] );
371 +
372 + return $list;
373 + }
374 +
375 + /**
376 + * Return a Category by the given ID
377 + *
378 + * @param $id
379 + *
380 + * @return Category|null
381 + */
382 + public static function get_by_id( $id ) {
383 + global $wpdb;
384 +
385 + // Log the start of the get_by_id function.
386 + Logger::getInstance()->info( 'Attempting to retrieve category by ID.', [
387 + 'plugin' => 'double-opt-in',
388 + 'id' => $id,
389 + ] );
390 +
391 + $table = $wpdb->prefix . 'f12_cf7_doubleoptin_categories';
392 +
393 + $query = $wpdb->prepare( 'SELECT * FROM ' . $table . ' WHERE id=%d', $id );
394 +
395 + // Log the prepared query before execution.
396 + Logger::getInstance()->debug( 'Executing database query to get category by ID.', [
397 + 'plugin' => 'double-opt-in',
398 + 'query' => $query,
399 + ] );
400 +
401 + $rows = $wpdb->get_results( $query, ARRAY_A );
402 +
403 + if ( is_array( $rows ) && ! empty( $rows ) ) {
404 + $rows = $rows[0];
405 +
406 + // Log the successful retrieval of the category.
407 + Logger::getInstance()->info( 'Category found and retrieved successfully.', [
408 + 'plugin' => 'double-opt-in',
409 + 'id' => $id,
410 + 'category' => $rows,
411 + ] );
412 +
413 + return new Category( Logger::getInstance(), $rows );
414 + }
415 +
416 + // Log that no category was found with the given ID.
417 + Logger::getInstance()->warning( 'No category found with the given ID.', [
418 + 'plugin' => 'double-opt-in',
419 + 'id' => $id,
420 + ] );
421 +
422 + return null;
423 + }
424 +
425 + /**
426 + * Delete a Category by the given id. All assigned Opt-Ins will be changed to be uncategorized.
427 + *
428 + * @param $id
429 + *
430 + * @return bool|int|\mysqli_result|resource|null
431 + */
432 + public static function delete_by_id( $id ) {
433 + global $wpdb;
434 +
435 + // Log the start of the deletion process.
436 + Logger::getInstance()->info( 'Attempting to delete category by ID.', [
437 + 'plugin' => 'double-opt-in',
438 + 'id' => $id,
439 + ] );
440 +
441 + $table = $wpdb->prefix . 'f12_cf7_doubleoptin_categories';
442 +
443 + // Ensure that the opt in class exists otherwise do nothing.
444 + if ( class_exists( 'forge12\contactform7\CF7DoubleOptIn\OptIn' ) ) {
445 + // Log the action before updating the category in the OptIn class.
446 + Logger::getInstance()->info( 'Updating category for related opt-ins before deletion.', [
447 + 'plugin' => 'double-opt-in',
448 + 'old_id' => $id,
449 + 'new_id' => 0,
450 + ] );
451 +
452 + OptIn::bulk_update_category( $id, 0 );
453 +
454 + // Log the deletion from the database.
455 + $result = $wpdb->delete( $table, array( 'id' => $id ), array( '%d' ) );
456 +
457 + if ( $result === false ) {
458 + // Log an error if the deletion failed.
459 + Logger::getInstance()->error( 'Failed to delete category from the database.', [
460 + 'plugin' => 'double-opt-in',
461 + 'id' => $id,
462 + 'error' => $wpdb->last_error,
463 + ] );
464 + } else {
465 + // Log a successful deletion.
466 + Logger::getInstance()->notice( 'Category deleted successfully.', [
467 + 'plugin' => 'double-opt-in',
468 + 'id' => $id,
469 + 'rows_deleted' => $result,
470 + ] );
471 + }
472 +
473 + return $result;
474 + }
475 +
476 + // Log that the required class does not exist.
477 + Logger::getInstance()->warning( 'Required OptIn class does not exist. Deletion process aborted.', [
478 + 'plugin' => 'double-opt-in',
479 + 'id' => $id,
480 + ] );
481 +
482 + return false;
483 + }
484 +
485 + /**
486 + * Update or create the given Object
487 + */
488 + public function save() {
489 + global $wpdb;
490 +
491 + $this->get_logger()->info( 'Attempting to save category data.', [ 'plugin' => 'double-opt-in' ] );
492 +
493 + $table = $wpdb->prefix . 'f12_cf7_doubleoptin_categories';
494 +
495 + if ( ! empty( $this->get_id() ) && $this->get_id() > 0 ) {
496 + $this->get_logger()->info( 'Updating existing category.', [
497 + 'plugin' => 'double-opt-in',
498 + 'id' => $this->get_id(),
499 + ] );
500 +
501 + $result = $wpdb->update( $table, array(
502 + 'name' => $this->get_name(),
503 + 'updatetime' => $this->get_updatetime()
504 + ), array(
505 + 'id' => $this->get_id()
506 + ) );
507 +
508 + if ( $result === false ) {
509 + $this->get_logger()->error( 'Failed to update category.', [
510 + 'plugin' => 'double-opt-in',
511 + 'id' => $this->get_id(),
512 + 'name' => $this->get_name(),
513 + 'error' => $wpdb->last_error,
514 + ] );
515 + } else {
516 + $this->get_logger()->notice( 'Category updated successfully.', [
517 + 'plugin' => 'double-opt-in',
518 + 'id' => $this->get_id(),
519 + 'rows_affected' => $result,
520 + ] );
521 + }
522 +
523 + return $result;
524 + } else {
525 + $this->get_logger()->info( 'Inserting new category.', [ 'plugin' => 'double-opt-in' ] );
526 +
527 + $result = $wpdb->insert( $table, array(
528 + 'name' => $this->get_name(),
529 + 'createtime' => $this->get_createtime(),
530 + 'updatetime' => $this->get_updatetime(),
531 + ) );
532 +
533 + if ( $result > 0 ) {
534 + $this->id = $wpdb->insert_id;
535 + $this->get_logger()->notice( 'New category inserted successfully.', [
536 + 'plugin' => 'double-opt-in',
537 + 'id' => $this->id,
538 + 'name' => $this->get_name(),
539 + ] );
540 + return $this->id;
541 + } else {
542 + $this->get_logger()->error( 'Failed to insert new category.', [
543 + 'plugin' => 'double-opt-in',
544 + 'name' => $this->get_name(),
545 + 'error' => $wpdb->last_error,
546 + ] );
547 + }
548 + }
549 +
550 + $this->get_logger()->critical( 'Save operation failed for an unknown reason.', [
551 + 'plugin' => 'double-opt-in',
552 + ] );
553 +
554 + return false;
555 + }
556 + }
302 557 }