Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
CommentAnalysisJob
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 4
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getJobType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
20
 updateCommentStatus
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2declare(strict_types=1);
3
4namespace App\Job;
5
6use App\Model\Entity\Comment;
7use App\Service\Api\AiService;
8use Cake\Queue\Job\Message;
9use Interop\Queue\Processor;
10
11/**
12 * CommentAnalysisJob Class
13 *
14 * This job is responsible for analyzing comments using AI.
15 * It processes comments from the queue, performs analysis, and updates the comment status
16 * based on the analysis results.
17 */
18class CommentAnalysisJob extends AbstractJob
19{
20    /**
21     * Instance of the AI service.
22     *
23     * @var \App\Service\Api\AiService
24     */
25    private AiService $aiService;
26
27    /**
28     * Constructor to allow dependency injection for testing
29     *
30     * @param \App\Service\Api\AiService|null $aiService
31     */
32    public function __construct(?AiService $aiService = null)
33    {
34        $this->aiService = $aiService ?? new AiService();
35    }
36
37    /**
38     * Get the human-readable job type name for logging
39     *
40     * @return string The job type description
41     */
42    protected static function getJobType(): string
43    {
44        return 'comment analysis';
45    }
46
47    /**
48     * Executes the comment analysis job.
49     *
50     * This method performs comment analysis using AI,
51     * updating the comment status based on the analysis results.
52     *
53     * @param \Cake\Queue\Job\Message $message The message containing job data.
54     * @return string|null The processor status (ACK or REJECT).
55     */
56    public function execute(Message $message): ?string
57    {
58        if (!$this->validateArguments($message, ['comment_id', 'content', 'user_id'])) {
59            return Processor::REJECT;
60        }
61
62        $commentId = $message->getArgument('comment_id');
63        $content = $message->getArgument('content');
64        $userId = $message->getArgument('user_id');
65
66        $commentsTable = $this->getTable('Comments');
67        $comment = $commentsTable->get($commentId);
68
69        if ($comment->is_analyzed) {
70            $this->log(
71                sprintf('Comment already analyzed. Skipping. Comment ID: %s', $commentId),
72                'info',
73                ['group_name' => static::class],
74            );
75
76            return Processor::ACK;
77        }
78
79        return $this->executeWithErrorHandling($commentId, function () use ($comment, $content) {
80            $analysisResult = $this->aiService->analyzeComment($content);
81
82            if ($analysisResult) {
83                $this->updateCommentStatus($comment, $analysisResult);
84
85                return true;
86            }
87
88            return false;
89        }, "User ID: {$userId}");
90    }
91
92    /**
93     * Updates the comment status based on the analysis result.
94     *
95     * This method extracts the inappropriateness status and reason from the analysis result
96     * and updates the comment entity with the analysis results.
97     *
98     * @param \App\Model\Entity\Comment $comment The comment entity to update.
99     * @param array $analysisResult The result of the comment analysis.
100     * @return void
101     */
102    private function updateCommentStatus(Comment $comment, array $analysisResult): void
103    {
104        $isInappropriate = $analysisResult['is_inappropriate'] ?? false;
105        $reason = $analysisResult['reason'] ?? [];
106
107        $comment->setAccess('is_inappropriate', true);
108        $comment->is_analyzed = true;
109        $comment->display = !$isInappropriate;
110        $comment->is_inappropriate = $isInappropriate;
111        $comment->inappropriate_reason = $isInappropriate ? json_encode($reason) : null;
112
113        $commentsTable = $this->getTable('Comments');
114        $commentsTable->save($comment);
115    }
116}