PluginProbe
Cookie Consent – GDPR & CCPA Cookie Banner & Consent Manager / 0.0.3
Cookie Consent – GDPR & CCPA Cookie Banner & Consent Manager v0.0.3
0.0.11 0.0.10 0.0.9 0.0.8 0.0.7 0.0.6 trunk 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5
cookiez / modules / scanner / database / scan-entry.php

scan-entry.php in Cookie Consent – GDPR & CCPA Cookie Banner & Consent Manager 0.0.3, at modules/scanner/database/scan-entry.php

130 lines 3.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Cookiez\Modules\Scanner\Database;
4
5 use Cookiez\Classes\Database\Entry;
6 use Cookiez\Modules\Scanner\Classes\Enums\Scan_Status;
7 use stdClass;
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class Scan_Entry extends Entry {
14 protected static function get_helper_class(): string {
15 return Scan_Table::class;
16 }
17
18 public static function find_many( array $where = [], ?int $limit = null, ?int $offset = null ): array {
19 $fields = [
20 's.id AS id',
21 's.api_id AS api_id',
22 's.status AS status',
23 's.type AS type',
24 's.initiator AS initiator',
25 's.summary AS summary',
26 's.created_at AS created_at',
27 's.updated_at AS updated_at',
28 'COUNT(DISTINCT u.id) AS total_urls',
29 "COUNT(DISTINCT CASE WHEN u.scan_status = '" . esc_sql( Scan_Status::COMPLETED ) . "' THEN u.id END) AS scanned_urls",
30 ];
31
32 $join = [
33 [ 'LEFT JOIN', Scan_Url_Table::class, 'u', 'u.scan_id = s.id' ],
34 ];
35
36 return (array) Scan_Table::select(
37 $fields,
38 ! empty( $where ) ? $where : '1',
39 $limit,
40 $offset,
41 $join,
42 [ 's.created_at' => 'DESC' ],
43 's.id',
44 's'
45 );
46 }
47
48 public static function find_by_id( int $scan_id ): ?stdClass {
49 $results = self::find_many( [ 's.id' => $scan_id ], 1 );
50
51 if ( empty( $results ) ) {
52 return null;
53 }
54
55 return $results[0];
56 }
57
58 public static function is_active_scan(): bool {
59 $result = Scan_Table::first(
60 Scan_Table::ID,
61 [ Scan_Table::STATUS => Scan_Status::IN_PROGRESS ]
62 );
63
64 return (bool) $result;
65 }
66
67 /**
68 * Oldest scan row with status completed (by created_at). Used for product timing (e.g. review prompt).
69 *
70 * @return \stdClass|null Row with id, api_id, status, created_at, updated_at or null.
71 */
72 public static function get_first_completed_scan(): ?\stdClass {
73 return Scan_Table::first(
74 '*',
75 [ Scan_Table::STATUS => Scan_Status::COMPLETED ],
76 1,
77 null,
78 '',
79 [ Scan_Table::UPDATED_AT => 'asc' ]
80 );
81 }
82
83 /**
84 * Return the first scan that is currently active (in-progress or paused), or null.
85 *
86 * @return bool
87 * Service-first insert: `$api_id` is obtained before reaching this method
88 * so every row has the service id stamped atomically.
89 */
90 public static function insert_one(
91 string $type,
92 string $initiator,
93 string $api_id,
94 string $status = Scan_Status::IN_PROGRESS
95 ): Scan_Entry {
96 $entry = new self();
97
98 $entry->set( Scan_Table::STATUS, $status );
99 $entry->set( Scan_Table::TYPE, $type );
100 $entry->set( Scan_Table::INITIATOR, $initiator );
101 $entry->set( Scan_Table::API_ID, $api_id );
102
103 $entry->create();
104
105 return $entry;
106 }
107
108 /**
109 * Whitelisted update. Unknown keys are dropped silently so callers can't
110 * round-trip arbitrary columns. Immutable columns are never in the list.
111 */
112 public static function update_one( int $scan_id, array $fields ) {
113 $mutable = [
114 Scan_Table::API_ID,
115 Scan_Table::STATUS,
116 Scan_Table::TYPE,
117 Scan_Table::INITIATOR,
118 Scan_Table::SUMMARY,
119 ];
120
121 $clean = array_intersect_key( $fields, array_flip( $mutable ) );
122
123 if ( empty( $clean ) ) {
124 return false;
125 }
126
127 return Scan_Table::update( $clean, [ Scan_Table::ID => $scan_id ] );
128 }
129 }
130