Skip to content

Commit be3be90

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 1aa0bef + 8cb828c commit be3be90

3 files changed

Lines changed: 414 additions & 0 deletions

File tree

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/* For licensing terms, see /license.txt */
6+
7+
namespace Chamilo\CoreBundle\Entity;
8+
9+
use DateTime;
10+
use Doctrine\Common\Collections\ArrayCollection;
11+
use Doctrine\Common\Collections\Collection;
12+
use Doctrine\ORM\Mapping as ORM;
13+
14+
#[ORM\Entity]
15+
#[ORM\Table(name: 'ai_tutor_conversation')]
16+
#[ORM\UniqueConstraint(name: 'uniq_ai_tutor_conv_user_course_provider', columns: ['user_id', 'course_id', 'ai_provider'])]
17+
#[ORM\Index(columns: ['user_id', 'course_id'], name: 'idx_ai_tutor_conv_user_course')]
18+
#[ORM\Index(columns: ['course_id'], name: 'idx_ai_tutor_conv_course')]
19+
#[ORM\Index(columns: ['last_message_at'], name: 'idx_ai_tutor_conv_last_message')]
20+
#[ORM\HasLifecycleCallbacks]
21+
class AiTutorConversation
22+
{
23+
#[ORM\Id]
24+
#[ORM\GeneratedValue]
25+
#[ORM\Column(name: 'id', type: 'integer')]
26+
protected ?int $id = null;
27+
28+
#[ORM\ManyToOne(targetEntity: User::class)]
29+
#[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
30+
protected User $user;
31+
32+
#[ORM\ManyToOne(targetEntity: Course::class)]
33+
#[ORM\JoinColumn(name: 'course_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
34+
protected Course $course;
35+
36+
#[ORM\ManyToOne(targetEntity: Session::class)]
37+
#[ORM\JoinColumn(name: 'session_id', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
38+
protected ?Session $session = null;
39+
40+
#[ORM\Column(name: 'ai_provider', type: 'string', length: 50, nullable: false)]
41+
protected string $aiProvider;
42+
43+
#[ORM\Column(name: 'provider_conversation_id', type: 'string', length: 255, nullable: true)]
44+
protected ?string $providerConversationId = null;
45+
46+
#[ORM\Column(name: 'created_at', type: 'datetime', nullable: false)]
47+
protected DateTime $createdAt;
48+
49+
#[ORM\Column(name: 'updated_at', type: 'datetime', nullable: false)]
50+
protected DateTime $updatedAt;
51+
52+
#[ORM\Column(name: 'last_message_at', type: 'datetime', nullable: true)]
53+
protected ?DateTime $lastMessageAt = null;
54+
55+
/**
56+
* @var Collection<int, AiTutorMessage>
57+
*/
58+
#[ORM\OneToMany(mappedBy: 'conversation', targetEntity: AiTutorMessage::class, cascade: ['persist'], orphanRemoval: true)]
59+
#[ORM\OrderBy(['createdAt' => 'ASC'])]
60+
protected Collection $messages;
61+
62+
public function __construct()
63+
{
64+
$this->messages = new ArrayCollection();
65+
$now = new DateTime();
66+
$this->createdAt = $now;
67+
$this->updatedAt = $now;
68+
}
69+
70+
#[ORM\PreUpdate]
71+
public function onPreUpdate(): void
72+
{
73+
$this->updatedAt = new DateTime();
74+
}
75+
76+
public function getId(): ?int
77+
{
78+
return $this->id;
79+
}
80+
81+
public function getUser(): User
82+
{
83+
return $this->user;
84+
}
85+
86+
public function setUser(User $user): self
87+
{
88+
$this->user = $user;
89+
90+
return $this;
91+
}
92+
93+
public function getCourse(): Course
94+
{
95+
return $this->course;
96+
}
97+
98+
public function setCourse(Course $course): self
99+
{
100+
$this->course = $course;
101+
102+
return $this;
103+
}
104+
105+
public function getSession(): ?Session
106+
{
107+
return $this->session;
108+
}
109+
110+
public function setSession(?Session $session): self
111+
{
112+
$this->session = $session;
113+
114+
return $this;
115+
}
116+
117+
public function getAiProvider(): string
118+
{
119+
return $this->aiProvider;
120+
}
121+
122+
public function setAiProvider(string $aiProvider): self
123+
{
124+
$this->aiProvider = $aiProvider;
125+
126+
return $this;
127+
}
128+
129+
public function getProviderConversationId(): ?string
130+
{
131+
return $this->providerConversationId;
132+
}
133+
134+
public function setProviderConversationId(?string $providerConversationId): self
135+
{
136+
$this->providerConversationId = $providerConversationId;
137+
138+
return $this;
139+
}
140+
141+
public function getCreatedAt(): DateTime
142+
{
143+
return $this->createdAt;
144+
}
145+
146+
public function getUpdatedAt(): DateTime
147+
{
148+
return $this->updatedAt;
149+
}
150+
151+
public function getLastMessageAt(): ?DateTime
152+
{
153+
return $this->lastMessageAt;
154+
}
155+
156+
public function setLastMessageAt(?DateTime $lastMessageAt): self
157+
{
158+
$this->lastMessageAt = $lastMessageAt;
159+
160+
return $this;
161+
}
162+
163+
public function touchLastMessageAt(): self
164+
{
165+
$now = new DateTime();
166+
$this->lastMessageAt = $now;
167+
$this->updatedAt = $now;
168+
169+
return $this;
170+
}
171+
172+
/**
173+
* @return Collection<int, AiTutorMessage>
174+
*/
175+
public function getMessages(): Collection
176+
{
177+
return $this->messages;
178+
}
179+
180+
public function addMessage(AiTutorMessage $message): self
181+
{
182+
if (!$this->messages->contains($message)) {
183+
$this->messages->add($message);
184+
$message->setConversation($this);
185+
$this->touchLastMessageAt();
186+
}
187+
188+
return $this;
189+
}
190+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/* For licensing terms, see /license.txt */
6+
7+
namespace Chamilo\CoreBundle\Entity;
8+
9+
use DateTime;
10+
use Doctrine\ORM\Mapping as ORM;
11+
12+
13+
#[ORM\Entity]
14+
#[ORM\Table(name: 'ai_tutor_message')]
15+
#[ORM\Index(columns: ['conversation_id', 'created_at'], name: 'idx_ai_tutor_msg_conv_created')]
16+
#[ORM\HasLifecycleCallbacks]
17+
class AiTutorMessage
18+
{
19+
#[ORM\Id]
20+
#[ORM\GeneratedValue]
21+
#[ORM\Column(name: 'id', type: 'integer')]
22+
protected ?int $id = null;
23+
24+
#[ORM\ManyToOne(targetEntity: AiTutorConversation::class)]
25+
#[ORM\JoinColumn(name: 'conversation_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
26+
protected AiTutorConversation $conversation;
27+
28+
#[ORM\Column(name: 'role', type: 'string', length: 20, nullable: false)]
29+
protected string $role;
30+
31+
#[ORM\Column(name: 'content', type: 'text', nullable: false)]
32+
protected string $content;
33+
34+
#[ORM\Column(name: 'created_at', type: 'datetime', nullable: false)]
35+
protected DateTime $createdAt;
36+
37+
public function __construct()
38+
{
39+
$this->createdAt = new DateTime();
40+
}
41+
42+
#[ORM\PrePersist]
43+
public function onPrePersist(): void
44+
{
45+
// Keep conversation timestamps in sync when a new message is stored.
46+
if (isset($this->conversation)) {
47+
$this->conversation->touchLastMessageAt();
48+
}
49+
}
50+
51+
public function getId(): ?int
52+
{
53+
return $this->id;
54+
}
55+
56+
public function getConversation(): AiTutorConversation
57+
{
58+
return $this->conversation;
59+
}
60+
61+
public function setConversation(AiTutorConversation $conversation): self
62+
{
63+
$this->conversation = $conversation;
64+
65+
return $this;
66+
}
67+
68+
public function getRole(): string
69+
{
70+
return $this->role;
71+
}
72+
73+
public function setRole(string $role): self
74+
{
75+
$this->role = $role;
76+
77+
return $this;
78+
}
79+
80+
public function getContent(): string
81+
{
82+
return $this->content;
83+
}
84+
85+
public function setContent(string $content): self
86+
{
87+
$this->content = $content;
88+
89+
return $this;
90+
}
91+
92+
public function getCreatedAt(): DateTime
93+
{
94+
return $this->createdAt;
95+
}
96+
97+
public function setCreatedAt(DateTime $createdAt): self
98+
{
99+
$this->createdAt = $createdAt;
100+
101+
return $this;
102+
}
103+
}

0 commit comments

Comments
 (0)