| 1 |
<?php |
| 2 |
/** |
| 3 |
* @package SheetsPilot |
| 4 |
* @author Unlimited Elements |
| 5 |
* @copyright (C) 2026 Unlimited Elements, All Rights Reserved. |
| 6 |
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html |
| 7 |
**/ |
| 8 |
if ( ! defined( 'ABSPATH' ) ) exit; |
| 9 |
if(!defined("SHEETSPILOT_INC")) die("restricted access"); |
| 10 |
|
| 11 |
class SheetsPilot_PluginAdmin{ |
| 12 |
|
| 13 |
private static $arrMenuPages = array(); |
| 14 |
private static $arrSubMenuPages = array(); |
| 15 |
public static $view; |
| 16 |
public static $isInsidePlugin = false; |
| 17 |
private $screen; |
| 18 |
|
| 19 |
const PRO_PLUGIN_BASENAME = 'sheetspilot-premium/sheetspilot-pro.php'; |
| 20 |
|
| 21 |
/** Used for DB schema upgrades on plugin update (match unlimited-elements pattern). */ |
| 22 |
const DB_VERSION = '9'; |
| 23 |
const OPTION_DB_VERSION = 'sheetspilot_db_version'; |
| 24 |
|
| 25 |
const DEBUG_SCREEN_ID = false; |
| 26 |
|
| 27 |
/** |
| 28 |
* Runs on plugin activation. Creates the logs table if it does not exist. |
| 29 |
*/ |
| 30 |
public static function onPluginActivation(){ |
| 31 |
if ( ! class_exists( 'SheetsPilotGlobals' ) ) { |
| 32 |
return; |
| 33 |
} |
| 34 |
self::createLogsTable(); |
| 35 |
self::createPromptsTable(); |
| 36 |
} |
| 37 |
|
| 38 |
/** |
| 39 |
* Check DB version on admin_init; run createLogsTable( true ) when version changes so dbDelta can update schema. |
| 40 |
*/ |
| 41 |
public static function checkDBUpgrade(){ |
| 42 |
if ( ! class_exists( 'SheetsPilotGlobals' ) ) { |
| 43 |
return; |
| 44 |
} |
| 45 |
$saved = get_option( self::OPTION_DB_VERSION ); |
| 46 |
|
| 47 |
if ( $saved !== self::DB_VERSION ) { |
| 48 |
self::createLogsTable( true ); |
| 49 |
self::createPromptsTable( true ); |
| 50 |
update_option( self::OPTION_DB_VERSION, self::DB_VERSION ); |
| 51 |
} |
| 52 |
} |
| 53 |
|
| 54 |
/** |
| 55 |
* Create the logs table for request/response logging. |
| 56 |
* When $isForce is false, does nothing if table already exists (like unlimited-elements createTable). |
| 57 |
* When $isForce is true, runs dbDelta anyway so schema can be updated on plugin upgrade. |
| 58 |
* |
| 59 |
* @param bool $isForce If true, run dbDelta even when table exists (for upgrades). |
| 60 |
*/ |
| 61 |
public static function createLogsTable( $isForce = false ){ |
| 62 |
|
| 63 |
global $wpdb; |
| 64 |
|
| 65 |
$table_name = SheetsPilotGlobals::$tableLogs; |
| 66 |
$charset_collate = $wpdb->get_charset_collate(); |
| 67 |
|
| 68 |
if ( $isForce === false ) { |
| 69 |
$existing_table = $wpdb->get_var( |
| 70 |
$wpdb->prepare( |
| 71 |
"SHOW TABLES LIKE %s", |
| 72 |
$table_name |
| 73 |
) |
| 74 |
); |
| 75 |
if ( $existing_table === $table_name ) { |
| 76 |
return; |
| 77 |
} |
| 78 |
} |
| 79 |
|
| 80 |
require_once ABSPATH . 'wp-admin/includes/upgrade.php'; |
| 81 |
|
| 82 |
// dbDelta format: PRIMARY KEY with two spaces before (id); use KEY not INDEX; one field per line. |
| 83 |
$sql = "CREATE TABLE " . $table_name . " ( |
| 84 |
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
| 85 |
prompt TEXT NULL, |
| 86 |
cell_value LONGTEXT NULL, |
| 87 |
request LONGTEXT NULL, |
| 88 |
response LONGTEXT NULL, |
| 89 |
response_data LONGTEXT NULL, |
| 90 |
response_action VARCHAR(32) NULL, |
| 91 |
metadata LONGTEXT NULL, |
| 92 |
userid BIGINT(20) UNSIGNED NULL, |
| 93 |
date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, |
| 94 |
comments TEXT NULL, |
| 95 |
PRIMARY KEY (id), |
| 96 |
KEY userid (userid) |
| 97 |
) " . $charset_collate . ";"; |
| 98 |
|
| 99 |
dbDelta( $sql ); |
| 100 |
} |
| 101 |
|
| 102 |
/** |
| 103 |
* Create the prompts table. |
| 104 |
* When $isForce is false, does nothing if table already exists. |
| 105 |
* When $isForce is true, runs dbDelta anyway so schema can be updated on plugin upgrade. |
| 106 |
* |
| 107 |
* @param bool $isForce If true, run dbDelta even when table exists (for upgrades). |
| 108 |
*/ |
| 109 |
public static function createPromptsTable( $isForce = false ){ |
| 110 |
|
| 111 |
global $wpdb; |
| 112 |
|
| 113 |
$table_name = SheetsPilotGlobals::$tablePrompts; |
| 114 |
$charset_collate = $wpdb->get_charset_collate(); |
| 115 |
|
| 116 |
if ( $isForce === false ) { |
| 117 |
$existing_table = $wpdb->get_var( |
| 118 |
$wpdb->prepare( |
| 119 |
"SHOW TABLES LIKE %s", |
| 120 |
$table_name |
| 121 |
) |
| 122 |
); |
| 123 |
if ( $existing_table === $table_name ) { |
| 124 |
return; |
| 125 |
} |
| 126 |
} |
| 127 |
|
| 128 |
require_once ABSPATH . 'wp-admin/includes/upgrade.php'; |
| 129 |
|
| 130 |
$sql = "CREATE TABLE " . $table_name . " ( |
| 131 |
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
| 132 |
text TEXT NULL, |
| 133 |
description VARCHAR(255) NULL, |
| 134 |
is_latest TINYINT(1) NOT NULL DEFAULT 0, |
| 135 |
is_saved TINYINT(1) NOT NULL DEFAULT 0, |
| 136 |
is_favorite TINYINT(1) NOT NULL DEFAULT 0, |
| 137 |
userid BIGINT(20) UNSIGNED NULL, |
| 138 |
post_type VARCHAR(64) NULL, |
| 139 |
postid BIGINT(20) UNSIGNED NULL, |
| 140 |
date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, |
| 141 |
comments TEXT NULL, |
| 142 |
prompt_type TEXT NULL, |
| 143 |
PRIMARY KEY (id), |
| 144 |
KEY userid (userid) |
| 145 |
) " . $charset_collate . ";"; |
| 146 |
|
| 147 |
dbDelta( $sql ); |
| 148 |
} |
| 149 |
|
| 150 |
/** |
| 151 |
* call init |
| 152 |
*/ |
| 153 |
public function __construct(){ |
| 154 |
|
| 155 |
$this->init(); |
| 156 |
|
| 157 |
// remove notifications from editor page |
| 158 |
add_action('admin_init', [ $this, 'removeNotificationsFromEditorPage' ]); |
| 159 |
|
| 160 |
// drop image generation query |
| 161 |
if( isset( $_GET['drop_query'] ) ){ |
| 162 |
SheetsPilot_PluginAdmin::dropImageQueueRequests(); |
| 163 |
} |
| 164 |
|
| 165 |
} |
| 166 |
|
| 167 |
|
| 168 |
/** |
| 169 |
* add admin menus from the list. |
| 170 |
*/ |
| 171 |
public function addAdminMenu(){ |
| 172 |
|
| 173 |
$pageTitle = "SheetsPilot"; |
| 174 |
if ( SheetsPilotGlobals::$isPro ) { |
| 175 |
$pageTitle = "SheetsPilot Pro"; |
| 176 |
} |
| 177 |
|
| 178 |
$menuTitle = $pageTitle; |
| 179 |
$menuSlug = "sheetspilot"; |
| 180 |
$function = array($this, "adminPages"); |
| 181 |
|
| 182 |
//SheetsPilotGlobals::$urlImages."unlimited-ai-menu-icon.svg" |
| 183 |
$svg_icon = '<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M16 0.315432V7.49984L13.1962 7.51684C13.1998 7.52818 13.1925 7.50551 13.1962 7.51684C12.0605 7.71454 11.2004 8.76033 11.2004 9.99933C11.2004 10.9097 10.9665 11.7642 10.5579 12.4995C10.3977 12.7879 10.2103 13.058 10 13.3061C9.4651 13.9382 8.7797 14.428 8.00121 14.7145C7.50076 14.8989 6.96162 14.9991 6.40012 14.9991V17.4992C6.6709 17.4992 6.93805 17.4835 7.20036 17.4532C8.21154 17.3367 9.15926 17.0024 10 16.4956C10.663 16.0964 11.259 15.5902 11.7661 14.9997C11.8459 14.9072 11.9238 14.8121 11.9988 14.7151C12.5089 14.0591 12.9145 13.3117 13.1901 12.5002C13.1937 12.4888 13.1979 12.4775 13.2016 12.4655C13.4597 11.6937 13.5998 10.8638 13.5998 10H16C16 10.0214 16 10.0428 15.9994 10.0648C15.9946 10.9053 15.89 11.7207 15.6972 12.5002C15.4935 13.3268 15.1901 14.1126 14.8014 14.8422C14.7737 14.8952 14.7446 14.9481 14.7156 15.0003C14.3953 15.5777 14.0211 16.1178 13.5998 16.6146C13.349 16.9105 13.0819 17.1907 12.7996 17.4539C11.9807 18.2176 11.0354 18.8365 10 19.2728C8.88849 19.7412 7.67302 20 6.40012 20C5.57147 20 4.7676 19.8904 4 19.6846V12.5002L6.80387 12.4832C6.8075 12.4945 6.80024 12.4718 6.80387 12.4832C7.93956 12.2855 8.79964 11.2397 8.79964 10.0007C8.79964 9.09025 9.03354 8.23585 9.44213 7.50048C9.6023 7.21212 9.78966 6.94202 10 6.69395C10.5349 6.06182 11.2203 5.57199 11.9988 5.28552C12.4993 5.10105 13.0384 5.00094 13.5998 5.00094V2.50078C13.3291 2.50078 13.0619 2.51652 12.7996 2.54675C11.7885 2.66322 10.8407 2.99754 10 3.50437C9.33696 3.90354 8.74101 4.40975 8.23391 5.00032C8.15413 5.09287 8.07616 5.18793 8.00121 5.2849C7.49109 5.94094 7.08553 6.68828 6.80991 7.49984C6.80629 7.51118 6.80206 7.52251 6.79843 7.53447C6.54034 8.30637 6.40012 9.13617 6.40012 10H4.0006C4.0006 9.97858 4.0006 9.95717 4.00121 9.93517C4.00604 9.09467 4.11061 8.27929 4.30342 7.49984C4.5071 6.67318 4.81052 5.88742 5.19915 5.15772C5.22696 5.10482 5.25597 5.05194 5.28498 4.99968C5.60532 4.42234 5.97945 3.88214 6.40073 3.38538C6.65156 3.08947 6.9187 2.80929 7.20097 2.54612C8.01994 1.78241 8.96525 1.16351 10.0006 0.727192C11.1121 0.258138 12.327 0 13.5998 0C14.4286 0 15.2324 0.109551 16 0.315432Z" fill="#F0F0F1"/></svg>'; |
| 184 |
|
| 185 |
$icon_data = 'data:image/svg+xml;base64,' . base64_encode($svg_icon); |
| 186 |
|
| 187 |
add_menu_page($pageTitle, $pageTitle, SheetsPilotGlobals::$capability, $menuSlug, $function, $icon_data); |
| 188 |
|
| 189 |
$prefix = 'sheetspilot'; |
| 190 |
|
| 191 |
//add sub menu page |
| 192 |
|
| 193 |
add_submenu_page( $menuSlug, "Posts Editor", "Posts Editor", SheetsPilotGlobals::$capability, $prefix, $function); |
| 194 |
if ( SheetsPilotGlobals::$isPro ) { |
| 195 |
add_submenu_page( $menuSlug, "Settings", "Settings", SheetsPilotGlobals::$capability, $prefix."_settings", $function); |
| 196 |
add_submenu_page( $menuSlug, "Log", "Log", SheetsPilotGlobals::$capability, $prefix."_log", $function); |
| 197 |
add_submenu_page( |
| 198 |
$menuSlug, |
| 199 |
__( 'Tools', 'sheetspilot' ), |
| 200 |
__( 'Tools', 'sheetspilot' ), |
| 201 |
SheetsPilotGlobals::$capability, |
| 202 |
$prefix . '_prompt_tester', |
| 203 |
$function |
| 204 |
); |
| 205 |
} |
| 206 |
|
| 207 |
} |
| 208 |
|
| 209 |
|
| 210 |
/** |
| 211 |
* init view |
| 212 |
*/ |
| 213 |
private function initView(){ |
| 214 |
|
| 215 |
|
| 216 |
$defaultView = SheetsPilotGlobals::DEFAULT_VIEW; |
| 217 |
|
| 218 |
//set view |
| 219 |
$viewInput = SheetsPilotFunctions::getGetVar("view","",SheetsPilotFunctions::SANITIZE_KEY); |
| 220 |
$page = SheetsPilotFunctions::getGetVar("page","",SheetsPilotFunctions::SANITIZE_KEY); |
| 221 |
|
| 222 |
if(strpos($page, 'sheetspilot') === 0) |
| 223 |
self::$isInsidePlugin = true; |
| 224 |
|
| 225 |
// Legacy URL from the old standalone "Tools" menu (kept so bookmarks keep working). |
| 226 |
if ( $page === 'sheetspilot_tools_prompt_tester' ) { |
| 227 |
self::$view = SheetsPilotGlobals::VIEW_PROMPT_TESTER; |
| 228 |
return false; |
| 229 |
} |
| 230 |
|
| 231 |
//get the view out of the page |
| 232 |
if(!empty($viewInput)){ |
| 233 |
self::$view = $viewInput; |
| 234 |
return(false); |
| 235 |
} |
| 236 |
|
| 237 |
if ( $page === 'sheetspilot' ) { |
| 238 |
self::$view = SheetsPilotGlobals::VIEW_POSTEDITOR; |
| 239 |
return(false); |
| 240 |
} |
| 241 |
|
| 242 |
//check bottom devider |
| 243 |
$deviderPos = strpos($page,"_"); |
| 244 |
|
| 245 |
if($deviderPos !== false){ |
| 246 |
|
| 247 |
self::$view = substr($page, $deviderPos+1); |
| 248 |
return(false); |
| 249 |
} |
| 250 |
|
| 251 |
//check middle devider |
| 252 |
$deviderPos = strpos($page, "-"); |
| 253 |
if($deviderPos !== false){ |
| 254 |
self::$view = substr($page, $deviderPos+1); |
| 255 |
|
| 256 |
return(false); |
| 257 |
} |
| 258 |
|
| 259 |
self::$view = $defaultView; |
| 260 |
|
| 261 |
} |
| 262 |
|
| 263 |
|
| 264 |
/** |
| 265 |
* open admin pages |
| 266 |
*/ |
| 267 |
public function adminPages(){ |
| 268 |
|
| 269 |
try{ |
| 270 |
|
| 271 |
if ( |
| 272 |
SheetsPilotGlobals::$isPro === false && |
| 273 |
( |
| 274 |
self::$view === SheetsPilotGlobals::VIEW_SETTINGS || |
| 275 |
self::$view === SheetsPilotGlobals::VIEW_LOG || |
| 276 |
self::$view === SheetsPilotGlobals::VIEW_PROMPT_HISTORY || |
| 277 |
self::$view === SheetsPilotGlobals::VIEW_PROMPT_TESTER |
| 278 |
) |
| 279 |
) { |
| 280 |
self::$view = SheetsPilotGlobals::VIEW_POSTEDITOR; |
| 281 |
} |
| 282 |
|
| 283 |
// its global full version |
| 284 |
if( SHEETS_PLUGIN_IS_GLOBAL_DEV ){ |
| 285 |
$path_to_view = SheetsPilotGlobals::$pathPlugin.'/pro/'; |
| 286 |
}else{ |
| 287 |
$path_to_view = SheetsPilotGlobals::$pathPluginPro; |
| 288 |
} |
| 289 |
|
| 290 |
if ( self::$view === SheetsPilotGlobals::VIEW_SETTINGS ) { |
| 291 |
$pathView = $path_to_view . 'views/settings.php'; |
| 292 |
} elseif ( self::$view === SheetsPilotGlobals::VIEW_LOG ) { |
| 293 |
$pathView = $path_to_view . 'views/log.php'; |
| 294 |
if ( ! class_exists( 'SheetsPilot_PluginViewLog', false ) ) { |
| 295 |
require_once $pathView; |
| 296 |
} |
| 297 |
new SheetsPilot_PluginViewLog(); |
| 298 |
return; |
| 299 |
} elseif ( self::$view === SheetsPilotGlobals::VIEW_PROMPT_HISTORY ) { |
| 300 |
$pathView = $path_to_view . 'views/prompt_history.php'; |
| 301 |
} elseif ( self::$view === SheetsPilotGlobals::VIEW_PROMPT_TESTER ) { |
| 302 |
$pathView = $path_to_view . 'views/prompt_tester.php'; |
| 303 |
} else { |
| 304 |
$pathView = SheetsPilotHelper::getPathView( self::$view ); |
| 305 |
} |
| 306 |
|
| 307 |
require $pathView; |
| 308 |
|
| 309 |
}catch(Exception $e){ |
| 310 |
|
| 311 |
echo "<br>"; |
| 312 |
|
| 313 |
SheetsPilotHelper::outputExceptionBox($e, SheetsPilotGlobals::PLUGIN_TITLE." error"); |
| 314 |
|
| 315 |
} |
| 316 |
} |
| 317 |
|
| 318 |
|
| 319 |
/** |
| 320 |
* add inside scripts |
| 321 |
*/ |
| 322 |
public function onAddScripts(){ |
| 323 |
|
| 324 |
//---- add js scripts |
| 325 |
|
| 326 |
switch(self::$view){ |
| 327 |
case SheetsPilotGlobals::VIEW_WELCOME: |
| 328 |
case SheetsPilotGlobals::VIEW_SETTINGS: |
| 329 |
|
| 330 |
SheetsPilotHelper::addStyle("unlimited_ai_admin"); |
| 331 |
SheetsPilotHelper::addStyle("unlimited_ai_styles"); |
| 332 |
$codemirror_css_url = SheetsPilotGlobals::$urlPlugin . 'assets/libraries/codemirror-custom/codemirror-custom.css'; |
| 333 |
SheetsPilotHelper::addStyleAbsoluteUrl($codemirror_css_url, 'sheetspilot' . '-codemirror'); |
| 334 |
SheetsPilotHelper::addScript("unlimited_ai_provider_admin"); |
| 335 |
SheetsPilotHelper::addScript("unlimited_ai_admin"); |
| 336 |
$codemirror_js_url = SheetsPilotGlobals::$urlPlugin . 'assets/libraries/codemirror-custom/codemirror-custom.min.js'; |
| 337 |
SheetsPilotHelper::addScriptAbsoluteUrl($codemirror_js_url, 'sheetspilot' . '-codemirror', true, array()); |
| 338 |
SheetsPilotHelper::addScript("unlimited_ai_settings"); |
| 339 |
SheetsPilotHelper::addScript("unlimited_ai_view_settings"); |
| 340 |
|
| 341 |
break; |
| 342 |
case SheetsPilotGlobals::VIEW_LOG: |
| 343 |
case SheetsPilotGlobals::VIEW_PROMPT_HISTORY: |
| 344 |
SheetsPilotHelper::addStyle("unlimited_ai_admin"); |
| 345 |
SheetsPilotHelper::addStyle("unlimited_ai_styles"); |
| 346 |
break; |
| 347 |
case SheetsPilotGlobals::VIEW_PROMPT_TESTER: |
| 348 |
wp_enqueue_media(); |
| 349 |
SheetsPilotHelper::addStyle("unlimited_ai_admin"); |
| 350 |
SheetsPilotHelper::addStyle("unlimited_ai_styles"); |
| 351 |
$prompt_tester_js_url = SHEETS_PLUGIN_IS_GLOBAL_DEV |
| 352 |
? SheetsPilotGlobals::$urlPlugin . 'pro/assets/js/prompt_tester.js' |
| 353 |
: SheetsPilotGlobals::$urlPluginPro . 'assets/js/prompt_tester.js'; |
| 354 |
SheetsPilotHelper::addScriptAbsoluteUrl( |
| 355 |
$prompt_tester_js_url, |
| 356 |
'sheetspilot-prompt-tester', |
| 357 |
true, |
| 358 |
array( 'jquery' ) |
| 359 |
); |
| 360 |
break; |
| 361 |
case SheetsPilotGlobals::VIEW_POSTEDITOR: |
| 362 |
wp_enqueue_media(); |
| 363 |
wp_enqueue_editor(); |
| 364 |
|
| 365 |
SheetsPilotHelper::addScript("unlimited_ai_image_preview" ); |
| 366 |
SheetsPilotHelper::addScript("sheetspilot_posteditor_variables", null, "assets/js", true ); |
| 367 |
SheetsPilotHelper::addScript("sheetspilot_posteditor_main", null, "assets/js", true ); |
| 368 |
|
| 369 |
SheetsPilotHelper::addInlineLocalization( [] ); |
| 370 |
|
| 371 |
SheetsPilotHelper::addStyle("unlimited_ai_admin"); |
| 372 |
SheetsPilotHelper::addStyle("unlimited_ai_postseditor_styles"); |
| 373 |
SheetsPilotHelper::addStyle("content-rules-dialog"); |
| 374 |
SheetsPilotHelper::addStyle("before_after_image"); |
| 375 |
$codemirror_css_url_pe = SheetsPilotGlobals::$urlPlugin . 'assets/libraries/codemirror-custom/codemirror-custom.css'; |
| 376 |
SheetsPilotHelper::addStyleAbsoluteUrl($codemirror_css_url_pe, 'sheetspilot' . '-codemirror'); |
| 377 |
SheetsPilotHelper::addScript("unlimited_ai_provider_admin"); |
| 378 |
SheetsPilotHelper::addScript("unlimited_ai_admin"); |
| 379 |
$codemirror_js_url_pe = SheetsPilotGlobals::$urlPlugin . 'assets/libraries/codemirror-custom/codemirror-custom.min.js'; |
| 380 |
SheetsPilotHelper::addScriptAbsoluteUrl($codemirror_js_url_pe, 'sheetspilot' . '-codemirror', true, array()); |
| 381 |
$showhint_js_url = SheetsPilotGlobals::$urlPlugin . 'assets/libraries/codemirror-custom/addon/hint/show-hint.js'; |
| 382 |
SheetsPilotHelper::addScriptAbsoluteUrl($showhint_js_url, 'sheetspilot' . '-codemirror-show-hint', true, array('sheetspilot' . '-codemirror')); |
| 383 |
$showhint_css_url = SheetsPilotGlobals::$urlPlugin . 'assets/libraries/codemirror-custom/addon/hint/show-hint.css'; |
| 384 |
SheetsPilotHelper::addStyleAbsoluteUrl($showhint_css_url, 'sheetspilot' . '-codemirror-show-hint'); |
| 385 |
|
| 386 |
SheetsPilotHelper::addLibraryScript('thickbox'); |
| 387 |
SheetsPilotHelper::addLibraryStyle('thickbox'); |
| 388 |
|
| 389 |
SheetsPilotHelper::addLibraryScript('jquery-ui-tooltip'); |
| 390 |
SheetsPilotHelper::addLibraryStyle('wp-jquery-ui-dialog'); |
| 391 |
|
| 392 |
SheetsPilotHelper::addLibraryScript('jquery-ui-core'); |
| 393 |
SheetsPilotHelper::addLibraryScript('jquery-ui-widget'); |
| 394 |
SheetsPilotHelper::addLibraryScript('jquery-ui-mouse'); |
| 395 |
SheetsPilotHelper::addLibraryScript('jquery-ui-position'); |
| 396 |
SheetsPilotHelper::addLibraryScript('jquery-effects-core'); |
| 397 |
|
| 398 |
SheetsPilotHelper::addScript("unlimited_ai_small_modal"); |
| 399 |
|
| 400 |
SheetsPilotHelper::addScript("sheetspilot_drawer_fn"); |
| 401 |
SheetsPilotHelper::addScript("sheetspilot_attributes_editor"); |
| 402 |
SheetsPilotHelper::addScript("sheetspilot_variable_product"); |
| 403 |
SheetsPilotHelper::addScript("sheetspilot_notification_fn"); |
| 404 |
SheetsPilotHelper::addScript("sheetspilot_repeater_editor"); |
| 405 |
SheetsPilotHelper::addScript("sheetspilot_top_filtering_bar"); |
| 406 |
SheetsPilotHelper::addScript("unlimited_ai_postseditor"); |
| 407 |
SheetsPilotHelper::addScript("before_after_image"); |
| 408 |
SheetsPilotHelper::addScript( "unlimited_ai_prompts", null, "assets/js", false, true ); |
| 409 |
SheetsPilotHelper::addScript("unlimited_ai_cell_processing"); |
| 410 |
SheetsPilotHelper::addScript("unlimited_ai_content_rules"); |
| 411 |
|
| 412 |
|
| 413 |
|
| 414 |
SheetsPilotHelper::addScript("select2.min"); |
| 415 |
SheetsPilotHelper::addStyle("select2.min"); |
| 416 |
SheetsPilotHelper::addStyle("bootstrap.min"); |
| 417 |
|
| 418 |
|
| 419 |
|
| 420 |
|
| 421 |
break; |
| 422 |
} |
| 423 |
|
| 424 |
//---- add css styles |
| 425 |
|
| 426 |
if(SheetsPilotGlobals::$enableCopy == true || SheetsPilotGlobals::$enablePaste == true) |
| 427 |
$this->onIncludeFrontScripts(); |
| 428 |
|
| 429 |
|
| 430 |
} |
| 431 |
|
| 432 |
|
| 433 |
/** |
| 434 |
* add outside scripts |
| 435 |
*/ |
| 436 |
public function onAddOutsideScripts(){ |
| 437 |
|
| 438 |
//add scripts on outside |
| 439 |
|
| 440 |
} |
| 441 |
|
| 442 |
|
| 443 |
/** |
| 444 |
* register settings for the settings page |
| 445 |
*/ |
| 446 |
public function onAdminInit(){ |
| 447 |
//register settings to save |
| 448 |
register_setting( SheetsPilotGlobals::OPTIONS_GROUP_NAME, 'sheetspilot_general_settings', |
| 449 |
[ |
| 450 |
'type' => 'array', |
| 451 |
'sanitize_callback' => [self::class, 'sanitizeGeneralSettings'], |
| 452 |
] |
| 453 |
); |
| 454 |
|
| 455 |
} |
| 456 |
|
| 457 |
/** |
| 458 |
* sanitize settings |
| 459 |
*/ |
| 460 |
public static function sanitizeGeneralSettings($input) |
| 461 |
{ |
| 462 |
if (!is_array($input)) { |
| 463 |
return []; |
| 464 |
} |
| 465 |
|
| 466 |
$output = []; |
| 467 |
|
| 468 |
|
| 469 |
$output['openai_key'] = isset($input['openai_key']) |
| 470 |
? sanitize_text_field($input['openai_key']) |
| 471 |
: ''; |
| 472 |
$output['openai_model'] = isset($input['openai_model']) |
| 473 |
? sanitize_text_field($input['openai_model']) |
| 474 |
: ''; |
| 475 |
|
| 476 |
$output['enable_debug_prompt_tool'] = ( isset( $input['enable_debug_prompt_tool'] ) && '1' === (string) $input['enable_debug_prompt_tool'] ) |
| 477 |
? '1' : '0'; |
| 478 |
|
| 479 |
$output['enable_debug_prompt_request'] = ( isset( $input['enable_debug_prompt_request'] ) && '1' === (string) $input['enable_debug_prompt_request'] ) |
| 480 |
? '1' : '0'; |
| 481 |
|
| 482 |
$output['showSessionLog'] = ( isset( $input['showSessionLog'] ) && '1' === (string) $input['showSessionLog'] ) |
| 483 |
? '1' : '0'; |
| 484 |
|
| 485 |
return $output; |
| 486 |
} |
| 487 |
|
| 488 |
/** |
| 489 |
* on ajax actions |
| 490 |
*/ |
| 491 |
public function onAjaxActions(){ |
| 492 |
|
| 493 |
$objActions = new SheetsPilot_AjaxActions(); |
| 494 |
$objActions->onAjaxActions(); |
| 495 |
} |
| 496 |
|
| 497 |
|
| 498 |
/** |
| 499 |
* init the class |
| 500 |
*/ |
| 501 |
public function init(){ |
| 502 |
|
| 503 |
$this->initView(); |
| 504 |
|
| 505 |
$main_plugin_file = SheetsPilotGlobals::$pathPlugin . 'unlimited-ai.php'; |
| 506 |
register_activation_hook( $main_plugin_file, array( __CLASS__, 'onPluginActivation' ) ); |
| 507 |
|
| 508 |
add_action("admin_menu", array($this, "addAdminMenu")); |
| 509 |
|
| 510 |
if(self::$isInsidePlugin == true) |
| 511 |
add_action("admin_enqueue_scripts", array($this,"onAddScripts"), true); |
| 512 |
else |
| 513 |
add_action("admin_enqueue_scripts", array($this,"onAddOutsideScripts"), true); |
| 514 |
|
| 515 |
//register settings |
| 516 |
add_action("admin_init", array($this,"onAdminInit")); |
| 517 |
// DB version check: create/update logs table on first load or plugin update (same pattern as unlimited-elements) |
| 518 |
add_action("admin_init", array( __CLASS__, 'checkDBUpgrade' )); |
| 519 |
add_action( 'after_plugin_row_' . self::PRO_PLUGIN_BASENAME, array( $this, 'renderProVersionMismatchRowNotice' ), 10, 3 ); |
| 520 |
|
| 521 |
//register ajax |
| 522 |
add_action('wp_ajax_'.'sheetspilot'."_ajax_actions"."", array($this,"onAjaxActions"), true); |
| 523 |
add_action('wp_ajax_nopriv_'.'sheetspilot'."_ajax_actions", array($this,"onAjaxActions"), true); |
| 524 |
|
| 525 |
add_filter( 'safe_style_css', function( $styles ) { |
| 526 |
$styles[] = 'display'; |
| 527 |
return $styles; |
| 528 |
}); |
| 529 |
|
| 530 |
} |
| 531 |
|
| 532 |
/** |
| 533 |
* Render a warning row under SheetsPilot Pro when active and versions mismatch. |
| 534 |
* |
| 535 |
* @param string $plugin_file Plugin basename. |
| 536 |
* @param array $plugin_data Plugin header data. |
| 537 |
* @param string $status Row status. |
| 538 |
* @return void |
| 539 |
*/ |
| 540 |
public function renderProVersionMismatchRowNotice( $plugin_file, $plugin_data, $status ) { |
| 541 |
if ( ! defined( 'SHEETSPILOT_PRO_PLUGIN_ACTIVE' ) || SHEETSPILOT_PRO_PLUGIN_ACTIVE !== true ) { |
| 542 |
return; |
| 543 |
} |
| 544 |
if ( ! defined( 'SHEETSPILOT_PRO_VERSION_MATCH' ) || SHEETSPILOT_PRO_VERSION_MATCH === true ) { |
| 545 |
return; |
| 546 |
} |
| 547 |
|
| 548 |
$free_version = defined( 'SHEETSPILOT_FREE_VERSION' ) ? (string) SHEETSPILOT_FREE_VERSION : ''; |
| 549 |
$pro_version = defined( 'SHEETSPILOT_PRO_VERSION' ) ? (string) SHEETSPILOT_PRO_VERSION : ''; |
| 550 |
$pro_min = defined( 'SHEETSPILOT_PRO_VERSION_COMPATABE_FROM' ) ? (string) SHEETSPILOT_PRO_VERSION_COMPATABE_FROM : $free_version; |
| 551 |
$message = sprintf( |
| 552 |
/* translators: 1: free version, 2: pro version, 3: minimum compatible pro version */ |
| 553 |
__( 'SheetsPilot Pro is incompatible with this SheetsPilot version. Free: %1$s, Pro: %2$s. Pro must be between %3$s and %1$s. Pro is disabled until versions are compatible.', 'sheetspilot' ), |
| 554 |
$free_version !== '' ? $free_version : 'unknown', |
| 555 |
$pro_version !== '' ? $pro_version : 'unknown', |
| 556 |
$pro_min !== '' ? $pro_min : 'unknown' |
| 557 |
); |
| 558 |
?> |
| 559 |
<tr class="plugin-update-tr active"> |
| 560 |
<td colspan="3" class="plugin-update colspanchange"> |
| 561 |
<div class="update-message notice inline notice-error notice-alt"> |
| 562 |
<p><?php echo esc_html( $message ); ?></p> |
| 563 |
</div> |
| 564 |
</td> |
| 565 |
</tr> |
| 566 |
<?php |
| 567 |
} |
| 568 |
|
| 569 |
/** |
| 570 |
* remove page notifications |
| 571 |
*/ |
| 572 |
function removeNotificationsFromEditorPage(){ |
| 573 |
|
| 574 |
if ( isset($_GET['page']) && $_GET['page'] === 'sheetspilot' ) { |
| 575 |
remove_all_actions('admin_notices'); |
| 576 |
remove_all_actions('all_admin_notices'); |
| 577 |
remove_all_actions('network_admin_notices'); |
| 578 |
} |
| 579 |
|
| 580 |
} |
| 581 |
|
| 582 |
|
| 583 |
public static function dropImageQueueRequests(){ |
| 584 |
delete_option('sheetspilot_image_queue_list' ); |
| 585 |
} |
| 586 |
|
| 587 |
} |
| 588 |
|