PluginProbe
Auto Alt Text / 2.4.2
Auto Alt Text v2.4.2
3.0.3 2.8.2 1.3.1 1.3.2 2.0.0 2.1.0 2.1.1 2.2.0 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.7.0 2.8.0 2.8.1 All 28 releases
auto-alt-text / src / App / Admin / PluginOptions.php

PluginOptions.php in Auto Alt Text 2.4.2, at src/App/Admin/PluginOptions.php

555 lines 28.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AATXT\App\Admin;
4
5 use AATXT\App\Logging\DBLogger;
6 use AATXT\App\AIProviders\Azure\AzureTranslator;
7 use AATXT\App\Exceptions\Azure\AzureTranslateInstanceException;
8 use AATXT\App\Utilities\AssetsManager;
9 use AATXT\App\Utilities\Encryption;
10 use AATXT\Config\Constants;
11
12 class PluginOptions
13 {
14 private static ?self $instance = null;
15 private static AssetsManager $assetsManager;
16
17 private function __construct()
18 {
19 //
20 }
21
22 /**
23 * Manage the necessary hooks to implement plugin options and their pages
24 * @return void
25 */
26 public static function register(): void
27 {
28 if (is_null(self::$instance)) {
29 self::$instance = new self();
30 }
31
32 self::$assetsManager = AssetsManager::make();
33
34 add_action('admin_notices', [self::$instance, 'showEncryptionConstantsNotice']);
35
36 add_action('admin_enqueue_scripts', [self::$instance, 'enqueueAdminScripts'], 1);
37 add_action('admin_menu', [self::$instance, 'addOptionsPageToTheMenu']);
38 add_action('admin_init', [self::$instance, 'setupPluginOptions'], 10);
39 add_action('admin_init', [self::$instance, 'migrateEncryptionKeys'], 9);
40
41 // Encrypt API Keys on update
42 add_action('pre_update_option_' . Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_COMPUTER_VISION, [self::$instance, 'encryptDataOnUpdate'], 10, 3);
43 add_action('pre_update_option_' . Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_TRANSLATE_INSTANCE, [self::$instance, 'encryptDataOnUpdate'], 10, 3);
44 add_action('pre_update_option_' . Constants::AATXT_OPTION_FIELD_API_KEY_OPENAI, [self::$instance, 'encryptDataOnUpdate'], 10, 3);
45
46 add_action('admin_notices', [self::$instance, 'encryptionErrorNotice']);
47 }
48
49 /**
50 * Show an error notice if the encryption of the API Key fails
51 * @return void
52 */
53 public function encryptionErrorNotice(): void
54 {
55 $raw = get_option(Constants::AATXT_OPTION_FIELD_API_KEY_OPENAI);
56 $decrypted = Encryption::make()->decrypt((string) $raw);
57
58 if ($raw && $decrypted === '') {
59 $screen = get_current_screen();
60 $settingsScreenId = 'toplevel_page_' . Constants::AATXT_PLUGIN_OPTIONS_PAGE_SLUG;
61 $showLink = ! ( $screen && $screen->id === $settingsScreenId );
62
63 $settingsUrl = esc_url( menu_page_url(Constants::AATXT_PLUGIN_OPTIONS_PAGE_SLUG, false) );
64
65 echo '<div class="notice notice-error is-dismissible">';
66 echo '<p>';
67
68 echo '<strong>' . esc_html__('Auto Alt Text', 'auto-alt-text') . ':</strong> ';
69
70 echo esc_html__(
71 'There was a problem with the encryption of your API Key for alt text generation. Please re-enter the key and save.',
72 'auto-alt-text'
73 );
74
75 if ($showLink) {
76 echo ' <a href="' . $settingsUrl . '">'
77 . esc_html__('Go to settings page', 'auto-alt-text')
78 . '</a>.';
79 }
80 echo '</p>';
81 echo '</div>';
82 }
83 }
84
85 /**
86 * Print an admin notice containing the defines to be added
87 * to the wp-config.php.
88 */
89 public function showEncryptionConstantsNotice(): void
90 {
91 if ( ! is_admin() || ! current_user_can('manage_options') ) {
92 return;
93 }
94
95 $screen = function_exists('get_current_screen') ? get_current_screen() : null;
96 if ( ! $screen || $screen->id !== 'toplevel_page_' . Constants::AATXT_PLUGIN_OPTIONS_PAGE_SLUG ) {
97 return;
98 }
99
100 if ( defined('AATXT_ENCRYPTION_KEY') && defined('AATXT_ENCRYPTION_SALT') ) {
101 return;
102 }
103
104 $suggestedKey = bin2hex(random_bytes(32));
105 $suggestedSalt = bin2hex(random_bytes(32));
106 ?>
107 <div class="notice notice-info is-dismissible">
108 <p>
109 <?php
110 printf(
111 /* translators: “Optional” label */
112 __( '%s: you can add two lines to your wp-config.php to make your API key more resilient if WordPress salts ever change.', 'auto-alt-text' ),
113 '<strong>' . esc_html__( 'Optional', 'auto-alt-text' ) . '</strong>'
114 );
115 ?>
116 </p>
117 <pre style="background:#f5f5f5; padding:10px; border-radius:4px;">
118 define('AATXT_ENCRYPTION_KEY', '<?php echo esc_html( $suggestedKey ); ?>');
119 define('AATXT_ENCRYPTION_SALT', '<?php echo esc_html( $suggestedSalt ); ?>');
120 </pre>
121 <p>
122 <?php esc_html_e(
123 'Just paste them before the line “/* That\'s all, stop editing! Happy publishing. */” in wp-config.php.',
124 'auto-alt-text'
125 ); ?>
126 </p>
127 <p>
128 <?php esc_html_e(
129 "If you don't have the ability to edit the wp-config.php, don't worry because the plugin will still work without this change. If your site's salting keys change in the future, you will simply need to resave your API Key in the options below.",
130 "auto-alt-text"
131 ); ?>
132 </p>
133 </div>
134 <?php
135 }
136
137 public function migrateEncryptionKeys(): void
138 {
139 if ( ! defined('AATXT_ENCRYPTION_KEY') || ! defined('AATXT_ENCRYPTION_SALT') ) {
140 return;
141 }
142
143 update_option(Constants::AATXT_LEGACY_ENCRYPTION_MIGRATION_DONE, '0');
144
145 if ( get_option(Constants::AATXT_LEGACY_ENCRYPTION_MIGRATION_DONE) ) {
146 return;
147 }
148
149 Encryption::make()->migrateLegacyApiKeys();
150
151 update_option(Constants::AATXT_LEGACY_ENCRYPTION_MIGRATION_DONE, '1');
152 }
153
154 /**
155 * Encrypt data
156 * @param ?string $newValue
157 * @return ?string
158 */
159 public function encryptDataOnUpdate(?string $newValue): ?string
160 {
161 if (!empty($newValue)) {
162 $newValue = (Encryption::make())->encrypt($newValue);
163 }
164 return $newValue;
165 }
166
167 /**
168 * @return void
169 */
170 public static function enqueueAdminScripts(): void
171 {
172 $screen = get_current_screen();
173 $isMainOptionsPage = $screen->id === 'toplevel_page_' . Constants::AATXT_PLUGIN_OPTIONS_PAGE_SLUG;
174
175 if ($isMainOptionsPage || strpos($screen->id, Constants::AATXT_PLUGIN_SLUG . '_') !== false) {
176
177 $adminCss = self::$assetsManager->getAssetUrl('resources/js/admin.js', true);
178
179 wp_enqueue_style(Constants::AATXT_PLUGIN_ASSETS_HANDLE, $adminCss, [], false);
180
181 if ($isMainOptionsPage) {
182 $adminJs = self::$assetsManager->getAssetUrl('resources/js/admin.js', false);
183 wp_enqueue_script(Constants::AATXT_PLUGIN_ASSETS_HANDLE, $adminJs, [], false);
184 }
185
186 }
187 }
188
189 /**
190 * Create options pages
191 * @return void
192 */
193 public static function addOptionsPageToTheMenu(): void
194 {
195 add_menu_page('Auto Alt Text Options', 'Auto Alt Text', 'manage_options', Constants::AATXT_PLUGIN_OPTIONS_PAGE_SLUG, [self::$instance, 'optionsMainPage'], null, 99);
196 add_submenu_page(Constants::AATXT_PLUGIN_OPTIONS_PAGE_SLUG, 'Error Log', 'Error log', 'manage_options', Constants::AATXT_PLUGIN_OPTION_LOG_PAGE_SLUG, [self::$instance, 'logOptionsPage']);
197 }
198
199 /**
200 * Implement the page showing error log
201 * @return void
202 */
203 public static function logOptionsPage(): void
204 {
205 ?>
206 <div class="wrap">
207 <h1><?php esc_html_e('Auto Alt Text Error Log', 'auto-alt-text') ?></h1>
208 <div class="aat-options plugin-description">
209 <p>
210 <?php esc_html_e("If the alt text of your images was not generated correctly, you can find the reason in this log.", 'auto-alt-text'); ?>
211 <br>
212 <?php esc_html_e("Each line corresponds to an error generated by a call to the Azure or OpenAI API after uploading an image.", 'auto-alt-text'); ?>
213 </p>
214 <?php
215 $logs = DBLogger::make()->getImageLog();
216 if ($logs) {
217 echo '<textarea id="error-log" name="error-log" readonly>' . esc_textarea($logs) . '</textarea>';
218 } else {
219 echo '<p>' . esc_html__('There is no error log yet!', 'auto-alt-text') . '</p>';
220 }
221
222 ?>
223 </div>
224 </div>
225 <?php
226 }
227
228 /**
229 * Implement the main option page
230 * @return void
231 */
232 public static function optionsMainPage(): void
233 {
234 ?>
235 <div class="wrap">
236 <h1><?php esc_html_e('Auto Alt Text Options', 'auto-alt-text') ?></h1>
237
238 <div class="aat-options plugin-description">
239 <p>
240 <?php esc_html_e("This plugin allows you to automatically generate Alt Text for the images that are uploaded to the site's media library.", 'auto-alt-text'); ?>
241 <br>
242 <?php esc_html_e("The following methods are available to generate the alt text:", 'auto-alt-text'); ?>
243 </p>
244 <ul>
245 <li>
246 <strong><?php esc_html_e("OpenAI's APIs", 'auto-alt-text'); ?></strong>: <?php esc_html_e("the image will be analyzed by the AI services provided by OpenAI and an alt text will be generated based on the prompt you set;", 'auto-alt-text'); ?>
247 </li>
248 <li>
249 <strong><?php esc_html_e("Azure's APIs", 'auto-alt-text'); ?></strong>: <?php esc_html_e("the image will be analyzed by the AI services provided by Azure and an alt text will be generated in the language of your choice;", 'auto-alt-text'); ?>
250 </li>
251 <li>
252 <strong><?php esc_html_e("Title of the article (not AI)", 'auto-alt-text'); ?></strong>: <?php esc_html_e("if the image is uploaded within an article, the title of the article will be used as alt text;", 'auto-alt-text'); ?>
253 </li>
254 <li>
255 <strong><?php esc_html_e("Title of the attachment (not AI)", 'auto-alt-text'); ?></strong>: <?php esc_html_e("the title of the attachment will be copied into the alt text;", 'auto-alt-text'); ?>
256 </li>
257 </ul>
258 <p><?php esc_html_e("Once all the necessary data for the chosen generation method has been entered, the alt texts will be created automatically upon uploading each image.", 'auto-alt-text'); ?></p>
259 <p><strong>New</strong>: <?php esc_html_e("For images already in the media library, you can create bulk alt texts. Open the Media Library in the \"list\" view, select the images for which to generate the alt text, and choose the \"Generate alt text\" bulk action. (Depending on the number of images chosen and their weight, this may take some time.)", 'auto-alt-text'); ?></p>
260 <p>
261 <strong><?php esc_html_e('Pay attention please:', 'auto-alt-text') ?></strong> <?php esc_html_e("if the alt text for an image is not generated, check the logs on the", 'auto-alt-text'); ?>
262 <a href="<?php esc_url(menu_page_url(Constants::AATXT_PLUGIN_OPTION_LOG_PAGE_SLUG, true)); ?>"><?php esc_html_e('designated page.', 'auto-alt-text') ?></a>
263 </p>
264 </div>
265 <form method="post" action="options.php" class="aat-options">
266 <?php
267 settings_fields('auto_alt_text_options');
268
269 echo '<div>';
270 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_TYPOLOGY) . '">' . esc_html__('Generation method', 'auto-alt-text') . '</label>';
271 echo '<p class="description">' . esc_html__("Which method do you want to use to generate the alt text for the images?", 'auto-alt-text') . '</p>';
272 $typology = self::typology();
273
274 ?>
275
276 <select name="<?php echo esc_attr(Constants::AATXT_OPTION_FIELD_TYPOLOGY); ?>"
277 id="<?php echo esc_attr(Constants::AATXT_OPTION_FIELD_TYPOLOGY); ?>">
278 <option value="<?php echo esc_attr(Constants::AATXT_OPTION_TYPOLOGY_DEACTIVATED); ?>"<?php echo esc_attr(self::selected($typology, Constants::AATXT_OPTION_TYPOLOGY_DEACTIVATED)); ?>><?php esc_html_e("Deactivated", 'auto-alt-text'); ?></option>
279 <option value="<?php echo esc_attr(Constants::AATXT_OPTION_TYPOLOGY_CHOICE_OPENAI); ?>"<?php echo esc_attr(self::selected($typology, Constants::AATXT_OPTION_TYPOLOGY_CHOICE_OPENAI)); ?>><?php esc_html_e("OpenAI's APIs", 'auto-alt-text'); ?></option>
280 <option value="<?php echo esc_attr(Constants::AATXT_OPTION_TYPOLOGY_CHOICE_AZURE); ?>"<?php echo esc_attr(self::selected($typology, Constants::AATXT_OPTION_TYPOLOGY_CHOICE_AZURE)); ?>><?php esc_html_e("Azure's APIs", 'auto-alt-text'); ?></option>
281 <option value="<?php echo esc_attr(Constants::AATXT_OPTION_TYPOLOGY_CHOICE_ARTICLE_TITLE); ?>"<?php echo esc_attr(self::selected($typology, Constants::AATXT_OPTION_TYPOLOGY_CHOICE_ARTICLE_TITLE)); ?>><?php esc_html_e("Title of the article (not AI)", 'auto-alt-text'); ?></option>
282 <option value="<?php echo esc_attr(Constants::AATXT_OPTION_TYPOLOGY_CHOICE_ATTACHMENT_TITLE); ?>"<?php echo esc_attr(self::selected($typology, Constants::AATXT_OPTION_TYPOLOGY_CHOICE_ATTACHMENT_TITLE)); ?>><?php esc_html_e("Title of the attachment (not AI)", 'auto-alt-text'); ?></option>
283 </select>
284 <?php
285 echo '</div>';
286
287 echo '<div class="plugin-option type-article-title"><strong>' . esc_html__('Notice', 'auto-alt-text') . '</strong>: ' .
288 esc_html__('If you try to insert an image into a post that has not yet been saved as a draft or published, the plugin cannot generate an alt text based on the post\'s title since the title itself has not yet been saved.', 'auto-alt-text') . ' ' .
289 esc_html__('Therefore, the alt text "Auto draft" will be inserted. To avoid this behavior, save the article draft first and then upload the image.', 'auto-alt-text') .
290 '</div>';
291
292 $openaiModel = self::openAiModel();
293
294 echo '<div class="plugin-option type-openai">';
295 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_MODEL_OPENAI) . '">' . esc_html__('Model', 'auto-alt-text') . '</label>';
296
297 echo '<select name="' . esc_attr(Constants::AATXT_OPTION_FIELD_MODEL_OPENAI) . '" id="' . esc_attr(Constants::AATXT_OPTION_FIELD_MODEL_OPENAI) . '">';
298 foreach(Constants::AATXT_OPTION_FIELD_MODEL_OPENAI_OPTIONS as $key => $value) {
299 echo '<option value="' . esc_attr($key) . '" ' . esc_attr(self::selected($openaiModel, $key)) . '>' . esc_html($value) . '</option>';
300 }
301 echo '</select>';
302 echo '</div>';
303
304 echo '<div class="plugin-option type-openai"><strong>' . esc_html__('Notice', 'auto-alt-text') . '</strong>: ' .
305 esc_html__('Rarely it may happen that the chosen model fails to generate correct alt text for the image.', 'auto-alt-text') . ' ' .
306 esc_html__('In these cases, the call to the api will be re-performed using the gpt-4o-mini model as fallback.', 'auto-alt-text') . '<br>' .
307 esc_html__('In case of errors, it is still possible to find the specific reason stated on the', 'auto-alt-text') . ' <a href="' . esc_url(menu_page_url(Constants::AATXT_PLUGIN_OPTION_LOG_PAGE_SLUG, false)) . '">' . esc_html__('error log page', 'auto-alt-text') . '</a>.' .
308 '</div>';
309
310 echo '<div class="plugin-option type-openai">';
311 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_API_KEY_OPENAI) . '">' . esc_html__('OpenAI API Key', 'auto-alt-text') . '</label>';
312 echo '<p class="description">' . esc_html__("Enter your API Key", 'auto-alt-text') . '</p>';
313 $apiKey = get_option(Constants::AATXT_OPTION_FIELD_API_KEY_OPENAI);
314 echo '<input type="password" name="' . esc_attr(Constants::AATXT_OPTION_FIELD_API_KEY_OPENAI) . '" value="' . esc_attr((Encryption::make())->decrypt($apiKey)) . '" />';
315 echo '</div>';
316
317 echo '<div class="plugin-option type-openai">';
318 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_PROMPT_OPENAI) . '">' . esc_html__('Prompt', 'auto-alt-text') . '</label>';
319 echo '<p class="description">' . esc_html__("Enter a specific and detailed prompt according to your needs.", 'auto-alt-text') . '</p>';
320 $defaultPrompt = sprintf(esc_html__("Act like an SEO expert and write an alt text of up to 125 characters for this image.", 'auto-alt-text'), Constants::AATXT_IMAGE_URL_TAG);
321 $prompt = get_option(Constants::AATXT_OPTION_FIELD_PROMPT_OPENAI) ?: $defaultPrompt;
322 echo '<textarea name="' . esc_attr(Constants::AATXT_OPTION_FIELD_PROMPT_OPENAI) . '" rows="5" cols="50">' . esc_textarea($prompt) . '</textarea>';
323 echo '</div>';
324
325 echo '<div class="plugin-option type-azure">' . esc_html__("Fill out the following fields to leverage Azure's computer vision services to generate the Alt texts.", 'auto-alt-text') . '</div>';
326
327 echo '<div class="plugin-option type-azure">';
328 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_COMPUTER_VISION) . '">' . esc_html__('Azure Computer Vision API Key', 'auto-alt-text') . '</label>';
329 echo '<p class="description">' . esc_html__("Enter the API key for the Computer Vision service of your Azure account.", 'auto-alt-text') . '</p>';
330 $apiKey = get_option(Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_COMPUTER_VISION);
331 echo '<input type="password" name="' . esc_attr(Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_COMPUTER_VISION) . '" value="' . esc_attr((Encryption::make())->decrypt($apiKey)) . '" />';
332 echo '</div>';
333
334 echo '<div class="plugin-option type-azure">';
335 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_COMPUTER_VISION) . '">' . esc_html__('Azure Computer Vision Endpoint', 'auto-alt-text') . '</label>';
336 echo '<p class="description">' . esc_html__("Enter the endpoint of the Computer Vision service.", 'auto-alt-text') . ' (es. https://computer-vision-france-central.cognitiveservices.azure.com/)</p>';
337 $endpoint = get_option(Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_COMPUTER_VISION);
338 echo '<input type="text" name="' . esc_attr(Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_COMPUTER_VISION) . '" value="' . esc_attr($endpoint) . '" />';
339 echo '</div>';
340
341 echo '<div class="plugin-option type-azure">' .
342 '<strong>' . esc_html__('The default alt text language is English.', 'auto-alt-text') . '</strong><br>' .
343 esc_html__('If you want to translate into another language, enter the following data necessary for the translation API to work.', 'auto-alt-text') . ' ' .
344 esc_html__('After saving the changes you can select the desired language.', 'auto-alt-text') .
345 '</div>';
346
347 echo '<div class="plugin-option type-azure">';
348 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_TRANSLATE_INSTANCE) . '">' . esc_html__('Azure Translate Instance API Key', 'auto-alt-text') . '</label>';
349 echo '<p class="description">' . esc_html__("Enter your API key for the Azure Translate Instance service.", 'auto-alt-text') . '</p>';
350 $translationApiKey = get_option(Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_TRANSLATE_INSTANCE);
351 echo '<input type="password" name="' . esc_attr(Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_TRANSLATE_INSTANCE) . '" value="' . esc_attr((Encryption::make())->decrypt($translationApiKey)) . '" class="notRequired" />';
352 echo '</div>';
353
354 echo '<div class="plugin-option type-azure">';
355 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_TRANSLATE_INSTANCE) . '">' . esc_html__('Azure Translate Instance Endpoint', 'auto-alt-text') . '</label>';
356 echo '<p class="description">' . esc_html__("Enter the endpoint of the Translate Instance service", 'auto-alt-text') . ' (es. https://api.cognitive.microsofttranslator.com/)</p>';
357 $translationEndpoint = get_option(Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_TRANSLATE_INSTANCE);
358 echo '<input type="text" name="' . esc_attr(Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_TRANSLATE_INSTANCE) . '" value="' . esc_attr($translationEndpoint) . '" class="notRequired" />';
359 echo '</div>';
360
361 echo '<div class="plugin-option type-azure">';
362 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_REGION_AZURE_TRANSLATE_INSTANCE) . '">' . esc_html__('Azure Translate Instance Region', 'auto-alt-text') . '</label>';
363 echo '<p class="description">' . esc_html__("Enter the region of the Azure Translate Instance service.", 'auto-alt-text') . ' (es. westeurope)</p>';
364 $translationRegion = get_option(Constants::AATXT_OPTION_FIELD_REGION_AZURE_TRANSLATE_INSTANCE);
365 echo '<input type="text" name="' . esc_attr(Constants::AATXT_OPTION_FIELD_REGION_AZURE_TRANSLATE_INSTANCE) . '" value="' . esc_attr($translationRegion) . '" class="notRequired" />';
366 echo '</div>';
367
368 if ($translationApiKey && $translationEndpoint && $translationRegion):
369 echo '<div class="plugin-option type-azure">';
370 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_LANGUAGE_AZURE_TRANSLATE_INSTANCE) . '">' . esc_html__('Alt Text Language', 'auto-alt-text') . '</label>';
371 echo '<p class="description">' . esc_html__("Select the language in which the alt text should be written.", 'auto-alt-text') . '</p>';
372 $currentLanguage = get_option(Constants::AATXT_OPTION_FIELD_LANGUAGE_AZURE_TRANSLATE_INSTANCE);
373
374 try {
375 $supportedLanguages = (AzureTranslator::make())->supportedLanguages();
376 } catch (AzureTranslateInstanceException $e) {
377 $supportedLanguages = [
378 "en" => [
379 "name" => "English",
380 "nativeName" => "English",
381 "dir" => "ltr",
382 ]
383 ];
384 echo '<p style="color:red"><strong>' . esc_html($e->getMessage()) . '</strong></p>';
385 }
386
387 ?>
388 <select name="<?php echo esc_attr(Constants::AATXT_OPTION_FIELD_LANGUAGE_AZURE_TRANSLATE_INSTANCE); ?>"
389 id="<?php echo esc_attr(Constants::AATXT_OPTION_FIELD_LANGUAGE_AZURE_TRANSLATE_INSTANCE); ?>">
390 <?php
391 foreach ($supportedLanguages as $key => $language):
392 ?>
393 <option value="<?php echo esc_attr($key) ?>" <?php echo esc_attr(self::selected($currentLanguage, $key)); ?>><?php echo esc_html($language['name']); ?></option>
394 <?php
395 endforeach;
396 ?>
397 </select>
398
399 <?php
400
401 echo '</div>';
402 endif;
403
404 echo '<div class="plugin-option type-article-title type-attachment-title type-openai type-azure">';
405 echo '<label for="' . esc_attr(Constants::AATXT_OPTION_FIELD_PRESERVE_EXISTING_ALT_TEXT) . '">' . esc_html__('Keep existing alt text', 'auto-alt-text') . '</label>';
406 echo '<p class="description">' . esc_html__("If checked, the existing alt text of images will not be overwritten.", 'auto-alt-text') . '</p>';
407 $preserveAltText = get_option(Constants::AATXT_OPTION_FIELD_PRESERVE_EXISTING_ALT_TEXT);
408 echo '<input type="checkbox" name="' . esc_attr(Constants::AATXT_OPTION_FIELD_PRESERVE_EXISTING_ALT_TEXT) . '" value="1" class="notRequired" ' . checked(1, $preserveAltText, false) . ' />';
409 echo '</div>';
410
411 submit_button();
412 ?>
413 </form>
414 </div>
415 <?php
416 }
417
418 /**
419 * If option is selected return the selected attribute
420 * @param string $selectedValue
421 * @param string $inputValue
422 * @return string
423 */
424 public static function selected(string $selectedValue, string $inputValue): string
425 {
426 if (empty($selectedValue) && 'en' == $inputValue) {
427 return ' selected';
428 }
429 return $selectedValue == $inputValue ? ' selected' : '';
430 }
431
432
433 /**
434 * Register input fields and option settings
435 * @return void
436 */
437 public static function setupPluginOptions(): void
438 {
439 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_API_KEY_OPENAI);
440 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_PROMPT_OPENAI, [self::class, 'sanitizeTextArea']);
441 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_TYPOLOGY, [self::class, 'sanitizeText']);
442 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_MODEL_OPENAI, [self::class, 'sanitizeText']);
443 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_COMPUTER_VISION);
444 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_COMPUTER_VISION, [self::class, 'sanitizeUrl']);
445 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_TRANSLATE_INSTANCE);
446 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_TRANSLATE_INSTANCE, [self::class, 'sanitizeUrl']);
447 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_REGION_AZURE_TRANSLATE_INSTANCE, [self::class, 'sanitizeText']);
448 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_LANGUAGE_AZURE_TRANSLATE_INSTANCE, [self::class, 'sanitizeText']);
449 register_setting('auto_alt_text_options', Constants::AATXT_OPTION_FIELD_PRESERVE_EXISTING_ALT_TEXT);
450 }
451
452 /**
453 * @return string
454 */
455 public static function typology(): string
456 {
457 return get_option(Constants::AATXT_OPTION_FIELD_TYPOLOGY);
458 }
459
460 public static function openAiModel(): string
461 {
462 return get_option(Constants::AATXT_OPTION_FIELD_MODEL_OPENAI) ?: Constants::AATXT_GPT4O;
463 }
464
465 /**
466 * @return string
467 */
468 public static function prompt(): string
469 {
470 return get_option(Constants::AATXT_OPTION_FIELD_PROMPT_OPENAI);
471 }
472
473 /**
474 * @return string
475 */
476 public static function apiKeyOpenAI(): string
477 {
478 $apiKey = get_option(Constants::AATXT_OPTION_FIELD_API_KEY_OPENAI);
479 return (Encryption::make())->decrypt($apiKey);
480 }
481
482 /**
483 * @return string
484 */
485 public static function apiKeyAzureComputerVision(): string
486 {
487 $apiKey = get_option(Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_COMPUTER_VISION);
488 return (Encryption::make())->decrypt($apiKey);
489 }
490
491 /**
492 * @return string
493 */
494 public static function endpointAzureComputerVision(): string
495 {
496 return get_option(Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_COMPUTER_VISION);
497 }
498
499 /**
500 * @return string
501 */
502 public static function apiKeyAzureTranslateInstance(): string
503 {
504 $apiKey = get_option(Constants::AATXT_OPTION_FIELD_API_KEY_AZURE_TRANSLATE_INSTANCE);
505 return (Encryption::make())->decrypt($apiKey);
506 }
507
508 /**
509 * @return string
510 */
511 public static function endpointAzureTranslateInstance(): string
512 {
513 return get_option(Constants::AATXT_OPTION_FIELD_ENDPOINT_AZURE_TRANSLATE_INSTANCE);
514 }
515
516 /**
517 * @return string
518 */
519 public static function regionAzureTranslateInstance(): string
520 {
521 return get_option(Constants::AATXT_OPTION_FIELD_REGION_AZURE_TRANSLATE_INSTANCE);
522 }
523
524 /**
525 * @return string
526 */
527 public static function languageAzureTranslateInstance(): string
528 {
529 return get_option(Constants::AATXT_OPTION_FIELD_LANGUAGE_AZURE_TRANSLATE_INSTANCE) ?: 'en';
530 }
531
532 /**
533 * @return bool
534 */
535 public static function preserveExistingAltText(): bool
536 {
537 return get_option(Constants::AATXT_OPTION_FIELD_PRESERVE_EXISTING_ALT_TEXT);
538 }
539
540 public static function sanitizeUrl($input): string
541 {
542 return sanitize_url($input);
543 }
544
545 public static function sanitizeText($input): string
546 {
547 return sanitize_text_field($input);
548 }
549
550 public static function sanitizeTextArea($input): string
551 {
552 return sanitize_textarea_field($input);
553 }
554 }
555