Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/tutor-pro/tutorai/CourseGenerationController.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
/**
3
+
* Helper class for handling magic ai functionalities
4
+
*
5
+
* @package TutorPro\TutorAI
6
+
* @author Themeum <support@themeum.com>
7
+
* @link https://themeum.com
8
+
* @since 3.0.0
9
+
*/
10
+
11
+
namespace TutorPro\TutorAI;
12
+
13
+
use Exception;
14
+
use Throwable;
15
+
use Tutor\Helpers\HttpHelper;
16
+
use TUTOR\Input;
17
+
use Tutor\Traits\JsonResponse;
18
+
use TutorPro\OpenAI\Constants\Models;
19
+
use TutorPro\OpenAI\Constants\Sizes;
20
+
21
+
if ( ! defined( 'ABSPATH' ) ) {
22
+
exit;
23
+
}
24
+
25
+
/**
26
+
* Controller class for generating course with content using openai.
27
+
*
28
+
* @since 3.0.0
29
+
*/
30
+
class CourseGenerationController {
31
+
/**
32
+
* Use the trait JsonResponse for sending response in application/json content type
33
+
*
34
+
* @var JsonResponse
35
+
*/
36
+
use JsonResponse;
37
+
38
+
/**
39
+
* Constructor method for the course generation controller
40
+
*
41
+
* @since 3.0.0
42
+
*/
43
+
public function __construct() {
44
+
/**
45
+
* Handle AJAX request for generating AI images
46
+
*
47
+
* @since 3.0.0
48
+
*/
49
+
add_action( 'wp_ajax_tutor_pro_generate_course_content', array( $this, 'course_content_generation' ) );
50
+
51
+
/**
52
+
* Handle AJAX request for generating course content for a topic
53
+
*
54
+
* @since 3.0.0
55
+
*/
56
+
add_action( 'wp_ajax_tutor_pro_generate_course_topic_content', array( $this, 'generate_course_topic_content' ) );
57
+
58
+
/**
59
+
* Handle AJAX request for generating quiz question by using openai.
60
+
*
61
+
* @since 3.0.0
62
+
*/
63
+
add_action( 'wp_ajax_tutor_pro_generate_quiz_questions', array( $this, 'generate_quiz_questions' ) );
64
+
}
65
+
66
+
/**
67
+
* Generate the course title from the user prompt.
68
+
*
69
+
* @since 3.0.0
70
+
*
71
+
* @return string|null
72
+
*
73
+
* @throws Throwable Catch if there any exceptions then throw it.
74
+
*/
75
+
private function generate_course_title() {
76
+
$prompt = Input::post( 'prompt', '' );
77
+
78
+
try {
79
+
$client = Helper::get_openai_client();
80
+
$response = $client->chat()->create(
81
+
Helper::create_openai_chat_input(
82
+
Prompts::prepare_course_title_messages( $prompt )
83
+
)
84
+
);
85
+
86
+
$response = Helper::check_openai_response( $response );
87
+
88
+
if ( ! empty( $response->choices ) ) {
89
+
return $response->choices[0]->message->content;
90
+
}
91
+
92
+
return null;
93
+
} catch ( Throwable $error ) {
94
+
throw $error;
95
+
}
96
+
}
97
+
98
+
/**
99
+
* Generate the course description from the user prompt.
100
+
*
101
+
* @since 3.0.0
102
+
*
103
+
* @param string $title Generated course title.
104
+
*
105
+
* @return string|null
106
+
*
107
+
* @throws Throwable Catch if there any exceptions then throw it.
108
+
*/
109
+
private function generate_course_description( string $title ) {
110
+
try {
111
+
$client = Helper::get_openai_client();
112
+
$response = $client->chat()->create(
113
+
Helper::create_openai_chat_input(
114
+
Prompts::prepare_course_description_messages( $title )
115
+
)
116
+
);
117
+
118
+
$response = Helper::check_openai_response( $response );
119
+
120
+
if ( ! empty( $response->choices ) ) {
121
+
$content = $response->choices[0]->message->content;
122
+
return Helper::markdown_to_html( $content );
123
+
}
124
+
125
+
return null;
126
+
} catch ( Throwable $error ) {
127
+
throw $error;
128
+
}
129
+
}
130
+
131
+
/**
132
+
* Generate course image using the course title.
133
+
*
134
+
* @since 3.0.0
135
+
*
136
+
* @param string $title The course title.
137
+
*
138
+
* @return string
139
+
*
140
+
* @throws Throwable If any exception happens, then throw it.
141
+
*/
142
+
private function generate_course_image( string $title ) {
143
+
try {
144
+
$client = Helper::get_openai_client();
145
+
$prompt = "Design a modern and professional e-learning course banner image that visually conveys the theme of a course titled '{title}'. The image should be clean and minimalistic, using realistic visuals, colors, and icons related to the course topic. Incorporate subtle, relevant graphics or symbols that represent the course subject while keeping the layout simple and focused. Avoid clutter and unnecessary details. Use a visually appealing color scheme that aligns with the course theme, ensuring the design remains sleek and engaging. Do not include any text in the image, focusing solely on the graphics and design to convey the course's theme in a minimal, realistic manner.";
146
+
$prompt = str_replace( '{title}', $title, $prompt );
147
+
148
+
$response = $client->images()->create(
149
+
array(
150
+
'model' => Models::DALL_E_3,
151
+
'prompt' => $prompt,
152
+
'size' => Sizes::LANDSCAPE,
153
+
'n' => 1,
154
+
'response_format' => 'b64_json',
155
+
)
156
+
);
157
+
158
+
$response = Helper::check_openai_response( $response );
159
+
160
+
return $response->data[0]->b64_json;
161
+
} catch ( Throwable $error ) {
162
+
throw $error;
163
+
}
164
+
}
165
+
166
+
/**
167
+
* Generate the course topic names from the title
168
+
*
169
+
* @since 3.0.0
170
+
*
171
+
* @param string $title The course title.
172
+
*
173
+
* @return array
174
+
*
175
+
* @throws Throwable If any exception happens then throws it.
176
+
*/
177
+
private function generate_course_topic_names( string $title ) {
178
+
try {
179
+
$client = Helper::get_openai_client();
180
+
$input = Helper::create_openai_chat_input(
181
+
Prompts::prepare_course_topic_names_messages( $title ),
182
+
array( 'response_format' => array( 'type' => 'json_object' ) )
183
+
);
184
+
185
+
$response = $client->chat()->create( $input );
186
+
$response = Helper::check_openai_response( $response );
187
+
$content = $response->choices[0]->message->content;
188
+
$content = Helper::sanitize_json( $content );
189
+
$content = Helper::is_valid_json( $content ) ? json_decode( $content ) : array();
190
+
$modules = ! empty( $content->modules ) ? $content->modules : array();
191
+
192
+
return $modules;
193
+
} catch ( Throwable $error ) {
194
+
throw $error;
195
+
}
196
+
}
197
+
198
+
/**
199
+
* API endpoint for generate course content for a topic by the course title and the topic name.
200
+
*
201
+
* @since 3.0.0
202
+
*
203
+
* @return void
204
+
*/
205
+
public function generate_course_topic_content() {
206
+
tutor_utils()->check_nonce();
207
+
208
+
$title = Input::post( 'title' );
209
+
$topic_name = Input::post( 'topic_name' );
210
+
$index = Input::post( 'index', 0, Input::TYPE_INT );
211
+
212
+
try {
213
+
$client = Helper::get_openai_client();
214
+
$input = Helper::create_openai_chat_input(
215
+
Prompts::prepare_course_topic_content_messages( $title, $topic_name )
216
+
);
217
+
$response = $client->chat()->create( $input );
218
+
$response = Helper::check_openai_response( $response );
219
+
$content = $response->choices[0]->message->content;
220
+
$content = Helper::sanitize_json( $content );
221
+
$content = Helper::is_valid_json( $content ) ? json_decode( $content ) : array();
222
+
223
+
$this->json_response(
224
+
__( 'Content generated', 'tutor-pro' ),
225
+
array(
226
+
'topic_contents' => $content,
227
+
'index' => $index,
228
+
)
229
+
);
230
+
} catch ( Exception $error ) {
231
+
$this->json_response( $error->getMessage(), null, HttpHelper::STATUS_INTERNAL_SERVER_ERROR );
232
+
}
233
+
}
234
+
235
+
/**
236
+
* API endpoint for generating course contents using the prompt.
237
+
*
238
+
* @since 3.0.0
239
+
*
240
+
* @return void
241
+
*/
242
+
public function course_content_generation() {
243
+
tutor_utils()->check_nonce();
244
+
245
+
$type = Input::post( 'type' );
246
+
$title = Input::post( 'title' );
247
+
try {
248
+
$method = 'generate_course_' . $type;
249
+
$arguments = 'title' === $type ? array() : array( $title );
250
+
251
+
if ( ! method_exists( $this, $method ) ) {
252
+
$this->json_response( __( 'Invalid type provided', 'tutor-pro' ), null, HttpHelper::STATUS_BAD_REQUEST );
253
+
}
254
+
255
+
$content = call_user_func_array( array( $this, $method ), $arguments );
256
+
257
+
$this->json_response(
258
+
__( 'Content generated', 'tutor-pro' ),
259
+
$content
260
+
);
261
+
} catch ( Exception $error ) {
262
+
$this->json_response( $error->getMessage(), null, HttpHelper::STATUS_INTERNAL_SERVER_ERROR );
263
+
}
264
+
}
265
+
266
+
/**
267
+
* Generate quiz questions by the help of course title, topic, and quiz title.
268
+
*
269
+
* @since 3.0.0
270
+
*
271
+
* @return void
272
+
*/
273
+
public function generate_quiz_questions() {
274
+
tutor_utils()->check_nonce();
275
+
276
+
$title = Input::post( 'title' );
277
+
$topic_name = Input::post( 'topic_name' );
278
+
$quiz_title = Input::post( 'quiz_title' );
279
+
280
+
if ( empty( $title ) || empty( $topic_name ) || empty( $quiz_title ) ) {
281
+
$this->json_response( __( 'Missing required payloads.', 'tutor-pro' ), null, HttpHelper::STATUS_BAD_REQUEST );
282
+
}
283
+
284
+
try {
285
+
$client = Helper::get_openai_client();
286
+
$input = Helper::create_openai_chat_input(
287
+
Prompts::prepare_quiz_questions_messages( $title, $topic_name, $quiz_title )
288
+
);
289
+
290
+
$response = $client->chat()->create( $input );
291
+
$response = Helper::check_openai_response( $response );
292
+
$content = $response->choices[0]->message->content;
293
+
$content = Helper::sanitize_json( $content );
294
+
$content = Helper::is_valid_json( $content ) ? json_decode( $content ) : array();
295
+
296
+
$this->json_response( __( 'Quiz generated', 'tutor-pro' ), $content );
297
+
} catch ( Exception $error ) {
298
+
$this->json_response( $error->getMessage(), null, HttpHelper::STATUS_INTERNAL_SERVER_ERROR );
299
+
}
300
+
}
301
+
}
302
+