Files
tinker_tickets/cron/create_recurring_tickets.php

136 lines
4.0 KiB
PHP
Raw Permalink Normal View History

Implement comprehensive improvement plan (Phases 1-6) Security (Phase 1-2): - Add SecurityHeadersMiddleware with CSP, X-Frame-Options, etc. - Add RateLimitMiddleware for API rate limiting - Add security event logging to AuditLogModel - Add ResponseHelper for standardized API responses - Update config.php with security constants Database (Phase 3): - Add migration 014 for additional indexes - Add migration 015 for ticket dependencies - Add migration 016 for ticket attachments - Add migration 017 for recurring tickets - Add migration 018 for custom fields Features (Phase 4-5): - Add ticket dependencies with DependencyModel and API - Add duplicate detection with check_duplicates API - Add file attachments with AttachmentModel and upload/download APIs - Add @mentions with autocomplete and highlighting - Add quick actions on dashboard rows Collaboration (Phase 5): - Add mention extraction in CommentModel - Add mention autocomplete dropdown in ticket.js - Add mention highlighting CSS styles Admin & Export (Phase 6): - Add StatsModel for dashboard widgets - Add dashboard stats cards (open, critical, unassigned, etc.) - Add CSV/JSON export via export_tickets API - Add rich text editor toolbar in markdown.js - Add RecurringTicketModel with cron job - Add CustomFieldModel for per-category fields - Add admin views: RecurringTickets, CustomFields, Workflow, Templates, AuditLog, UserActivity - Add admin APIs: manage_workflows, manage_templates, manage_recurring, custom_fields, get_users - Add admin routes in index.php Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 09:55:01 -05:00
#!/usr/bin/env php
<?php
/**
* Recurring Tickets Cron Job
*
* Run this script via cron to automatically create tickets from recurring schedules.
* Recommended: Run every 5-15 minutes
*
* Example crontab entry:
* */10 * * * * /usr/bin/php /path/to/cron/create_recurring_tickets.php >> /var/log/recurring_tickets.log 2>&1
*/
// Change to project root directory
chdir(dirname(__DIR__));
// Include required files
require_once 'config/config.php';
require_once 'models/RecurringTicketModel.php';
require_once 'models/TicketModel.php';
require_once 'models/AuditLogModel.php';
// Log function
function logMessage($message) {
echo "[" . date('Y-m-d H:i:s') . "] " . $message . "\n";
}
logMessage("Starting recurring tickets cron job");
try {
// Create database connection
$conn = new mysqli(
$GLOBALS['config']['DB_HOST'],
$GLOBALS['config']['DB_USER'],
$GLOBALS['config']['DB_PASS'],
$GLOBALS['config']['DB_NAME']
);
if ($conn->connect_error) {
throw new Exception("Database connection failed: " . $conn->connect_error);
}
// Initialize models
$recurringModel = new RecurringTicketModel($conn);
$ticketModel = new TicketModel($conn);
$auditLog = new AuditLogModel($conn);
// Get all due recurring tickets
$dueTickets = $recurringModel->getDueRecurringTickets();
logMessage("Found " . count($dueTickets) . " recurring tickets due for creation");
$created = 0;
$errors = 0;
foreach ($dueTickets as $recurring) {
logMessage("Processing recurring ticket ID: " . $recurring['recurring_id']);
try {
// Prepare ticket data
$ticketData = [
'title' => processTemplate($recurring['title_template']),
'description' => processTemplate($recurring['description_template']),
'category' => $recurring['category'],
'type' => $recurring['type'],
'priority' => $recurring['priority'],
'status' => 'Open'
];
// Create the ticket
$result = $ticketModel->createTicket($ticketData, $recurring['created_by']);
if ($result['success']) {
$ticketId = $result['ticket_id'];
logMessage("Created ticket: " . $ticketId);
// Assign to user if specified
if ($recurring['assigned_to']) {
$ticketModel->assignTicket($ticketId, $recurring['assigned_to'], $recurring['created_by']);
Implement comprehensive improvement plan (Phases 1-6) Security (Phase 1-2): - Add SecurityHeadersMiddleware with CSP, X-Frame-Options, etc. - Add RateLimitMiddleware for API rate limiting - Add security event logging to AuditLogModel - Add ResponseHelper for standardized API responses - Update config.php with security constants Database (Phase 3): - Add migration 014 for additional indexes - Add migration 015 for ticket dependencies - Add migration 016 for ticket attachments - Add migration 017 for recurring tickets - Add migration 018 for custom fields Features (Phase 4-5): - Add ticket dependencies with DependencyModel and API - Add duplicate detection with check_duplicates API - Add file attachments with AttachmentModel and upload/download APIs - Add @mentions with autocomplete and highlighting - Add quick actions on dashboard rows Collaboration (Phase 5): - Add mention extraction in CommentModel - Add mention autocomplete dropdown in ticket.js - Add mention highlighting CSS styles Admin & Export (Phase 6): - Add StatsModel for dashboard widgets - Add dashboard stats cards (open, critical, unassigned, etc.) - Add CSV/JSON export via export_tickets API - Add rich text editor toolbar in markdown.js - Add RecurringTicketModel with cron job - Add CustomFieldModel for per-category fields - Add admin views: RecurringTickets, CustomFields, Workflow, Templates, AuditLog, UserActivity - Add admin APIs: manage_workflows, manage_templates, manage_recurring, custom_fields, get_users - Add admin routes in index.php Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 09:55:01 -05:00
}
// Log to audit
$auditLog->log(
$recurring['created_by'],
'create',
'ticket',
$ticketId,
['source' => 'recurring', 'recurring_id' => $recurring['recurring_id']]
);
// Update the recurring ticket's next run time
$recurringModel->updateAfterRun($recurring['recurring_id']);
$created++;
} else {
logMessage("ERROR: Failed to create ticket - " . ($result['error'] ?? 'Unknown error'));
$errors++;
}
} catch (Exception $e) {
logMessage("ERROR: Exception processing recurring ticket - " . $e->getMessage());
$errors++;
}
}
logMessage("Completed: Created $created tickets, $errors errors");
$conn->close();
} catch (Exception $e) {
logMessage("FATAL ERROR: " . $e->getMessage());
exit(1);
}
/**
* Process template variables
*/
function processTemplate($template) {
if (empty($template)) {
return $template;
}
$replacements = [
'{{date}}' => date('Y-m-d'),
'{{time}}' => date('H:i:s'),
'{{datetime}}' => date('Y-m-d H:i:s'),
'{{week}}' => date('W'),
'{{month}}' => date('F'),
'{{year}}' => date('Y'),
'{{day_of_week}}' => date('l'),
'{{day}}' => date('d'),
];
return str_replace(array_keys($replacements), array_values($replacements), $template);
}
logMessage("Cron job finished");