PluginProbe ʕ •ᴥ•ʔ
Download Manager / 3.3.63
Download Manager v3.3.63
3.3.63 3.3.62 3.3.61 3.3.60 3.3.59 3.3.58 3.3.57 3.3.56 trunk 2.1.3 2.3.0 2.5.96 2.5.97 2.6.2 2.6.96 2.8.3 2.9.99 3.0.4 3.1.05 3.1.07 3.1.08 3.1.11 3.1.12 3.1.14 3.1.17 3.1.18 3.1.22 3.1.23 3.1.24 3.1.25 3.1.26 3.1.27 3.1.28 3.2.04 3.2.13 3.2.14 3.2.16 3.2.18 3.2.19 3.2.21 3.2.22 3.2.23 3.2.24 3.2.25 3.2.27 3.2.28 3.2.29 3.2.30 3.2.31 3.2.32 3.2.33 3.2.34 3.2.35 3.2.37 3.2.38 3.2.39 3.2.40 3.2.41 3.2.42 3.2.43 3.2.44 3.2.45 3.2.46 3.2.47 3.2.48 3.2.49 3.2.50 3.2.51 3.2.52 3.2.53 3.2.54 3.2.55 3.2.56 3.2.57 3.2.58 3.2.59 3.2.60 3.2.61 3.2.63 3.2.64 3.2.65 3.2.66 3.2.67 3.2.68 3.2.69 3.2.70 3.2.71 3.2.72 3.2.73 3.2.74 3.2.75 3.2.76 3.2.77 3.2.78 3.2.79 3.2.80 3.2.81 3.2.82 3.2.83 3.2.84 3.2.85 3.2.86 3.2.87 3.2.88 3.2.89 3.2.90 3.2.91 3.2.92 3.2.93 3.2.94 3.2.95 3.2.96 3.2.97 3.2.98 3.2.99 3.3.00 3.3.01 3.3.02 3.3.03 3.3.04 3.3.05 3.3.06 3.3.07 3.3.08 3.3.09 3.3.10 3.3.11 3.3.12 3.3.13 3.3.14 3.3.15 3.3.16 3.3.17 3.3.18 3.3.19 3.3.20 3.3.21 3.3.22 3.3.23 3.3.24 3.3.25 3.3.26 3.3.27 3.3.28 3.3.29 3.3.30 3.3.31 3.3.32 3.3.33 3.3.34 3.3.35 3.3.36 3.3.37 3.3.38 3.3.39 3.3.40 3.3.41 3.3.42 3.3.43 3.3.44 3.3.45 3.3.46 3.3.47 3.3.48 3.3.49 3.3.50 3.3.51 3.3.52 3.3.53 3.3.54 3.3.55
download-manager / src / __ / Jobs / ActivityReportJob.php
download-manager / src / __ / Jobs Last commit date
ActivityReportJob.php 2 days ago CleanupJob.php 2 days ago DeleteExpiredJob.php 2 days ago Job.php 2 days ago JobBuilder.php 2 days ago JobHandler.php 2 days ago SendEmailJob.php 2 days ago
ActivityReportJob.php
258 lines
1 <?php
2 /**
3 * Activity Report Job Handler
4 *
5 * Sends periodic activity summary emails to administrators.
6 *
7 * @package WPDM\__\Jobs
8 * @since 7.0.2
9 */
10
11 namespace WPDM\__\Jobs;
12
13 use WPDM\__\ActivityReport;
14
15 class ActivityReportJob extends Job
16 {
17 /**
18 * Execute the activity report job
19 *
20 * @param object|array $data Job payload
21 * @return bool
22 */
23 public function handle($data): bool
24 {
25 // Check if feature is enabled
26 if (!(int) get_option('__wpdm_activity_report_enabled', 0)) {
27 $this->log('Activity reports feature is disabled');
28 return true; // Not an error, just disabled
29 }
30
31 $this->log('Starting activity report job');
32
33 // Get configuration from options (fallback to job data)
34 $frequency = get_option('__wpdm_activity_report_frequency', $this->get('frequency', 'weekly'));
35 $sections = get_option('__wpdm_activity_report_sections', $this->get('sections', ['download_summary', 'top_packages']));
36 $recipients = $this->getRecipients();
37
38 if (empty($recipients)) {
39 $this->log('No recipients configured for activity report');
40 return true; // Not an error, just no recipients
41 }
42
43 // Ensure sections is an array
44 if (!is_array($sections)) {
45 $sections = ['download_summary', 'top_packages'];
46 }
47
48 // Generate and send report
49 try {
50 $report = new ActivityReport($frequency);
51 $success = $report->sendReport($recipients, $sections);
52
53 if ($success) {
54 $this->log('Activity report sent successfully to ' . count($recipients) . ' recipient(s)');
55 } else {
56 $this->log('Failed to send activity report to some recipients', 'warning');
57 }
58
59 return true;
60 } catch (\Throwable $e) {
61 $this->log('Error generating activity report: ' . $e->getMessage(), 'error');
62 throw $e;
63 }
64 }
65
66 /**
67 * Get recipients from options
68 *
69 * @return array
70 */
71 private function getRecipients(): array
72 {
73 $recipients = [];
74
75 // Check if admin email should be included
76 $includeAdmin = (int) get_option('__wpdm_activity_report_admin', 1);
77 if ($includeAdmin) {
78 $recipients[] = get_option('admin_email');
79 }
80
81 // Get additional emails
82 $additionalEmails = get_option('__wpdm_activity_report_emails', '');
83 if (!empty($additionalEmails)) {
84 $emails = array_map('trim', explode(',', $additionalEmails));
85 foreach ($emails as $email) {
86 if (is_email($email) && !in_array($email, $recipients)) {
87 $recipients[] = $email;
88 }
89 }
90 }
91
92 // Fallback to job data if no options configured
93 if (empty($recipients)) {
94 $dataRecipients = $this->get('recipients', []);
95 if (is_array($dataRecipients)) {
96 $recipients = $dataRecipients;
97 }
98 }
99
100 return $recipients;
101 }
102
103 /**
104 * Get job name
105 *
106 * @return string
107 */
108 public static function getName(): string
109 {
110 return 'Activity Report';
111 }
112
113 /**
114 * Get job description
115 *
116 * @return string
117 */
118 public static function getDescription(): string
119 {
120 return 'Sends periodic activity summary emails to administrators';
121 }
122
123 /**
124 * Schedule the activity report job
125 *
126 * @return int|false Job ID on success, false on failure
127 */
128 public static function schedule()
129 {
130 // Cancel any existing job first
131 self::cancelExisting();
132
133 // Check if enabled
134 if (!(int) get_option('__wpdm_activity_report_enabled', 0)) {
135 return false;
136 }
137
138 $frequency = get_option('__wpdm_activity_report_frequency', 'weekly');
139 $day = (int) get_option('__wpdm_activity_report_day', $frequency === 'weekly' ? 1 : 1);
140 $hour = (int) get_option('__wpdm_activity_report_hour', 9);
141
142 // Calculate next execution time
143 $nextExecuteAt = self::calculateNextExecutionTime($frequency, $day, $hour);
144
145 // Calculate interval in seconds
146 $interval = $frequency === 'monthly' ? 30 * 86400 : 7 * 86400;
147
148 // Create the job
149 return \WPDM\__\CronJob::create(
150 self::class,
151 [
152 'frequency' => $frequency,
153 'scheduled_at' => time(),
154 ],
155 $nextExecuteAt,
156 0, // Repeat indefinitely
157 $interval,
158 'reports',
159 5,
160 3,
161 'wpdm_activity_report' // Unique code
162 );
163 }
164
165 /**
166 * Cancel existing activity report job
167 *
168 * @return bool
169 */
170 public static function cancelExisting(): bool
171 {
172 global $wpdb;
173
174 return $wpdb->query($wpdb->prepare(
175 "DELETE FROM {$wpdb->prefix}ahm_cron_jobs
176 WHERE type = %s AND status IN ('pending', 'running')",
177 self::class
178 )) !== false;
179 }
180
181 /**
182 * Calculate next execution time based on settings
183 *
184 * @param string $frequency
185 * @param int $day
186 * @param int $hour
187 * @return int Unix timestamp
188 */
189 private static function calculateNextExecutionTime(string $frequency, int $day, int $hour): int
190 {
191 $now = time();
192 $currentHour = (int) date('G');
193 $currentDay = (int) date('N'); // 1 = Monday, 7 = Sunday
194 $currentDayOfMonth = (int) date('j');
195
196 if ($frequency === 'monthly') {
197 // Monthly: Execute on specific day of month
198 $day = max(1, min(28, $day)); // Limit to 28 to avoid issues with short months
199
200 // Try this month first
201 $thisMonth = strtotime(date('Y-m-') . sprintf('%02d', $day) . ' ' . sprintf('%02d', $hour) . ':00:00');
202
203 if ($thisMonth > $now) {
204 return $thisMonth;
205 }
206
207 // Next month
208 return strtotime('+1 month', strtotime(date('Y-m-01') . ' ' . sprintf('%02d', $hour) . ':00:00')) + (($day - 1) * 86400);
209 } else {
210 // Weekly: Execute on specific day of week
211 $day = max(1, min(7, $day)); // 1 = Monday, 7 = Sunday
212
213 // Days until target day
214 $daysUntil = $day - $currentDay;
215
216 if ($daysUntil < 0) {
217 $daysUntil += 7;
218 } elseif ($daysUntil === 0 && $currentHour >= $hour) {
219 $daysUntil = 7;
220 }
221
222 return strtotime('+' . $daysUntil . ' days', strtotime(date('Y-m-d') . ' ' . sprintf('%02d', $hour) . ':00:00'));
223 }
224 }
225
226 /**
227 * Send a test report
228 *
229 * @param string $email Email address to send test to
230 * @return bool
231 */
232 public static function sendTestReport(string $email): bool
233 {
234 if (!is_email($email)) {
235 return false;
236 }
237
238 $frequency = get_option('__wpdm_activity_report_frequency', 'weekly');
239 $sections = get_option('__wpdm_activity_report_sections', [
240 'download_summary',
241 'top_packages',
242 'user_activity',
243 ]);
244
245 if (!is_array($sections) || empty($sections)) {
246 $sections = ['download_summary', 'top_packages', 'user_activity'];
247 }
248
249 try {
250 $report = new ActivityReport($frequency);
251 return $report->sendReport([$email], $sections);
252 } catch (\Throwable $e) {
253 error_log('[WPDM] Test report failed: ' . $e->getMessage());
254 return false;
255 }
256 }
257 }
258