Analytics_Manager.php
8 months ago
Browser_Detector.php
9 months ago
Content_Cache_Manager.php
9 months ago
Data_Collector.php
2 months ago
Email_Reports.php
9 months ago
Export_Manager.php
9 months ago
License_Manager.php
9 months ago
Milestone_Manager.php
9 months ago
Pro_Data_Collector.php
9 months ago
REST_API.php
9 months ago
Export_Manager.php
737 lines
| 1 | <?php |
| 2 | |
| 3 | namespace EmbedPress\Includes\Classes\Analytics; |
| 4 | |
| 5 | /** |
| 6 | * Export Manager for Analytics Data |
| 7 | * Handles exporting analytics data in various formats (CSV, Excel, PDF) |
| 8 | */ |
| 9 | class Export_Manager |
| 10 | { |
| 11 | /** |
| 12 | * Export analytics data in specified format |
| 13 | * |
| 14 | * @param string $format Export format (csv, excel, pdf) |
| 15 | * @param array $analytics_data General analytics data |
| 16 | * @param array $content_analytics Detailed content analytics |
| 17 | * @param array $args Export arguments |
| 18 | * @return array Export result with success status and file info |
| 19 | */ |
| 20 | public function export_data($format, $analytics_data, $content_analytics, $args = []) |
| 21 | { |
| 22 | try { |
| 23 | switch ($format) { |
| 24 | case 'csv': |
| 25 | return $this->export_csv($analytics_data, $content_analytics, $args); |
| 26 | case 'excel': |
| 27 | return $this->export_excel($analytics_data, $content_analytics, $args); |
| 28 | case 'pdf': |
| 29 | return $this->export_pdf($analytics_data, $content_analytics, $args); |
| 30 | default: |
| 31 | return [ |
| 32 | 'success' => false, |
| 33 | 'message' => __('Unsupported export format.', 'embedpress') |
| 34 | ]; |
| 35 | } |
| 36 | } catch (\Exception $e) { |
| 37 | return [ |
| 38 | 'success' => false, |
| 39 | 'message' => $e->getMessage() |
| 40 | ]; |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * Export data as CSV |
| 46 | * |
| 47 | * @param array $analytics_data |
| 48 | * @param array $content_analytics |
| 49 | * @param array $args |
| 50 | * @return array |
| 51 | */ |
| 52 | private function export_csv($analytics_data, $content_analytics, $args) |
| 53 | { |
| 54 | $filename = $this->generate_filename('csv', $args); |
| 55 | $file_path = $this->get_export_directory() . $filename; |
| 56 | |
| 57 | // Create CSV content |
| 58 | $csv_content = $this->generate_csv_content($analytics_data, $content_analytics, $args); |
| 59 | |
| 60 | // Write to file |
| 61 | if (file_put_contents($file_path, $csv_content) === false) { |
| 62 | return [ |
| 63 | 'success' => false, |
| 64 | 'message' => __('Failed to create CSV file.', 'embedpress') |
| 65 | ]; |
| 66 | } |
| 67 | |
| 68 | return [ |
| 69 | 'success' => true, |
| 70 | 'filename' => $filename, |
| 71 | 'download_url' => $this->get_download_url($filename), |
| 72 | 'file_path' => $file_path |
| 73 | ]; |
| 74 | } |
| 75 | |
| 76 | /** |
| 77 | * Export data as Excel |
| 78 | * |
| 79 | * @param array $analytics_data |
| 80 | * @param array $content_analytics |
| 81 | * @param array $args |
| 82 | * @return array |
| 83 | */ |
| 84 | private function export_excel($analytics_data, $content_analytics, $args) |
| 85 | { |
| 86 | $filename = $this->generate_filename('xlsx', $args); |
| 87 | $file_path = $this->get_export_directory() . $filename; |
| 88 | |
| 89 | // For now, create Excel as CSV with .xlsx extension |
| 90 | // In a full implementation, you'd use a library like PhpSpreadsheet |
| 91 | $csv_content = $this->generate_csv_content($analytics_data, $content_analytics, $args); |
| 92 | |
| 93 | if (file_put_contents($file_path, $csv_content) === false) { |
| 94 | return [ |
| 95 | 'success' => false, |
| 96 | 'message' => __('Failed to create Excel file.', 'embedpress') |
| 97 | ]; |
| 98 | } |
| 99 | |
| 100 | return [ |
| 101 | 'success' => true, |
| 102 | 'filename' => $filename, |
| 103 | 'download_url' => $this->get_download_url($filename), |
| 104 | 'file_path' => $file_path |
| 105 | ]; |
| 106 | } |
| 107 | |
| 108 | /** |
| 109 | * Export data as PDF (Frontend generation) |
| 110 | * Returns HTML content for frontend PDF generation |
| 111 | * |
| 112 | * @param array $analytics_data |
| 113 | * @param array $content_analytics |
| 114 | * @param array $args |
| 115 | * @return array |
| 116 | */ |
| 117 | private function export_pdf($analytics_data, $content_analytics, $args) |
| 118 | { |
| 119 | try { |
| 120 | // Generate HTML content for frontend PDF generation |
| 121 | $html_content = $this->generate_html_report($analytics_data, $content_analytics, $args); |
| 122 | |
| 123 | return [ |
| 124 | 'success' => true, |
| 125 | 'frontend_export' => true, |
| 126 | 'export_type' => 'pdf', |
| 127 | 'html_content' => $html_content, |
| 128 | 'filename' => $this->generate_filename('pdf', $args) |
| 129 | ]; |
| 130 | |
| 131 | } catch (\Exception $e) { |
| 132 | return [ |
| 133 | 'success' => false, |
| 134 | 'message' => __('Failed to generate PDF HTML. Please try again.', 'embedpress') |
| 135 | ]; |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * Prepare structured data for frontend PDF generation |
| 141 | * |
| 142 | * @param array $analytics_data |
| 143 | * @param array $content_analytics |
| 144 | * @param array $args |
| 145 | * @return array |
| 146 | */ |
| 147 | private function prepare_pdf_data($analytics_data, $content_analytics, $args) |
| 148 | { |
| 149 | $date_range = $args['date_range'] ?? 30; |
| 150 | $start_date = $args['start_date'] ?? null; |
| 151 | $end_date = $args['end_date'] ?? null; |
| 152 | |
| 153 | // Prepare structured data for frontend PDF generation |
| 154 | return [ |
| 155 | 'report_info' => [ |
| 156 | 'title' => 'EmbedPress Analytics Report', |
| 157 | 'generated_date' => current_time('Y-m-d H:i:s'), |
| 158 | 'date_range' => $date_range, |
| 159 | 'start_date' => $start_date, |
| 160 | 'end_date' => $end_date, |
| 161 | 'period_text' => $this->get_period_text($date_range, $start_date, $end_date) |
| 162 | ], |
| 163 | 'overview' => [ |
| 164 | 'total_views' => $analytics_data['total_views'] ?? 0, |
| 165 | 'total_impressions' => $analytics_data['total_impressions'] ?? 0, |
| 166 | 'total_clicks' => $analytics_data['total_clicks'] ?? 0, |
| 167 | 'unique_viewers' => $analytics_data['unique_viewers'] ?? 0, |
| 168 | 'avg_engagement_time' => $analytics_data['avg_engagement_time'] ?? 0, |
| 169 | 'bounce_rate' => $analytics_data['bounce_rate'] ?? 0 |
| 170 | ], |
| 171 | 'content_analytics' => $this->format_content_analytics($content_analytics), |
| 172 | 'charts_data' => [ |
| 173 | 'views_over_time' => $analytics_data['views_chart'] ?? [], |
| 174 | 'top_content' => array_slice($content_analytics, 0, 10), |
| 175 | 'browser_stats' => $analytics_data['browser_stats'] ?? [], |
| 176 | 'device_stats' => $analytics_data['device_stats'] ?? [], |
| 177 | 'geo_stats' => $analytics_data['geo_stats'] ?? [] |
| 178 | ] |
| 179 | ]; |
| 180 | } |
| 181 | |
| 182 | /** |
| 183 | * Format content analytics for PDF export |
| 184 | * |
| 185 | * @param array $content_analytics |
| 186 | * @return array |
| 187 | */ |
| 188 | private function format_content_analytics($content_analytics) |
| 189 | { |
| 190 | $formatted = []; |
| 191 | |
| 192 | foreach ($content_analytics as $content) { |
| 193 | $formatted[] = [ |
| 194 | 'title' => $content['title'] ?? 'Untitled', |
| 195 | 'type' => $content['embed_type'] ?? 'Unknown', |
| 196 | 'views' => $content['views'] ?? 0, |
| 197 | 'impressions' => $content['impressions'] ?? 0, |
| 198 | 'clicks' => $content['clicks'] ?? 0, |
| 199 | 'engagement_rate' => $content['engagement_rate'] ?? 0, |
| 200 | 'url' => $content['url'] ?? '' |
| 201 | ]; |
| 202 | } |
| 203 | |
| 204 | return $formatted; |
| 205 | } |
| 206 | |
| 207 | /** |
| 208 | * Get human readable period text |
| 209 | * |
| 210 | * @param int $date_range |
| 211 | * @param string $start_date |
| 212 | * @param string $end_date |
| 213 | * @return string |
| 214 | */ |
| 215 | private function get_period_text($date_range, $start_date, $end_date) |
| 216 | { |
| 217 | if ($start_date && $end_date) { |
| 218 | return sprintf('%s to %s', |
| 219 | date('M j, Y', strtotime($start_date)), |
| 220 | date('M j, Y', strtotime($end_date)) |
| 221 | ); |
| 222 | } |
| 223 | |
| 224 | return sprintf('Last %d days', $date_range); |
| 225 | } |
| 226 | |
| 227 | /** |
| 228 | * Generate CSV content |
| 229 | * |
| 230 | * @param array $analytics_data |
| 231 | * @param array $content_analytics |
| 232 | * @param array $args |
| 233 | * @return string |
| 234 | */ |
| 235 | private function generate_csv_content($analytics_data, $content_analytics, $args) |
| 236 | { |
| 237 | $csv_lines = []; |
| 238 | |
| 239 | // Add header |
| 240 | $csv_lines[] = '"EmbedPress Analytics Export"'; |
| 241 | $csv_lines[] = '"Generated on: ' . date('Y-m-d H:i:s') . '"'; |
| 242 | $csv_lines[] = '"Date Range: ' . ($args['date_range'] ?? 30) . ' days"'; |
| 243 | $csv_lines[] = ''; |
| 244 | |
| 245 | // Overview section |
| 246 | $csv_lines[] = '"OVERVIEW METRICS"'; |
| 247 | $csv_lines[] = '"Metric","Value"'; |
| 248 | $csv_lines[] = sprintf('"Total Views","%s"', $analytics_data['views_analytics']['total_views'] ?? 0); |
| 249 | $csv_lines[] = sprintf('"Total Clicks","%s"', $analytics_data['total_clicks'] ?? 0); |
| 250 | $csv_lines[] = sprintf('"Total Impressions","%s"', $analytics_data['total_impressions'] ?? 0); |
| 251 | $csv_lines[] = sprintf('"Unique Viewers","%s"', $analytics_data['total_unique_viewers'] ?? 0); |
| 252 | $csv_lines[] = ''; |
| 253 | |
| 254 | // Content by type section |
| 255 | if (!empty($analytics_data['content_by_type'])) { |
| 256 | $csv_lines[] = '"CONTENT BY TYPE"'; |
| 257 | $csv_lines[] = '"Content Type","Count"'; |
| 258 | foreach ($analytics_data['content_by_type'] as $type => $count) { |
| 259 | $csv_lines[] = sprintf('"%s","%s"', ucfirst($type), $count); |
| 260 | } |
| 261 | $csv_lines[] = ''; |
| 262 | } |
| 263 | |
| 264 | // Daily views section |
| 265 | if (!empty($analytics_data['views_analytics']['daily_views'])) { |
| 266 | $csv_lines[] = '"DAILY VIEWS"'; |
| 267 | $csv_lines[] = '"Date","Views","Clicks","Impressions"'; |
| 268 | foreach ($analytics_data['views_analytics']['daily_views'] as $daily) { |
| 269 | $csv_lines[] = sprintf( |
| 270 | '"%s","%s","%s","%s"', |
| 271 | $daily['date'] ?? '', |
| 272 | $daily['views'] ?? 0, |
| 273 | $daily['clicks'] ?? 0, |
| 274 | $daily['impressions'] ?? 0 |
| 275 | ); |
| 276 | } |
| 277 | $csv_lines[] = ''; |
| 278 | } |
| 279 | |
| 280 | // Device analytics section |
| 281 | if (!empty($analytics_data['device_analytics'])) { |
| 282 | $csv_lines[] = '"DEVICE ANALYTICS"'; |
| 283 | $csv_lines[] = '"Device Type","Count"'; |
| 284 | foreach ($analytics_data['device_analytics']['devices'] ?? [] as $device) { |
| 285 | $csv_lines[] = sprintf('"%s","%s"', $device['device_type'] ?? '', $device['count'] ?? 0); |
| 286 | } |
| 287 | $csv_lines[] = ''; |
| 288 | |
| 289 | if (!empty($analytics_data['device_analytics']['browsers'])) { |
| 290 | $csv_lines[] = '"BROWSER ANALYTICS"'; |
| 291 | $csv_lines[] = '"Browser","Count"'; |
| 292 | foreach ($analytics_data['device_analytics']['browsers'] as $browser) { |
| 293 | $csv_lines[] = sprintf('"%s","%s"', $browser['browser'] ?? '', $browser['count'] ?? 0); |
| 294 | } |
| 295 | $csv_lines[] = ''; |
| 296 | } |
| 297 | } |
| 298 | |
| 299 | // Geo analytics section (Pro feature) |
| 300 | if (!empty($analytics_data['geo_analytics'])) { |
| 301 | $csv_lines[] = '"GEO ANALYTICS"'; |
| 302 | $csv_lines[] = '"Country","City","Count"'; |
| 303 | foreach ($analytics_data['geo_analytics'] as $geo) { |
| 304 | $csv_lines[] = sprintf( |
| 305 | '"%s","%s","%s"', |
| 306 | $geo['country'] ?? '', |
| 307 | $geo['city'] ?? '', |
| 308 | $geo['count'] ?? 0 |
| 309 | ); |
| 310 | } |
| 311 | $csv_lines[] = ''; |
| 312 | } |
| 313 | |
| 314 | // Referral analytics section (Pro feature) |
| 315 | if (!empty($analytics_data['referral_analytics'])) { |
| 316 | $csv_lines[] = '"REFERRAL ANALYTICS"'; |
| 317 | $csv_lines[] = '"Referrer","Count"'; |
| 318 | foreach ($analytics_data['referral_analytics'] as $referral) { |
| 319 | $csv_lines[] = sprintf('"%s","%s"', $referral['referrer'] ?? '', $referral['count'] ?? 0); |
| 320 | } |
| 321 | $csv_lines[] = ''; |
| 322 | } |
| 323 | |
| 324 | // Content analytics section |
| 325 | if (!empty($content_analytics)) { |
| 326 | $csv_lines[] = '"DETAILED CONTENT ANALYTICS"'; |
| 327 | $csv_lines[] = '"Page Title","Content ID","Source","Views","Clicks","Impressions","Page URL","Created Date"'; |
| 328 | |
| 329 | foreach ($content_analytics as $content) { |
| 330 | $csv_lines[] = sprintf( |
| 331 | '"%s","%s","%s","%s","%s","%s","%s","%s"', |
| 332 | str_replace('"', '""', $content['title'] ?? ''), |
| 333 | $content['content_id'] ?? '', |
| 334 | $content['embed_type'] ?? '', |
| 335 | $content['total_views'] ?? 0, |
| 336 | $content['total_clicks'] ?? 0, |
| 337 | $content['total_impressions'] ?? 0, |
| 338 | str_replace('"', '""', $content['page_url'] ?? ''), |
| 339 | $content['created_at'] ?? '' |
| 340 | ); |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | return implode("\r\n", $csv_lines); |
| 345 | } |
| 346 | |
| 347 | /** |
| 348 | * Generate HTML report content |
| 349 | * |
| 350 | * @param array $analytics_data |
| 351 | * @param array $content_analytics |
| 352 | * @param array $args |
| 353 | * @return string |
| 354 | */ |
| 355 | private function generate_html_report($analytics_data, $content_analytics, $args) |
| 356 | { |
| 357 | $html = '<!DOCTYPE html> |
| 358 | <html lang="en"> |
| 359 | <head> |
| 360 | <meta charset="UTF-8"> |
| 361 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 362 | <title>EmbedPress Analytics Report</title> |
| 363 | <style> |
| 364 | body { font-family: Arial, sans-serif; margin: 20px; line-height: 1.6; color: #333; } |
| 365 | .header { text-align: center; border-bottom: 2px solid #5b4e96; padding-bottom: 20px; margin-bottom: 30px; } |
| 366 | .header h1 { color: #5b4e96; margin: 0; } |
| 367 | .section { margin-bottom: 30px; } |
| 368 | .section h2 { color: #5b4e96; border-bottom: 1px solid #ddd; padding-bottom: 5px; } |
| 369 | .metrics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin: 20px 0; } |
| 370 | .metric-card { background: #f8f9fa; padding: 15px; border-radius: 5px; text-align: center; } |
| 371 | .metric-value { font-size: 24px; font-weight: bold; color: #5b4e96; } |
| 372 | .metric-label { font-size: 14px; color: #666; } |
| 373 | table { width: 100%; border-collapse: collapse; margin: 15px 0; } |
| 374 | th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } |
| 375 | th { background-color: #5b4e96; color: white; } |
| 376 | tr:nth-child(even) { background-color: #f2f2f2; } |
| 377 | .footer { margin-top: 40px; text-align: center; color: #666; font-size: 12px; } |
| 378 | @media print { body { margin: 0; } } |
| 379 | </style> |
| 380 | </head> |
| 381 | <body> |
| 382 | <div class="header"> |
| 383 | <h1>EmbedPress Analytics Report</h1> |
| 384 | <p>Generated on: ' . date('F j, Y \a\t g:i A') . '</p> |
| 385 | <p>Date Range: ' . ($args['date_range'] ?? 30) . ' days</p> |
| 386 | </div>'; |
| 387 | |
| 388 | // Overview metrics |
| 389 | $html .= '<div class="section"> |
| 390 | <h2>Overview Metrics</h2> |
| 391 | <div class="metrics-grid"> |
| 392 | <div class="metric-card"> |
| 393 | <div class="metric-value">' . number_format($analytics_data['views_analytics']['total_views'] ?? 0) . '</div> |
| 394 | <div class="metric-label">Total Views</div> |
| 395 | </div> |
| 396 | <div class="metric-card"> |
| 397 | <div class="metric-value">' . number_format($analytics_data['total_clicks'] ?? 0) . '</div> |
| 398 | <div class="metric-label">Total Clicks</div> |
| 399 | </div> |
| 400 | <div class="metric-card"> |
| 401 | <div class="metric-value">' . number_format($analytics_data['total_impressions'] ?? 0) . '</div> |
| 402 | <div class="metric-label">Total Impressions</div> |
| 403 | </div> |
| 404 | <div class="metric-card"> |
| 405 | <div class="metric-value">' . number_format($analytics_data['total_unique_viewers'] ?? 0) . '</div> |
| 406 | <div class="metric-label">Unique Viewers</div> |
| 407 | </div> |
| 408 | </div> |
| 409 | </div>'; |
| 410 | |
| 411 | // Content by type |
| 412 | if (!empty($analytics_data['content_by_type'])) { |
| 413 | $html .= '<div class="section"> |
| 414 | <h2>Content by Type</h2> |
| 415 | <table> |
| 416 | <thead> |
| 417 | <tr><th>Content Type</th><th>Count</th></tr> |
| 418 | </thead> |
| 419 | <tbody>'; |
| 420 | foreach ($analytics_data['content_by_type'] as $type => $count) { |
| 421 | $html .= '<tr><td>' . ucfirst($type) . '</td><td>' . number_format($count) . '</td></tr>'; |
| 422 | } |
| 423 | $html .= '</tbody></table></div>'; |
| 424 | } |
| 425 | |
| 426 | // Content analytics |
| 427 | if (!empty($content_analytics)) { |
| 428 | $html .= '<div class="section"> |
| 429 | <h2>Top Content Analytics</h2> |
| 430 | <table> |
| 431 | <thead> |
| 432 | <tr><th>Title</th><th>Source</th><th>Views</th><th>Clicks</th><th>Impressions</th></tr> |
| 433 | </thead> |
| 434 | <tbody>'; |
| 435 | $count = 0; |
| 436 | foreach ($content_analytics as $item) { |
| 437 | if ($count >= 20) break; |
| 438 | $html .= '<tr> |
| 439 | <td>' . htmlspecialchars($item['title'] ?? $item['content_id'] ?? 'N/A') . '</td> |
| 440 | <td>' . htmlspecialchars($item['embed_type'] ?? 'N/A') . '</td> |
| 441 | <td>' . number_format($item['total_views'] ?? 0) . '</td> |
| 442 | <td>' . number_format($item['total_clicks'] ?? 0) . '</td> |
| 443 | <td>' . number_format($item['total_impressions'] ?? 0) . '</td> |
| 444 | </tr>'; |
| 445 | $count++; |
| 446 | } |
| 447 | $html .= '</tbody></table></div>'; |
| 448 | } |
| 449 | |
| 450 | $html .= '<div class="footer"> |
| 451 | <p>Report generated by EmbedPress</p> |
| 452 | <p>For more detailed analytics, visit your WordPress admin dashboard.</p> |
| 453 | </div> |
| 454 | </body> |
| 455 | </html>'; |
| 456 | |
| 457 | return $html; |
| 458 | } |
| 459 | |
| 460 | /** |
| 461 | * Generate text report content (legacy) |
| 462 | * |
| 463 | * @param array $analytics_data |
| 464 | * @param array $content_analytics |
| 465 | * @param array $args |
| 466 | * @return string |
| 467 | */ |
| 468 | private function generate_text_report($analytics_data, $content_analytics, $args) |
| 469 | { |
| 470 | $content = "EmbedPress Analytics Report\n"; |
| 471 | $content .= "===========================\n\n"; |
| 472 | $content .= "Generated on: " . date('Y-m-d H:i:s') . "\n"; |
| 473 | $content .= "Date Range: " . ($args['date_range'] ?? 30) . " days\n\n"; |
| 474 | |
| 475 | // Overview section |
| 476 | $content .= "OVERVIEW METRICS\n"; |
| 477 | $content .= "================\n"; |
| 478 | $content .= "Total Views: " . number_format($analytics_data['views_analytics']['total_views'] ?? 0) . "\n"; |
| 479 | $content .= "Total Clicks: " . number_format($analytics_data['total_clicks'] ?? 0) . "\n"; |
| 480 | $content .= "Total Impressions: " . number_format($analytics_data['total_impressions'] ?? 0) . "\n"; |
| 481 | $content .= "Unique Viewers: " . number_format($analytics_data['total_unique_viewers'] ?? 0) . "\n\n"; |
| 482 | |
| 483 | // Content by type |
| 484 | if (!empty($analytics_data['content_by_type'])) { |
| 485 | $content .= "CONTENT BY TYPE\n"; |
| 486 | $content .= "===============\n"; |
| 487 | foreach ($analytics_data['content_by_type'] as $type => $count) { |
| 488 | $content .= ucfirst($type) . ": " . number_format($count) . "\n"; |
| 489 | } |
| 490 | $content .= "\n"; |
| 491 | } |
| 492 | |
| 493 | // Device analytics |
| 494 | if (!empty($analytics_data['device_analytics']['devices'])) { |
| 495 | $content .= "DEVICE ANALYTICS\n"; |
| 496 | $content .= "================\n"; |
| 497 | foreach ($analytics_data['device_analytics']['devices'] as $device) { |
| 498 | $content .= ($device['device_type'] ?? 'Unknown') . ": " . number_format($device['count'] ?? 0) . "\n"; |
| 499 | } |
| 500 | $content .= "\n"; |
| 501 | } |
| 502 | |
| 503 | // Content analytics (limited for readability) |
| 504 | if (!empty($content_analytics)) { |
| 505 | $content .= "TOP CONTENT ANALYTICS\n"; |
| 506 | $content .= "=====================\n"; |
| 507 | $count = 0; |
| 508 | foreach ($content_analytics as $item) { |
| 509 | if ($count >= 20) break; // Limit for readability |
| 510 | $content .= "Title: " . ($item['title'] ?? $item['content_id'] ?? 'N/A') . "\n"; |
| 511 | $content .= "Source: " . ($item['embed_type'] ?? 'N/A') . "\n"; |
| 512 | $content .= "Views: " . number_format($item['total_views'] ?? 0) . "\n"; |
| 513 | $content .= "Clicks: " . number_format($item['total_clicks'] ?? 0) . "\n"; |
| 514 | $content .= "Impressions: " . number_format($item['total_impressions'] ?? 0) . "\n"; |
| 515 | $content .= "----------------------------------------\n"; |
| 516 | $count++; |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | $content .= "\nReport generated by EmbedPress Analytics\n"; |
| 521 | $content .= "For more detailed analytics, visit your WordPress admin dashboard.\n"; |
| 522 | |
| 523 | return $content; |
| 524 | } |
| 525 | |
| 526 | /** |
| 527 | * Generate simple PDF content (legacy) |
| 528 | * |
| 529 | * @param array $analytics_data |
| 530 | * @param array $content_analytics |
| 531 | * @param array $args |
| 532 | * @return string |
| 533 | */ |
| 534 | private function generate_simple_pdf($analytics_data, $content_analytics, $args) |
| 535 | { |
| 536 | // Create a basic PDF structure |
| 537 | $pdf_content = "%PDF-1.4\n"; |
| 538 | $pdf_content .= "1 0 obj\n"; |
| 539 | $pdf_content .= "<<\n"; |
| 540 | $pdf_content .= "/Type /Catalog\n"; |
| 541 | $pdf_content .= "/Pages 2 0 R\n"; |
| 542 | $pdf_content .= ">>\n"; |
| 543 | $pdf_content .= "endobj\n\n"; |
| 544 | |
| 545 | $pdf_content .= "2 0 obj\n"; |
| 546 | $pdf_content .= "<<\n"; |
| 547 | $pdf_content .= "/Type /Pages\n"; |
| 548 | $pdf_content .= "/Kids [3 0 R]\n"; |
| 549 | $pdf_content .= "/Count 1\n"; |
| 550 | $pdf_content .= ">>\n"; |
| 551 | $pdf_content .= "endobj\n\n"; |
| 552 | |
| 553 | // Create content text |
| 554 | $text_content = "EmbedPress Analytics Report\\n"; |
| 555 | $text_content .= "Generated on: " . date('Y-m-d H:i:s') . "\\n"; |
| 556 | $text_content .= "Date Range: " . ($args['date_range'] ?? 30) . " days\\n\\n"; |
| 557 | |
| 558 | // Overview section |
| 559 | $text_content .= "OVERVIEW METRICS\\n"; |
| 560 | $text_content .= "================\\n"; |
| 561 | $text_content .= "Total Views: " . ($analytics_data['views_analytics']['total_views'] ?? 0) . "\\n"; |
| 562 | $text_content .= "Total Clicks: " . ($analytics_data['total_clicks'] ?? 0) . "\\n"; |
| 563 | $text_content .= "Total Impressions: " . ($analytics_data['total_impressions'] ?? 0) . "\\n"; |
| 564 | $text_content .= "Unique Viewers: " . ($analytics_data['total_unique_viewers'] ?? 0) . "\\n\\n"; |
| 565 | |
| 566 | // Content by type |
| 567 | if (!empty($analytics_data['content_by_type'])) { |
| 568 | $text_content .= "CONTENT BY TYPE\\n"; |
| 569 | $text_content .= "===============\\n"; |
| 570 | foreach ($analytics_data['content_by_type'] as $type => $count) { |
| 571 | $text_content .= ucfirst($type) . ": " . $count . "\\n"; |
| 572 | } |
| 573 | $text_content .= "\\n"; |
| 574 | } |
| 575 | |
| 576 | // Content analytics |
| 577 | if (!empty($content_analytics)) { |
| 578 | $text_content .= "DETAILED CONTENT ANALYTICS\\n"; |
| 579 | $text_content .= "==========================\\n"; |
| 580 | $count = 0; |
| 581 | foreach ($content_analytics as $item) { |
| 582 | if ($count >= 10) break; // Limit for PDF |
| 583 | $text_content .= "Title: " . ($item['title'] ?? $item['content_id'] ?? 'N/A') . "\\n"; |
| 584 | $text_content .= "Source: " . ($item['embed_type'] ?? 'N/A') . "\\n"; |
| 585 | $text_content .= "Views: " . ($item['total_views'] ?? 0) . "\\n"; |
| 586 | $text_content .= "---\\n"; |
| 587 | $count++; |
| 588 | } |
| 589 | } |
| 590 | |
| 591 | $content_length = strlen($text_content); |
| 592 | |
| 593 | $pdf_content .= "3 0 obj\n"; |
| 594 | $pdf_content .= "<<\n"; |
| 595 | $pdf_content .= "/Type /Page\n"; |
| 596 | $pdf_content .= "/Parent 2 0 R\n"; |
| 597 | $pdf_content .= "/MediaBox [0 0 612 792]\n"; |
| 598 | $pdf_content .= "/Contents 4 0 R\n"; |
| 599 | $pdf_content .= "/Resources <<\n"; |
| 600 | $pdf_content .= "/Font <<\n"; |
| 601 | $pdf_content .= "/F1 <<\n"; |
| 602 | $pdf_content .= "/Type /Font\n"; |
| 603 | $pdf_content .= "/Subtype /Type1\n"; |
| 604 | $pdf_content .= "/BaseFont /Helvetica\n"; |
| 605 | $pdf_content .= ">>\n"; |
| 606 | $pdf_content .= ">>\n"; |
| 607 | $pdf_content .= ">>\n"; |
| 608 | $pdf_content .= ">>\n"; |
| 609 | $pdf_content .= "endobj\n\n"; |
| 610 | |
| 611 | $pdf_content .= "4 0 obj\n"; |
| 612 | $pdf_content .= "<<\n"; |
| 613 | $pdf_content .= "/Length " . ($content_length + 50) . "\n"; |
| 614 | $pdf_content .= ">>\n"; |
| 615 | $pdf_content .= "stream\n"; |
| 616 | $pdf_content .= "BT\n"; |
| 617 | $pdf_content .= "/F1 12 Tf\n"; |
| 618 | $pdf_content .= "50 750 Td\n"; |
| 619 | $pdf_content .= "(" . $text_content . ") Tj\n"; |
| 620 | $pdf_content .= "ET\n"; |
| 621 | $pdf_content .= "endstream\n"; |
| 622 | $pdf_content .= "endobj\n\n"; |
| 623 | |
| 624 | $pdf_content .= "xref\n"; |
| 625 | $pdf_content .= "0 5\n"; |
| 626 | $pdf_content .= "0000000000 65535 f \n"; |
| 627 | $pdf_content .= "0000000009 00000 n \n"; |
| 628 | $pdf_content .= "0000000074 00000 n \n"; |
| 629 | $pdf_content .= "0000000131 00000 n \n"; |
| 630 | $pdf_content .= "0000000380 00000 n \n"; |
| 631 | $pdf_content .= "trailer\n"; |
| 632 | $pdf_content .= "<<\n"; |
| 633 | $pdf_content .= "/Size 5\n"; |
| 634 | $pdf_content .= "/Root 1 0 R\n"; |
| 635 | $pdf_content .= ">>\n"; |
| 636 | $pdf_content .= "startxref\n"; |
| 637 | $pdf_content .= "500\n"; |
| 638 | $pdf_content .= "%%EOF\n"; |
| 639 | |
| 640 | return $pdf_content; |
| 641 | } |
| 642 | |
| 643 | /** |
| 644 | * Generate PDF HTML content (legacy method) |
| 645 | * |
| 646 | * @param array $analytics_data |
| 647 | * @param array $content_analytics |
| 648 | * @param array $args |
| 649 | * @return string |
| 650 | */ |
| 651 | private function generate_pdf_html($analytics_data, $content_analytics, $args) |
| 652 | { |
| 653 | $html = '<!DOCTYPE html><html><head>'; |
| 654 | $html .= '<title>EmbedPress Analytics Report</title>'; |
| 655 | $html .= '<style>body{font-family:Arial,sans-serif;margin:20px;}table{border-collapse:collapse;width:100%;}th,td{border:1px solid #ddd;padding:8px;text-align:left;}th{background-color:#f2f2f2;}</style>'; |
| 656 | $html .= '</head><body>'; |
| 657 | |
| 658 | $html .= '<h1>EmbedPress Analytics Report</h1>'; |
| 659 | $html .= '<p>Generated on: ' . date('Y-m-d H:i:s') . '</p>'; |
| 660 | $html .= '<p>Date Range: ' . ($args['date_range'] ?? 30) . ' days</p>'; |
| 661 | |
| 662 | // Overview section |
| 663 | $html .= '<h2>Overview</h2>'; |
| 664 | $html .= '<table>'; |
| 665 | $html .= '<tr><th>Metric</th><th>Value</th></tr>'; |
| 666 | $html .= '<tr><td>Total Views</td><td>' . ($analytics_data['views_analytics']['total_views'] ?? 0) . '</td></tr>'; |
| 667 | $html .= '<tr><td>Total Clicks</td><td>' . ($analytics_data['total_clicks'] ?? 0) . '</td></tr>'; |
| 668 | $html .= '<tr><td>Total Impressions</td><td>' . ($analytics_data['total_impressions'] ?? 0) . '</td></tr>'; |
| 669 | $html .= '<tr><td>Unique Viewers</td><td>' . ($analytics_data['total_unique_viewers'] ?? 0) . '</td></tr>'; |
| 670 | $html .= '</table>'; |
| 671 | |
| 672 | // Content analytics section |
| 673 | if (!empty($content_analytics)) { |
| 674 | $html .= '<h2>Content Analytics</h2>'; |
| 675 | $html .= '<table>'; |
| 676 | $html .= '<tr><th>Page Title</th><th>Source</th><th>Views</th><th>Clicks</th><th>Impressions</th></tr>'; |
| 677 | |
| 678 | foreach ($content_analytics as $content) { |
| 679 | $html .= '<tr>'; |
| 680 | $html .= '<td>' . htmlspecialchars($content['title'] ?? $content['content_id'] ?? '') . '</td>'; |
| 681 | $html .= '<td>' . htmlspecialchars($content['embed_type'] ?? '') . '</td>'; |
| 682 | $html .= '<td>' . ($content['total_views'] ?? 0) . '</td>'; |
| 683 | $html .= '<td>' . ($content['total_clicks'] ?? 0) . '</td>'; |
| 684 | $html .= '<td>' . ($content['total_impressions'] ?? 0) . '</td>'; |
| 685 | $html .= '</tr>'; |
| 686 | } |
| 687 | $html .= '</table>'; |
| 688 | } |
| 689 | |
| 690 | $html .= '</body></html>'; |
| 691 | return $html; |
| 692 | } |
| 693 | |
| 694 | /** |
| 695 | * Generate filename for export |
| 696 | * |
| 697 | * @param string $extension |
| 698 | * @param array $args |
| 699 | * @return string |
| 700 | */ |
| 701 | private function generate_filename($extension, $args) |
| 702 | { |
| 703 | $date = date('Y-m-d'); |
| 704 | $time = date('H-i-s'); |
| 705 | return "embedpress-analytics-{$date}-{$time}.{$extension}"; |
| 706 | } |
| 707 | |
| 708 | /** |
| 709 | * Get export directory path |
| 710 | * |
| 711 | * @return string |
| 712 | */ |
| 713 | private function get_export_directory() |
| 714 | { |
| 715 | $upload_dir = wp_upload_dir(); |
| 716 | $export_dir = $upload_dir['basedir'] . '/embedpress-exports/'; |
| 717 | |
| 718 | if (!file_exists($export_dir)) { |
| 719 | wp_mkdir_p($export_dir); |
| 720 | } |
| 721 | |
| 722 | return $export_dir; |
| 723 | } |
| 724 | |
| 725 | /** |
| 726 | * Get download URL for exported file |
| 727 | * |
| 728 | * @param string $filename |
| 729 | * @return string |
| 730 | */ |
| 731 | private function get_download_url($filename) |
| 732 | { |
| 733 | $upload_dir = wp_upload_dir(); |
| 734 | return $upload_dir['baseurl'] . '/embedpress-exports/' . $filename; |
| 735 | } |
| 736 | } |
| 737 |