Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ArticleSummaryUpdateJob
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 3
56
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 / 19
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2declare(strict_types=1);
3
4namespace App\Job;
5
6use App\Service\Api\AiService;
7use Cake\Queue\Job\Message;
8use Interop\Queue\Processor;
9
10/**
11 * ArticleSummaryUpdateJob
12 *
13 * This job is responsible for generating and updating the summary of an article using AI.
14 * It processes messages from the queue to update the summary field of an article.
15 */
16class ArticleSummaryUpdateJob extends AbstractJob
17{
18    /**
19     * Instance of the AI service.
20     *
21     * @var \App\Service\Api\AiService
22     */
23    private AiService $aiService;
24
25    /**
26     * Constructor to allow dependency injection for testing
27     *
28     * @param \App\Service\Api\AiService|null $aiService
29     */
30    public function __construct(?AiService $aiService = null)
31    {
32        $this->aiService = $aiService ?? new AiService();
33    }
34
35    /**
36     * Get the human-readable job type name for logging
37     *
38     * @return string The job type description
39     */
40    protected static function getJobType(): string
41    {
42        return 'article summary update';
43    }
44
45    /**
46     * Executes the job to generate and update article summary.
47     *
48     * This method processes the message, retrieves the article, generates a summary
49     * using AI, and updates the article with the new summary.
50     *
51     * @param \Cake\Queue\Job\Message $message The message containing article data.
52     * @return string|null Returns Processor::ACK on success, Processor::REJECT on failure.
53     */
54    public function execute(Message $message): ?string
55    {
56        if (!$this->validateArguments($message, ['id', 'title'])) {
57            return Processor::REJECT;
58        }
59
60        $id = $message->getArgument('id');
61        $title = $message->getArgument('title');
62
63        $articlesTable = $this->getTable('Articles');
64        $article = $articlesTable->get($id);
65
66        return $this->executeWithErrorHandling($id, function () use ($article, $articlesTable) {
67            $summaryResult = $this->aiService->generateTextSummary(
68                'article',
69                (string)strip_tags($article->body),
70            );
71
72            if (isset($summaryResult['summary'])) {
73                if (empty($article->summary)) {
74                    $article->summary = $summaryResult['summary'];
75                }
76
77                if (empty($article->lede)) {
78                    $article->lede = $summaryResult['lede'];
79                }
80
81                return $articlesTable->save($article, ['noMessage' => true]);
82            }
83
84            return false;
85        }, $title);
86    }
87}