| 1 |
<?php |
| 2 |
namespace PostSnippets; |
| 3 |
|
| 4 |
if ( ! defined( 'ABSPATH' ) ) exit; |
| 5 |
|
| 6 |
/** |
| 7 |
* Post Snippets Settings. |
| 8 |
* |
| 9 |
* Class that renders out the HTML for the settings screen and contains helpful |
| 10 |
* methods to simply the maintainance of the admin screen. |
| 11 |
* |
| 12 |
*/ |
| 13 |
class Admin |
| 14 |
{ |
| 15 |
/** |
| 16 |
* Plugin settings. |
| 17 |
* |
| 18 |
* @var array |
| 19 |
*/ |
| 20 |
protected $settings; |
| 21 |
|
| 22 |
public $_admin_page = 'post-snippets'; |
| 23 |
public $_admin_upgrade_page = 'https://postsnippets.com/pricing/'; |
| 24 |
|
| 25 |
// const GROUP_CLASS = 'PostSnippets\Group'; |
| 26 |
|
| 27 |
/** |
| 28 |
* Defines hooks and filters for admin page. |
| 29 |
*/ |
| 30 |
public function __construct() |
| 31 |
{ |
| 32 |
add_action('admin_menu', array(&$this, 'menu')); |
| 33 |
add_action('admin_init', array(&$this, 'init')); |
| 34 |
add_action('current_screen', array(&$this, 'addHeaderXss')); |
| 35 |
add_filter('plugin_action_links_' . plugin_basename(PS_MAIN_FILE_PATH), array( |
| 36 |
$this, |
| 37 |
'actionLinks' |
| 38 |
)); |
| 39 |
|
| 40 |
// Newsletter sign-up admin notice |
| 41 |
add_action('admin_notices', array($this, 'admin_notice_newsletter')); |
| 42 |
|
| 43 |
// Get started admin notice |
| 44 |
add_action('admin_notices', array($this, 'admin_notice_get_started')); |
| 45 |
|
| 46 |
// add_action( 'wp_ajax_sync_up', array( $this, 'sync_up' ) ); |
| 47 |
// add_action( 'wp_ajax_sync_down', array( $this, 'sync_down' ) ); |
| 48 |
|
| 49 |
add_action('init', array($this, 'load_block')); |
| 50 |
|
| 51 |
add_filter('set-screen-option', array($this, 'all_snippets_set_option'), 10, 3); |
| 52 |
|
| 53 |
add_action('wp_footer', array('PostSnippets\PSallSnippets', 'run_frontend_footer_js_css')); |
| 54 |
|
| 55 |
add_action('wp_head', array('PostSnippets\PSallSnippets', 'run_frontend_header_js')); |
| 56 |
|
| 57 |
add_action('admin_print_scripts', function () { |
| 58 |
|
| 59 |
PSallSnippets::run_admin_js_css(); |
| 60 |
|
| 61 |
}); |
| 62 |
|
| 63 |
add_action('admin_footer', array($this, 'chatbot_ai_modal') ); |
| 64 |
|
| 65 |
} |
| 66 |
|
| 67 |
/** |
| 68 |
* Render the chatbot modal HTML |
| 69 |
*/ |
| 70 |
public function chatbot_ai_modal() { |
| 71 |
if ( ! isset ( $_GET['page'] ) || ! in_array( $_GET['page'], ['post-snippets-edit','post-snippets-edit-css','post-snippets-edit-js'] ) ) { |
| 72 |
return; |
| 73 |
} |
| 74 |
|
| 75 |
?> |
| 76 |
<button id="chatbot-toggle" type="button" aria-label="Open AI Assistant"> |
| 77 |
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 78 |
<path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 13.5997 2.37562 15.1116 3.04346 16.4525L2.06947 20.4839C1.91746 21.1137 2.50286 21.6811 3.1255 21.5032L7.04504 20.3833C8.5447 21.4194 10.2032 22 12 22Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 79 |
<path d="M8 12H8.01" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 80 |
<path d="M12 12H12.01" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 81 |
<path d="M16 12H16.01" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 82 |
</svg> |
| 83 |
</button> |
| 84 |
|
| 85 |
<div id="chatbot-wrapper" style="display: none;"> |
| 86 |
<div id="chatbot-header"> |
| 87 |
<div class="header-main"> |
| 88 |
<h3><span class="status-dot"></span> AI Assistant</h3> |
| 89 |
</div> |
| 90 |
<div class="header-actions"> |
| 91 |
<button id="chatbot-close" type="button" aria-label="Close Assistant"> |
| 92 |
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 93 |
<path d="M13 1L1 13M1 1L13 13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 94 |
</svg> |
| 95 |
</button> |
| 96 |
</div> |
| 97 |
</div> |
| 98 |
<div id="chatbot-messages"></div> |
| 99 |
<div id="chatbot-input-container"> |
| 100 |
<textarea id="chatbot-input" rows="1" placeholder="Describe the code you need..."></textarea> |
| 101 |
<button id="chatbot-send" type="button" aria-label="Send message"> |
| 102 |
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 103 |
<path d="M22 2L11 13M22 2L15 22L11 13M11 13L2 9L22 2" /> |
| 104 |
</svg> |
| 105 |
</button> |
| 106 |
</div> |
| 107 |
</div> |
| 108 |
<?php |
| 109 |
} |
| 110 |
|
| 111 |
public function load_block() |
| 112 |
{ |
| 113 |
|
| 114 |
wp_register_script( |
| 115 |
'post-snippets-block', |
| 116 |
PS_URL . 'src/blocks/blocks.build.js', |
| 117 |
array('wp-blocks', 'wp-editor', 'wp-element') |
| 118 |
); |
| 119 |
|
| 120 |
register_block_type('greentreelabs/post-snippets-block', array( |
| 121 |
'editor_script' => 'post-snippets-block', |
| 122 |
// 'render_callback' => array($this, 'render_block_content'), |
| 123 |
'render_callback' => function ($attributes) { |
| 124 |
return PSallSnippets::render_block_content($attributes); |
| 125 |
}, |
| 126 |
)); |
| 127 |
|
| 128 |
wp_localize_script('post-snippets-block', 'all_snippets', array( |
| 129 |
|
| 130 |
'all_snippets' => PSallSnippets::get_all_snippets_gutenberg() |
| 131 |
|
| 132 |
)); |
| 133 |
|
| 134 |
} |
| 135 |
|
| 136 |
// ------------------------------------------------------------------------- |
| 137 |
// Setup |
| 138 |
// ------------------------------------------------------------------------- |
| 139 |
|
| 140 |
/** |
| 141 |
* Register the administration page. |
| 142 |
* |
| 143 |
* @return void |
| 144 |
*/ |
| 145 |
public function menu() |
| 146 |
{ |
| 147 |
$capability = $this->get_allowed_capability(); |
| 148 |
|
| 149 |
if ($capability == 'edit_posts') { |
| 150 |
$allowed = true; |
| 151 |
} |
| 152 |
|
| 153 |
if (current_user_can('manage_options') or isset($allowed)) { |
| 154 |
|
| 155 |
$optionPage = add_menu_page( |
| 156 |
__('Post Snippets', 'post-snippets'), |
| 157 |
__('Post Snippets', 'post-snippets'), |
| 158 |
$capability, |
| 159 |
'post-snippets', |
| 160 |
array( |
| 161 |
$this, |
| 162 |
'allSnippetsPage', |
| 163 |
), |
| 164 |
PS_URL . 'assets/icon.svg' |
| 165 |
); |
| 166 |
|
| 167 |
add_action("load-$optionPage", array($this, 'add_screen_options')); |
| 168 |
|
| 169 |
|
| 170 |
$allSnippets = add_submenu_page( |
| 171 |
'post-snippets', |
| 172 |
__('All Snippets', 'post-snippets'), |
| 173 |
__('All Snippets', 'post-snippets'), |
| 174 |
$capability, |
| 175 |
'post-snippets', |
| 176 |
array( |
| 177 |
$this, |
| 178 |
'allSnippetsPage', |
| 179 |
) |
| 180 |
); |
| 181 |
|
| 182 |
$editSnippets = add_submenu_page( |
| 183 |
'post-snippets', |
| 184 |
__('Add Custom Code', 'post-snippets'), |
| 185 |
__('Add Custom Code', 'post-snippets'), |
| 186 |
$capability, |
| 187 |
'post-snippets-edit', |
| 188 |
array( |
| 189 |
$this, |
| 190 |
'editPage', |
| 191 |
) |
| 192 |
); |
| 193 |
|
| 194 |
add_action('load-' . $editSnippets, array(\PostSnippets::EDIT_CLASS, 'page_actions'), 9); |
| 195 |
add_action('admin_footer-' . $editSnippets, array(\PostSnippets::EDIT_CLASS, 'footer_scripts')); |
| 196 |
add_filter('admin_title', array(\PostSnippets::EDIT_CLASS, 'change_edit_snippet_page_title'), 10, 2); |
| 197 |
|
| 198 |
/**Add CSS */ |
| 199 |
$editCSS = add_submenu_page( |
| 200 |
'post-snippets', |
| 201 |
__('Add Custom CSS', 'post-snippets'), |
| 202 |
__('Add Custom CSS', 'post-snippets'), |
| 203 |
$capability, |
| 204 |
'post-snippets-edit-css', |
| 205 |
array( |
| 206 |
$this, |
| 207 |
'editPage', |
| 208 |
) |
| 209 |
); |
| 210 |
|
| 211 |
add_action('load-' . $editCSS, array(\PostSnippets::EDIT_CLASS, 'page_actions'), 9); |
| 212 |
add_action('admin_footer-' . $editCSS, array(\PostSnippets::EDIT_CLASS, 'footer_scripts')); |
| 213 |
add_filter('admin_title', array(\PostSnippets::EDIT_CLASS, 'change_edit_snippet_page_title'), 10, 2); |
| 214 |
|
| 215 |
/**Add JS */ |
| 216 |
$editJS = add_submenu_page( |
| 217 |
'post-snippets', |
| 218 |
__('Add Custom JS', 'post-snippets'), |
| 219 |
__('Add Custom JS', 'post-snippets'), |
| 220 |
$capability, |
| 221 |
'post-snippets-edit-js', |
| 222 |
array( |
| 223 |
$this, |
| 224 |
'editPage', |
| 225 |
) |
| 226 |
); |
| 227 |
|
| 228 |
add_action('load-' . $editJS, array(\PostSnippets::EDIT_CLASS, 'page_actions'), 9); |
| 229 |
add_action('admin_footer-' . $editJS, array(\PostSnippets::EDIT_CLASS, 'footer_scripts')); |
| 230 |
add_filter('admin_title', array(\PostSnippets::EDIT_CLASS, 'change_edit_snippet_page_title'), 10, 2); |
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
$snippetsOptions = add_submenu_page( |
| 235 |
'post-snippets', |
| 236 |
__('Options', 'post-snippets'), |
| 237 |
__('Options', 'post-snippets'), |
| 238 |
$capability, |
| 239 |
'post-snippets-options', |
| 240 |
array( |
| 241 |
$this, |
| 242 |
// 'optionsPage', |
| 243 |
'tabOptions' |
| 244 |
) |
| 245 |
); |
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
$snippetsImpExp = add_submenu_page( |
| 250 |
'post-snippets', |
| 251 |
__('Import/Export', 'post-snippets'), |
| 252 |
__('Import/Export', 'post-snippets'), |
| 253 |
$capability, |
| 254 |
'post-snippets-imp-exp', |
| 255 |
array( |
| 256 |
$this, |
| 257 |
'tabTools', |
| 258 |
) |
| 259 |
); |
| 260 |
|
| 261 |
|
| 262 |
$newsPage = add_submenu_page( |
| 263 |
'post-snippets', |
| 264 |
__('News', 'post-snippets'), |
| 265 |
__('News', 'post-snippets'), |
| 266 |
$capability, |
| 267 |
'post-snippets-news', |
| 268 |
array( |
| 269 |
$this, |
| 270 |
'newsPage', |
| 271 |
) |
| 272 |
); |
| 273 |
|
| 274 |
$chatbot_ai = add_submenu_page( 'post-snippets', |
| 275 |
__( 'AI Chatbot', 'post-snippets' ), |
| 276 |
__( 'AI Chatbot', 'post-snippets' ), $capability, 'post-snippets-chatbot', array( |
| 277 |
$this, |
| 278 |
'chatbot_ai', |
| 279 |
) ); |
| 280 |
|
| 281 |
add_submenu_page($this->_admin_page, __('👉 Get Pro Bundle', 'post-snippets'), sprintf('<span style="color:#adff2f!important;">👉 %1$s <b>%2$s</b> ➤</span>', __('Get', 'post-snippets'), __('Pro Bundle', 'post-snippets')), $capability, $this->_admin_upgrade_page, ''); |
| 282 |
|
| 283 |
/*$optionPage = add_submenu_page( |
| 284 |
__( 'Post Snippets', 'post-snippets'), |
| 285 |
__( 'Post Snippets', 'post-snippets'), |
| 286 |
$capability, |
| 287 |
'post-snippets', |
| 288 |
array ( &$this, 'optionsPage' ) |
| 289 |
);*/ |
| 290 |
new Help($editSnippets); |
| 291 |
} else { |
| 292 |
add_menu_page( |
| 293 |
__('Post Snippets', 'post-snippets'), |
| 294 |
__('Post Snippets', 'post-snippets'), |
| 295 |
'manage_options', |
| 296 |
'post-snippets', |
| 297 |
array( |
| 298 |
$this, |
| 299 |
'overviewPage', |
| 300 |
), |
| 301 |
PS_URL . 'assets/icon.svg' |
| 302 |
); |
| 303 |
} |
| 304 |
} |
| 305 |
|
| 306 |
function add_screen_options() |
| 307 |
{ |
| 308 |
$option = 'per_page'; |
| 309 |
$args = array( |
| 310 |
'label' => __('Number of items per page', 'post-snippets'), |
| 311 |
'default' => 10, |
| 312 |
'option' => 'psp_snippets_per_page' |
| 313 |
); |
| 314 |
add_screen_option($option, $args); |
| 315 |
} |
| 316 |
|
| 317 |
function all_snippets_set_option($status, $option, $value) |
| 318 |
{ |
| 319 |
return $value; |
| 320 |
|
| 321 |
} |
| 322 |
|
| 323 |
/** |
| 324 |
* Initialize assets for the administration page. |
| 325 |
* |
| 326 |
* @return void |
| 327 |
*/ |
| 328 |
public function init() |
| 329 |
{ |
| 330 |
wp_register_script('post-snippets', plugins_url('/assets/post-snippets.js', \PostSnippets::FILE), array('jquery', 'wp-i18n'), PS_VERSION, true); |
| 331 |
if (postsnippets_fs()->can_use_premium_code__premium_only()) { |
| 332 |
wp_register_script('post-snippets-pro', plugins_url('/assets-pro/post-snippets-pro.js', \PostSnippets::FILE), array( |
| 333 |
'jquery', |
| 334 |
'post-snippets' |
| 335 |
), PS_VERSION, true); |
| 336 |
// wp_register_script( 'quill', plugins_url( '/assets-pro/quill.min.js', \PostSnippets::FILE ), array( |
| 337 |
// 'post-snippets-pro' |
| 338 |
// ), PS_VERSION, true ); |
| 339 |
} |
| 340 |
wp_set_script_translations('post-snippets', 'post-snippets'); /**To use wp i18n in JS */ |
| 341 |
$this->scripts(); |
| 342 |
$this->registerSettings(); |
| 343 |
} |
| 344 |
|
| 345 |
/** |
| 346 |
* Enqueue scripts to be loaded. |
| 347 |
* |
| 348 |
* @return void |
| 349 |
*/ |
| 350 |
public function scripts() |
| 351 |
{ |
| 352 |
// Localize the strings in the script |
| 353 |
$translation_array = array( |
| 354 |
'invalid_shortcode' => __('Invalid shortcode name', 'post-snippets'), |
| 355 |
'save_title_nonce' => wp_create_nonce('ps-save-title-nonce'), |
| 356 |
'update_snippet_nonce' => wp_create_nonce('ps-update-snippet-nonce'), |
| 357 |
); |
| 358 |
wp_localize_script('post-snippets', 'post_snippets', $translation_array); |
| 359 |
|
| 360 |
// Add CSS for Pro features page |
| 361 |
$features_style_url = plugins_url('/assets/features.css', \PostSnippets::FILE); |
| 362 |
wp_register_style('post-snippets-icons', $features_style_url, array(), PS_VERSION); |
| 363 |
wp_enqueue_style('post-snippets-icons'); |
| 364 |
|
| 365 |
// Add CSS for icons |
| 366 |
$features_style_url = plugins_url('/assets/icons.css', \PostSnippets::FILE); |
| 367 |
wp_register_style('post-snippets-features', $features_style_url, array(), PS_VERSION); |
| 368 |
wp_enqueue_style('post-snippets-features'); |
| 369 |
|
| 370 |
// Add CSS for newsletter opt-in |
| 371 |
$features_style_url = plugins_url('/assets/newsletter.css', \PostSnippets::FILE); |
| 372 |
wp_register_style('post-snippets-newsletter', $features_style_url, array(), PS_VERSION); |
| 373 |
wp_enqueue_style('post-snippets-newsletter'); |
| 374 |
|
| 375 |
// wp_enqueue_script( 'jquery-ui-sortable' ); |
| 376 |
wp_enqueue_script('jquery-ui-dialog'); |
| 377 |
wp_enqueue_script('underscore'); |
| 378 |
|
| 379 |
|
| 380 |
|
| 381 |
wp_enqueue_script('post-snippets'); |
| 382 |
} |
| 383 |
|
| 384 |
|
| 385 |
/** |
| 386 |
* Add X-XSS-Protection header. |
| 387 |
* |
| 388 |
* Newer versions of Chrome does not allow form tags to be submitted in the |
| 389 |
* forms. This header disables that functionlity on the Post Snippets admin |
| 390 |
* screen only. |
| 391 |
*/ |
| 392 |
public function addHeaderXss($current_screen) |
| 393 |
{ |
| 394 |
if ($current_screen->base == 'settings_page_post-snippets/post-snippets') { |
| 395 |
header('X-XSS-Protection: 0'); |
| 396 |
} |
| 397 |
} |
| 398 |
|
| 399 |
/** |
| 400 |
* Quick link to the Post Snippets Settings page from the Plugins page. |
| 401 |
* |
| 402 |
* @param array $links Array of all plugin links |
| 403 |
* |
| 404 |
* @return array $links Array with all the plugin's action links |
| 405 |
*/ |
| 406 |
public function actionLinks($links) |
| 407 |
{ |
| 408 |
|
| 409 |
$links[] = '<a href="' . PS_MAIN_PAGE_URL . '">' . __('Settings', 'post-snippets') . '</a>'; |
| 410 |
|
| 411 |
return $links; |
| 412 |
} |
| 413 |
|
| 414 |
|
| 415 |
public static function pspro_object_to_array($obj) |
| 416 |
{ |
| 417 |
//only process if it's an object or array being passed to the function |
| 418 |
if (is_object($obj) || is_array($obj)) { |
| 419 |
$ret = (array) $obj; |
| 420 |
foreach ($ret as &$item) { |
| 421 |
//recursively process EACH element regardless of type |
| 422 |
$item = self::pspro_object_to_array($item); |
| 423 |
} |
| 424 |
return $ret; |
| 425 |
} |
| 426 |
//otherwise (i.e. for scalar values) return without modification |
| 427 |
else { |
| 428 |
return $obj; |
| 429 |
} |
| 430 |
} |
| 431 |
|
| 432 |
|
| 433 |
|
| 434 |
/** |
| 435 |
* Update User Option. |
| 436 |
* |
| 437 |
* Sets the per user option for the read-only overview page. |
| 438 |
* |
| 439 |
* @since Post Snippets 1.9.7 |
| 440 |
*/ |
| 441 |
private function setUserOptions() |
| 442 |
{ |
| 443 |
if ( |
| 444 |
isset($_POST['post_snippets_user_nonce']) |
| 445 |
&& wp_verify_nonce($_POST['post_snippets_user_nonce'], 'post_snippets_user_options') |
| 446 |
) { |
| 447 |
$id = get_current_user_id(); |
| 448 |
$render = isset($_POST['render']) ? true : false; |
| 449 |
update_user_meta($id, \PostSnippets::USER_META_KEY, $render); |
| 450 |
} |
| 451 |
} |
| 452 |
|
| 453 |
/** |
| 454 |
* Get User Option. |
| 455 |
* |
| 456 |
* Gets the per user option for the read-only overview page. |
| 457 |
* |
| 458 |
* @since Post Snippets 1.9.7 |
| 459 |
* @return boolean If overview should be rendered on output or not |
| 460 |
*/ |
| 461 |
private function getUserOptions() |
| 462 |
{ |
| 463 |
$id = get_current_user_id(); |
| 464 |
$options = get_user_meta($id, \PostSnippets::USER_META_KEY, true); |
| 465 |
|
| 466 |
return $options; |
| 467 |
} |
| 468 |
|
| 469 |
|
| 470 |
// ------------------------------------------------------------------------- |
| 471 |
// HTML generation for option pages |
| 472 |
// ------------------------------------------------------------------------- |
| 473 |
|
| 474 |
/** |
| 475 |
* Display Flashing Message. |
| 476 |
* |
| 477 |
* @param string $message Message to display to the user. |
| 478 |
*/ |
| 479 |
private function message($message) |
| 480 |
{ |
| 481 |
if ($message) { |
| 482 |
echo "<div class='updated'><p><strong>{$message}</strong></p></div>"; |
| 483 |
} |
| 484 |
} |
| 485 |
|
| 486 |
public function newsPage() |
| 487 |
{ |
| 488 |
$plugins = array( |
| 489 |
array( |
| 490 |
"name" => "myCred", |
| 491 |
"description" => "myCred makes it simple to create a loyalty program or gamify your website so that you can increase the average customer value with less marketing effort.", |
| 492 |
"image" => "myCred.png", |
| 493 |
"url" => "https://wordpress.org/plugins/mycred", |
| 494 |
), |
| 495 |
array( |
| 496 |
"name" => "WP Contact Slider", |
| 497 |
"description" => "WP contact slider is simple contact slider to display contactform7, Gravity forms, Wp Forms, Caldera forms, Constant Contact Forms or display random text or HTML.", |
| 498 |
"image" => "ContactSlider.png", |
| 499 |
"url" => "https://wordpress.org/plugins/wp-contact-slider/", |
| 500 |
), |
| 501 |
array( |
| 502 |
"name" => "Wholesale For WooCommerce", |
| 503 |
"description" => "Sign up wholesale customers and display wholesale prices based on multiple wholesale user roles on your existing WooCommerce store", |
| 504 |
"image" => "WholesaleForWoocommerce.png", |
| 505 |
"url" => "https://woocommerce.com/products/wholesale-for-woocommerce/", |
| 506 |
), |
| 507 |
array( |
| 508 |
"name" => "WooCommerce Product Disclaimer", |
| 509 |
"description" => "Woocommerce extension where you can set some products to accept terms and conditions before adding product to cart. ", |
| 510 |
"image" => "ProductDisclaimer.png", |
| 511 |
"url" => "https://wordpress.org/plugins/woo-product-disclaimer/", |
| 512 |
) |
| 513 |
); |
| 514 |
|
| 515 |
include PS_PATH . "/views/admin_news.php"; |
| 516 |
} |
| 517 |
|
| 518 |
public function chatbot_ai() { |
| 519 |
if (isset($_POST['ps_openai_api_key'])) { |
| 520 |
check_admin_referer('ps_settings_group-options'); |
| 521 |
$api_key = sanitize_text_field($_POST['ps_openai_api_key']); |
| 522 |
update_option('ps_openai_api_key', $api_key); |
| 523 |
echo '<div class="updated"><p>Settings saved successfully.</p></div>'; |
| 524 |
} |
| 525 |
|
| 526 |
$api_key = get_option('ps_openai_api_key'); |
| 527 |
?> |
| 528 |
<div class="wrap ps-ai-settings-wrap"> |
| 529 |
<div class="ps-ai-header-dashboard"> |
| 530 |
<div class="header-content"> |
| 531 |
<h1>AI Chatbot Mastery</h1> |
| 532 |
<p class="subtitle">Connect and configure your advanced AI assistant for intelligent code generation.</p> |
| 533 |
</div> |
| 534 |
<div class="status-badge <?php echo $api_key ? 'active' : 'inactive'; ?>"> |
| 535 |
<span class="dot"></span> <?php echo $api_key ? 'Connected' : 'Disconnected'; ?> |
| 536 |
</div> |
| 537 |
</div> |
| 538 |
|
| 539 |
<div class="ps-ai-dashboard-grid"> |
| 540 |
<div class="ps-ai-card main-settings"> |
| 541 |
<div class="card-header"> |
| 542 |
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.778-7.778zM12 12V4m0 8l4-4m-4 4l-4-4"/></svg> |
| 543 |
<h2>Authentication</h2> |
| 544 |
</div> |
| 545 |
<form method="post" action=""> |
| 546 |
<?php settings_fields('ps_settings_group'); ?> |
| 547 |
<div class="input-group"> |
| 548 |
<label for="ps_openai_api_key">OpenAI API Key</label> |
| 549 |
<div class="input-wrapper"> |
| 550 |
<input type="password" |
| 551 |
name="ps_openai_api_key" |
| 552 |
id="ps_openai_api_key" |
| 553 |
value="<?php echo esc_attr($api_key); ?>" |
| 554 |
placeholder="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"> |
| 555 |
<span class="input-hint">Your keys are encrypted and stored securely.</span> |
| 556 |
</div> |
| 557 |
</div> |
| 558 |
<div class="card-footer"> |
| 559 |
<?php submit_button('Update Configuration', 'primary large'); ?> |
| 560 |
</div> |
| 561 |
</form> |
| 562 |
</div> |
| 563 |
|
| 564 |
<div class="ps-ai-card help-card"> |
| 565 |
<div class="card-header"> |
| 566 |
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg> |
| 567 |
<h2>Guide</h2> |
| 568 |
</div> |
| 569 |
<div class="card-body"> |
| 570 |
<ul class="steps"> |
| 571 |
<li> |
| 572 |
<span class="step-num">1</span> |
| 573 |
<div> |
| 574 |
<strong>Get Your Key</strong> |
| 575 |
<p>Visit <a href="https://platform.openai.com/api-keys" target="_blank">OpenAI Dashboard</a> to create a new secret key.</p> |
| 576 |
</div> |
| 577 |
</li> |
| 578 |
<li> |
| 579 |
<span class="step-num">2</span> |
| 580 |
<div> |
| 581 |
<strong>Set Quotas</strong> |
| 582 |
<p>Ensure your account has an active balance or credit to use the API.</p> |
| 583 |
</div> |
| 584 |
</li> |
| 585 |
<li> |
| 586 |
<span class="step-num">3</span> |
| 587 |
<div> |
| 588 |
<strong>Go Live</strong> |
| 589 |
<p>Paste the key here and start chatting with the assistant on any snippet edit page.</p> |
| 590 |
</div> |
| 591 |
</li> |
| 592 |
</ul> |
| 593 |
</div> |
| 594 |
</div> |
| 595 |
</div> |
| 596 |
|
| 597 |
<style> |
| 598 |
.ps-ai-settings-wrap { margin-top: 30px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; max-width: 1000px; } |
| 599 |
.ps-ai-header-dashboard { display: flex; justify-content: space-between; align-items: center; margin-bottom: 40px; padding: 20px; background: white; border-radius: 16px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05); } |
| 600 |
.ps-ai-header-dashboard h1 { margin: 0; font-size: 28px; font-weight: 800; color: #0f172a; } |
| 601 |
.ps-ai-header-dashboard .subtitle { margin: 8px 0 0; color: #64748b; font-size: 15px; } |
| 602 |
.status-badge { display: flex; align-items: center; gap: 8px; padding: 8px 16px; border-radius: 99px; font-size: 13px; font-weight: 600; } |
| 603 |
.status-badge.active { background: #f0fdf4; color: #166534; } |
| 604 |
.status-badge.inactive { background: #fef2f2; color: #991b1b; } |
| 605 |
.status-badge .dot { width: 8px; height: 8px; border-radius: 50%; } |
| 606 |
.status-badge.active .dot { background: #22c55e; box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2); } |
| 607 |
.status-badge.inactive .dot { background: #ef4444; } |
| 608 |
|
| 609 |
.ps-ai-dashboard-grid { display: grid; grid-template-columns: 1.5fr 1fr; gap: 30px; } |
| 610 |
.ps-ai-card { background: white; border-radius: 16px; border: 1px solid #f1f5f9; box-shadow: 0 10px 15px -3px rgba(0,0,0,0.05); display: flex; flex-direction: column; overflow: hidden; } |
| 611 |
.ps-ai-card .card-header { padding: 24px; border-bottom: 1px solid #f1f5f9; display: flex; align-items: center; gap: 12px; } |
| 612 |
.ps-ai-card .card-header h2 { margin: 0; font-size: 18px; font-weight: 600; color: #0f172a; } |
| 613 |
.ps-ai-card .card-header svg { color: #3b82f6; } |
| 614 |
|
| 615 |
.ps-ai-card .card-body, .ps-ai-card form { padding: 30px; flex: 1; } |
| 616 |
.input-group label { display: block; font-weight: 600; margin-bottom: 10px; color: #334155; } |
| 617 |
.input-wrapper input { width: 100%; padding: 12px 16px; border-radius: 10px; border: 1px solid #e2e8f0; background: #f8fafc; font-size: 14px; transition: all 0.2s; } |
| 618 |
.input-wrapper input:focus { border-color: #3b82f6; box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1); outline: none; background: #fff; } |
| 619 |
.input-hint { display: block; font-size: 12px; color: #94a3b8; margin-top: 8px; } |
| 620 |
|
| 621 |
.card-footer { padding: 20px 30px; background: #f8fafc; border-top: 1px solid #f1f5f9; } |
| 622 |
.card-footer .submit { margin: 0; } |
| 623 |
|
| 624 |
.steps { list-style: none; margin: 0; padding: 0; } |
| 625 |
.steps li { display: flex; gap: 16px; margin-bottom: 24px; } |
| 626 |
.step-num { width: 28px; height: 28px; background: #3b82f6; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: bold; flex-shrink: 0; } |
| 627 |
.steps li strong { display: block; margin-bottom: 4px; color: #0f172a; } |
| 628 |
.steps li p { margin: 0; font-size: 13px; color: #64748b; line-height: 1.5; } |
| 629 |
.steps li a { color: #3b82f6; text-decoration: none; font-weight: 500; } |
| 630 |
.steps li a:hover { text-decoration: underline; } |
| 631 |
</style> |
| 632 |
</div> |
| 633 |
<?php |
| 634 |
} |
| 635 |
|
| 636 |
public function restPage() |
| 637 |
{ |
| 638 |
?> |
| 639 |
<div class="wrap"> |
| 640 |
<form method="post" action="options.php"> |
| 641 |
<?php settings_fields('ps_rest_fields'); ?> |
| 642 |
|
| 643 |
<?php do_settings_sections('ps-rest-settings'); ?> |
| 644 |
<?php submit_button(); ?> |
| 645 |
</form> |
| 646 |
</div> |
| 647 |
<?php |
| 648 |
} |
| 649 |
|
| 650 |
|
| 651 |
|
| 652 |
/** |
| 653 |
* Creates the all snippets administration page. |
| 654 |
* |
| 655 |
* For users with manage_options capability (admin, super admin). |
| 656 |
* |
| 657 |
* @since Post Snippets 3.1.4 |
| 658 |
*/ |
| 659 |
public function allSnippetsPage() |
| 660 |
{ |
| 661 |
|
| 662 |
$allSnippets = new PSallSnippets(); |
| 663 |
|
| 664 |
?> |
| 665 |
<div class="wrap"> |
| 666 |
<div id="icon-users" class="icon32"></div> |
| 667 |
<!-- H4 is used below cause admin notices are appended to first H1 or H2 --> |
| 668 |
<h4 class="wp-heading-inline- all_snippets_heading"><?php esc_html_e('All', 'post-snippets'); ?> Snippets</h4> |
| 669 |
<a href="<?php echo esc_url("?page=post-snippets-edit") ?>" |
| 670 |
class="page-title-action"><?php esc_html_e('Add New', 'post-snippets'); ?></a> |
| 671 |
<form id="posts-filter" method="get"> |
| 672 |
<input type="hidden" name="page" value="post-snippets"> |
| 673 |
|
| 674 |
<?php |
| 675 |
wp_nonce_field('pspro_all_snippets', 'pspro_all_snippets_nonce', false); |
| 676 |
// wp_nonce_field('sync_up', 'sync_up'); |
| 677 |
// wp_nonce_field('sync_down', 'sync_down'); |
| 678 |
$allSnippets->prepare_items(); |
| 679 |
$allSnippets->display(); |
| 680 |
|
| 681 |
?> |
| 682 |
</form> |
| 683 |
</div> |
| 684 |
|
| 685 |
<?php |
| 686 |
|
| 687 |
|
| 688 |
} |
| 689 |
|
| 690 |
public function editPage() |
| 691 |
{ |
| 692 |
|
| 693 |
$snippet = new Edit(); |
| 694 |
|
| 695 |
} |
| 696 |
|
| 697 |
|
| 698 |
|
| 699 |
|
| 700 |
|
| 701 |
/** |
| 702 |
* Tab to set options for the plugin. |
| 703 |
* |
| 704 |
* @return void |
| 705 |
*/ |
| 706 |
public function tabOptions() |
| 707 |
{ |
| 708 |
// echo '<p class="description post-snippets-documentation-note">'; |
| 709 |
// _e( 'Click \'Help\' in the top right for the documentation!', 'post-snippets' ); |
| 710 |
// echo '</p>'; |
| 711 |
|
| 712 |
?> |
| 713 |
<div class="wrap"> |
| 714 |
<div id="icon-users" class="icon32"></div> |
| 715 |
<h1 class="wp-heading-inline"><?php esc_html_e('Options', 'post-snippets'); ?></h1> |
| 716 |
<!-- <form id="posts-filter" method="post"> --> |
| 717 |
<?php |
| 718 |
$data = array(); |
| 719 |
echo View::render('admin_options', $data); |
| 720 |
?> |
| 721 |
<!-- </form> --> |
| 722 |
</div> |
| 723 |
|
| 724 |
<?php |
| 725 |
|
| 726 |
|
| 727 |
} |
| 728 |
|
| 729 |
/** |
| 730 |
* Tab for Import/Export |
| 731 |
* |
| 732 |
* @since Post Snippets 2.0 |
| 733 |
*/ |
| 734 |
public function tabTools() |
| 735 |
{ |
| 736 |
// echo '<p class="description post-snippets-documentation-note">'; |
| 737 |
// _e( 'Click \'Help\' in the top right for the documentation!', 'post-snippets' ); |
| 738 |
// echo '</p>'; |
| 739 |
|
| 740 |
$ie = new ImportExport(); |
| 741 |
|
| 742 |
// Create header and export html form |
| 743 |
printf("<h3>%s</h3>", __('Import/Export', 'post-snippets')); |
| 744 |
printf("<h4>%s</h4>", __('Export', 'post-snippets')); |
| 745 |
echo '<form method="post">'; |
| 746 |
wp_nonce_field('postsnippets_export', 'postsnippets_export_nonce'); |
| 747 |
echo '<p>'; |
| 748 |
_e('Export your snippets for backup or to import them on another site.', 'post-snippets'); |
| 749 |
echo '</p>'; |
| 750 |
printf("<input type='submit' class='button' name='postsnippets_export' value='%s' />", __('Export Snippets', 'post-snippets')); |
| 751 |
echo '</form>'; |
| 752 |
|
| 753 |
// Export logic, and import html form and logic |
| 754 |
$ie->exportAllSnippets(); |
| 755 |
echo $ie->importSnippets(); |
| 756 |
} |
| 757 |
|
| 758 |
/** |
| 759 |
* Tab for Pro features |
| 760 |
* |
| 761 |
* @since Post Snippets 2.5.4 |
| 762 |
*/ |
| 763 |
private function tabFeatures() |
| 764 |
{ |
| 765 |
$features = new Features(); |
| 766 |
|
| 767 |
echo $features->showFeatures(); |
| 768 |
|
| 769 |
} |
| 770 |
|
| 771 |
|
| 772 |
/** |
| 773 |
* Creates a read-only overview page. |
| 774 |
* |
| 775 |
* For users with edit_posts capability but without manage_options |
| 776 |
* capability. |
| 777 |
* |
| 778 |
* @since Post Snippets 1.9.7 |
| 779 |
*/ |
| 780 |
public function overviewPage() |
| 781 |
{ |
| 782 |
// Header |
| 783 |
echo '<div class="wrap">'; |
| 784 |
echo '<h2>Post Snippets</h2>'; |
| 785 |
echo '<p>'; |
| 786 |
_e('This is an overview of all snippets defined for this site. These snippets are inserted into posts from the post editor using the Post Snippets button. You can choose to see the snippets here as-is or as they are actually rendered on the website. Enabling rendered snippets for this overview might look strange if the snippet have dependencies on variables, CSS or other parameters only available on the frontend. If that is the case it is recommended to keep this option disabled.', 'post-snippets'); |
| 787 |
echo '</p>'; |
| 788 |
|
| 789 |
// Form |
| 790 |
$this->setUserOptions(); |
| 791 |
$render = $this->getUserOptions(); |
| 792 |
|
| 793 |
echo '<form method="post" action="">'; |
| 794 |
wp_nonce_field('post_snippets_user_options', 'post_snippets_user_nonce'); |
| 795 |
|
| 796 |
$this->checkbox(__('Display rendered snippets', 'post-snippets'), 'render', $render); |
| 797 |
$this->submit('update-post-snippets-user', __('Update', 'post-snippets')); |
| 798 |
echo '</form>'; |
| 799 |
|
| 800 |
// Snippet List |
| 801 |
$snippets = get_option(\PostSnippets::OPTION_KEY); |
| 802 |
if (!empty($snippets)) { |
| 803 |
foreach ($snippets as $key => $snippet) { |
| 804 |
echo "<hr style='border: none;border-top:1px dashed #aaa; margin:24px 0;' />"; |
| 805 |
|
| 806 |
echo "<h3>{$snippet['title']}"; |
| 807 |
if ($snippet['description']) { |
| 808 |
echo "<span class='description'> {$snippet['description']}</span>"; |
| 809 |
} |
| 810 |
echo "</h3>"; |
| 811 |
|
| 812 |
if ($snippet['vars']) { |
| 813 |
printf("<strong>%s:</strong> {$snippet['vars']}<br/>", __('Variables', 'post-snippets')); |
| 814 |
} |
| 815 |
|
| 816 |
// echo "<strong>Variables:</strong> {$snippet['vars']}<br/>"; |
| 817 |
|
| 818 |
$options = array(); |
| 819 |
if ($snippet['shortcode']) { |
| 820 |
array_push($options, 'Shortcode'); |
| 821 |
} |
| 822 |
if ($snippet['php']) { |
| 823 |
array_push($options, 'PHP'); |
| 824 |
} |
| 825 |
if ($snippet['wptexturize']) { |
| 826 |
array_push($options, 'wptexturize'); |
| 827 |
} |
| 828 |
if ($options) { |
| 829 |
printf("<strong>%s:</strong> %s<br/>", __('Options', 'post-snippets'), implode(', ', $options)); |
| 830 |
} |
| 831 |
|
| 832 |
printf("<br/><strong>%s:</strong><br/>", __('Snippet', 'post-snippets')); |
| 833 |
if ($render) { |
| 834 |
echo do_shortcode($snippet['snippet']); |
| 835 |
} else { |
| 836 |
echo "<code>"; |
| 837 |
echo nl2br(htmlspecialchars($snippet['snippet'], ENT_NOQUOTES)); |
| 838 |
echo "</code>"; |
| 839 |
} |
| 840 |
} |
| 841 |
} |
| 842 |
// Close |
| 843 |
echo '</div>'; |
| 844 |
} |
| 845 |
|
| 846 |
|
| 847 |
// ------------------------------------------------------------------------- |
| 848 |
// Register and callbacks for the options tab |
| 849 |
// ------------------------------------------------------------------------- |
| 850 |
|
| 851 |
/** |
| 852 |
* Register settings for the options tab. |
| 853 |
* |
| 854 |
* @return void |
| 855 |
*/ |
| 856 |
protected function registerSettings() |
| 857 |
{ |
| 858 |
$this->settings = get_option(\PostSnippets::SETTINGS); |
| 859 |
|
| 860 |
register_setting( |
| 861 |
\PostSnippets::SETTINGS, |
| 862 |
\PostSnippets::SETTINGS |
| 863 |
); |
| 864 |
|
| 865 |
add_settings_section( |
| 866 |
'general_section', |
| 867 |
__('General', 'post-snippets'), |
| 868 |
null, |
| 869 |
'post-snippets' |
| 870 |
); |
| 871 |
|
| 872 |
add_settings_field( |
| 873 |
'exclude_from_custom_editors', |
| 874 |
__('Exclude from Custom Editors', 'post-snippets'), |
| 875 |
array($this, 'cbExcludeFromCustomEditors'), |
| 876 |
'post-snippets', |
| 877 |
'general_section', |
| 878 |
array( |
| 879 |
'id' => 'exclude_from_custom_editors', |
| 880 |
'label_for' => 'exclude_from_custom_editors', |
| 881 |
'description' => __('Checking this only includes Post Snippets on standard WordPress post editing screens.', 'post-snippets') |
| 882 |
) |
| 883 |
); |
| 884 |
|
| 885 |
|
| 886 |
add_settings_field( |
| 887 |
'complete_uninstall', |
| 888 |
__('Complete Uninstall', 'post-snippets'), |
| 889 |
array($this, 'cbCompleteUninstall'), |
| 890 |
'post-snippets', |
| 891 |
'general_section', |
| 892 |
array( |
| 893 |
'id' => 'complete_uninstall', |
| 894 |
'label_for' => 'complete_uninstall', |
| 895 |
'description' => __('When the plugin is deleted, also delete all snippets and plugin settings.', 'post-snippets') |
| 896 |
) |
| 897 |
); |
| 898 |
|
| 899 |
|
| 900 |
add_settings_section( |
| 901 |
'duplicate_section', |
| 902 |
__('Duplicate Snippets', 'post-snippets'), |
| 903 |
null, |
| 904 |
'post-snippets' |
| 905 |
); |
| 906 |
|
| 907 |
add_settings_field( |
| 908 |
'allow_duplicate', |
| 909 |
__('Allow Duplicate', 'post-snippets'), |
| 910 |
array($this, 'cbAllowDuplicate'), |
| 911 |
'post-snippets', |
| 912 |
'duplicate_section', |
| 913 |
array( |
| 914 |
'id' => 'allow_duplicate', |
| 915 |
'label_for' => 'allow_duplicate', |
| 916 |
'description' => __('Allow duplicate snippets: import all snippets from the file regardless and leave all existing snippets unchanged.', 'post-snippets') |
| 917 |
) |
| 918 |
); |
| 919 |
|
| 920 |
|
| 921 |
add_settings_field( |
| 922 |
'replace_duplicate', |
| 923 |
__('Replace Duplicate', 'post-snippets'), |
| 924 |
array($this, 'cbReplaceDuplicate'), |
| 925 |
'post-snippets', |
| 926 |
'duplicate_section', |
| 927 |
array( |
| 928 |
'id' => 'replace_duplicate', |
| 929 |
'label_for' => 'replace_duplicate', |
| 930 |
'description' => __('Replace any existing snippets with a newly imported snippet of the same name.', 'post-snippets') |
| 931 |
) |
| 932 |
); |
| 933 |
|
| 934 |
|
| 935 |
add_settings_field( |
| 936 |
'skip_duplicate', |
| 937 |
__('Do not Import Duplicate', 'post-snippets'), |
| 938 |
array($this, 'cbSkipDuplicate'), |
| 939 |
'post-snippets', |
| 940 |
'duplicate_section', |
| 941 |
array( |
| 942 |
'id' => 'skip_duplicate', |
| 943 |
'label_for' => 'skip_duplicate', |
| 944 |
'description' => __('Do not import any duplicate snippets; leave all existing snippets unchanged.', 'post-snippets') |
| 945 |
) |
| 946 |
); |
| 947 |
|
| 948 |
} |
| 949 |
|
| 950 |
/** |
| 951 |
* Callback for HTML generator for exlusion of custom editors. |
| 952 |
* |
| 953 |
* @param array $args |
| 954 |
* |
| 955 |
* @return void |
| 956 |
*/ |
| 957 |
public function cbExcludeFromCustomEditors($args) |
| 958 |
{ |
| 959 |
$checked = isset($this->settings[$args['id']]) ? |
| 960 |
$this->settings[$args['id']] : |
| 961 |
false; |
| 962 |
|
| 963 |
echo "<input type='checkbox' id='{$args['id']}' "; |
| 964 |
echo "name='" . \PostSnippets::SETTINGS . "[{$args['id']}]' value='1' "; |
| 965 |
if ($checked) { |
| 966 |
echo 'checked '; |
| 967 |
} |
| 968 |
echo " />"; |
| 969 |
|
| 970 |
echo "<span class='description'>{$args['description']}</span>"; |
| 971 |
} |
| 972 |
|
| 973 |
|
| 974 |
/** |
| 975 |
* Callback for Complete Uninstallation Option. |
| 976 |
* |
| 977 |
* @param array $args |
| 978 |
* |
| 979 |
* @return void |
| 980 |
*/ |
| 981 |
public function cbCompleteUninstall($args) |
| 982 |
{ |
| 983 |
$checked = isset($this->settings[$args['id']]) ? |
| 984 |
$this->settings[$args['id']] : |
| 985 |
false; |
| 986 |
|
| 987 |
echo "<input type='checkbox' id='{$args['id']}' "; |
| 988 |
echo "name='" . \PostSnippets::SETTINGS . "[{$args['id']}]' value='1' "; |
| 989 |
if ($checked) { |
| 990 |
echo 'checked '; |
| 991 |
} |
| 992 |
echo " />"; |
| 993 |
|
| 994 |
echo "<span class='description'>{$args['description']}</span>"; |
| 995 |
} |
| 996 |
|
| 997 |
|
| 998 |
/** |
| 999 |
* Callback for Allow Duplicate selection. |
| 1000 |
* |
| 1001 |
* @param array $args |
| 1002 |
* |
| 1003 |
* @return void |
| 1004 |
*/ |
| 1005 |
public function cbAllowDuplicate($args) |
| 1006 |
{ |
| 1007 |
$checked = $this->pspro_isDuplicateOptionChecked($args['id']); |
| 1008 |
|
| 1009 |
echo "<input type='radio' id='{$args['id']}' "; |
| 1010 |
echo "name='" . \PostSnippets::SETTINGS . "[" . \PostSnippets::DUPLICATE_SETTINGS . "]' value='{$args['id']}' "; |
| 1011 |
if ($checked) { |
| 1012 |
echo 'checked '; |
| 1013 |
} |
| 1014 |
echo " />"; |
| 1015 |
|
| 1016 |
echo "<span class='description'>{$args['description']}</span>"; |
| 1017 |
} |
| 1018 |
|
| 1019 |
|
| 1020 |
/** |
| 1021 |
* Callback for Complete Uninstallation Option. |
| 1022 |
* |
| 1023 |
* @param array $args |
| 1024 |
* |
| 1025 |
* @return void |
| 1026 |
*/ |
| 1027 |
public function cbReplaceDuplicate($args) |
| 1028 |
{ |
| 1029 |
$checked = $this->pspro_isDuplicateOptionChecked($args['id']); |
| 1030 |
|
| 1031 |
echo "<input type='radio' id='{$args['id']}' "; |
| 1032 |
echo "name='" . \PostSnippets::SETTINGS . "[" . \PostSnippets::DUPLICATE_SETTINGS . "]' value='{$args['id']}' "; |
| 1033 |
if ($checked) { |
| 1034 |
echo 'checked '; |
| 1035 |
} |
| 1036 |
echo " />"; |
| 1037 |
|
| 1038 |
echo "<span class='description'>{$args['description']}</span>"; |
| 1039 |
} |
| 1040 |
|
| 1041 |
|
| 1042 |
/** |
| 1043 |
* Callback for Complete Uninstallation Option. |
| 1044 |
* |
| 1045 |
* @param array $args |
| 1046 |
* |
| 1047 |
* @return void |
| 1048 |
*/ |
| 1049 |
public function cbSkipDuplicate($args) |
| 1050 |
{ |
| 1051 |
$checked = $this->pspro_isDuplicateOptionChecked($args['id']); |
| 1052 |
|
| 1053 |
echo "<input type='radio' id='{$args['id']}' "; |
| 1054 |
echo "name='" . \PostSnippets::SETTINGS . "[" . \PostSnippets::DUPLICATE_SETTINGS . "]' value='{$args['id']}' "; |
| 1055 |
if ($checked) { |
| 1056 |
echo 'checked '; |
| 1057 |
} |
| 1058 |
echo " />"; |
| 1059 |
|
| 1060 |
echo "<span class='description'>{$args['description']}</span>"; |
| 1061 |
} |
| 1062 |
|
| 1063 |
public function pspro_isDuplicateOptionChecked($option = '') |
| 1064 |
{ |
| 1065 |
|
| 1066 |
if (empty($option)) { |
| 1067 |
return false; |
| 1068 |
} |
| 1069 |
|
| 1070 |
if (isset($this->settings['duplicate_option']) && $this->settings['duplicate_option'] == $option) { |
| 1071 |
return true; |
| 1072 |
} |
| 1073 |
|
| 1074 |
return false; |
| 1075 |
|
| 1076 |
} |
| 1077 |
|
| 1078 |
|
| 1079 |
// ------------------------------------------------------------------------- |
| 1080 |
// HTML and Form element methods for Snippets form |
| 1081 |
// ------------------------------------------------------------------------- |
| 1082 |
|
| 1083 |
/** |
| 1084 |
* Checkbox. |
| 1085 |
* |
| 1086 |
* Renders the HTML for an input checkbox. |
| 1087 |
* |
| 1088 |
* @param string $label The label rendered to screen |
| 1089 |
* @param string $name The unique name and id to identify the input |
| 1090 |
* @param boolean $checked If the input is checked or not |
| 1091 |
* |
| 1092 |
* @return void |
| 1093 |
*/ |
| 1094 |
public static function checkbox($label, $name, $checked) |
| 1095 |
{ |
| 1096 |
echo "<label for=\"{$name}\">"; |
| 1097 |
printf('<input type="checkbox" name="%1$s" id="%1$s" value="true"', $name); |
| 1098 |
if ($checked) { |
| 1099 |
echo ' checked'; |
| 1100 |
} |
| 1101 |
echo ' />'; |
| 1102 |
echo " {$label}</label><br/>"; |
| 1103 |
} |
| 1104 |
|
| 1105 |
/** |
| 1106 |
* Submit. |
| 1107 |
* |
| 1108 |
* Renders the HTML for a submit button. |
| 1109 |
* |
| 1110 |
* @since Post Snippets 1.9.7 |
| 1111 |
* |
| 1112 |
* @param string $name The name that identifies the button on submit |
| 1113 |
* @param string $label The label rendered on the button |
| 1114 |
* @param string $class Optional. Button class. Default: button-primary |
| 1115 |
* @param boolean $wrap Optional. Wrap in a submit div. Default: true |
| 1116 |
* |
| 1117 |
* @return void |
| 1118 |
*/ |
| 1119 |
public static function submit($name, $label, $class = 'button-primary', $wrap = true) |
| 1120 |
{ |
| 1121 |
$btn = sprintf('<input type="submit" name="%s" value="%s" class="%s" /> ', $name, $label, $class); |
| 1122 |
|
| 1123 |
if ($wrap) { |
| 1124 |
$btn = "<div class=\"submit\">{$btn}</div>"; |
| 1125 |
} |
| 1126 |
|
| 1127 |
echo $btn; |
| 1128 |
} |
| 1129 |
|
| 1130 |
/** |
| 1131 |
* |
| 1132 |
* Show newsletter opt-in, only in Post Snippets. |
| 1133 |
* Not on Pro features tab/page. |
| 1134 |
* Not when user selected to Hide opt-in. |
| 1135 |
* |
| 1136 |
* @since 2.5.4 |
| 1137 |
*/ |
| 1138 |
public function admin_notice_newsletter() |
| 1139 |
{ |
| 1140 |
|
| 1141 |
// Hide newsletter opt-in if option is true |
| 1142 |
if (get_option('ps_hide_admin_notice_newsletter') == true) { |
| 1143 |
return; |
| 1144 |
} |
| 1145 |
|
| 1146 |
// Set option if "hide" button click detected (custom querystring value set to 1). |
| 1147 |
if (!empty($_REQUEST['ps-dismiss-newsletter-nag'])) { |
| 1148 |
update_option('ps_hide_admin_notice_newsletter', true); |
| 1149 |
|
| 1150 |
return; |
| 1151 |
} |
| 1152 |
|
| 1153 |
// Show newsletter notice. |
| 1154 |
if (get_current_screen()->id == 'settings_page_post-snippets/post-snippets') { |
| 1155 |
$active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'snippets'; |
| 1156 |
if ($active_tab != 'features') { |
| 1157 |
include_once(PS_PATH . '/views/admin_notice_newsletter.php'); |
| 1158 |
} |
| 1159 |
|
| 1160 |
} |
| 1161 |
} |
| 1162 |
|
| 1163 |
|
| 1164 |
/** |
| 1165 |
* |
| 1166 |
* Show 'Get started' admin notice', everywhere. |
| 1167 |
* Not when user already clicked or dismissed. |
| 1168 |
* |
| 1169 |
* @since 2.5.4 |
| 1170 |
*/ |
| 1171 |
public function admin_notice_get_started() |
| 1172 |
{ |
| 1173 |
|
| 1174 |
// Hide newsletter opt-in if option is true |
| 1175 |
if (get_option('ps_hide_admin_notice_get_started') == true) { |
| 1176 |
return; |
| 1177 |
} |
| 1178 |
|
| 1179 |
// Set option if "hide" button click detected (custom query string value set to 1). |
| 1180 |
if (!empty($_REQUEST['ps-dismiss-get-started-nag'])) { |
| 1181 |
update_option('ps_hide_admin_notice_get_started', true); |
| 1182 |
|
| 1183 |
return; |
| 1184 |
} |
| 1185 |
|
| 1186 |
// Show newsletter notice. |
| 1187 |
if (strpos(get_current_screen()->id, '/post-snippets') == false) { |
| 1188 |
$active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'snippets'; |
| 1189 |
if ($active_tab != 'features') { |
| 1190 |
include_once(PS_PATH . '/views/admin_notice_get_started.php'); |
| 1191 |
} |
| 1192 |
|
| 1193 |
} |
| 1194 |
} |
| 1195 |
|
| 1196 |
public function get_allowed_capability() |
| 1197 |
{ |
| 1198 |
$capability = 'manage_options'; |
| 1199 |
|
| 1200 |
if (defined('POST_SNIPPETS_ALLOW_EDIT_POSTS') and current_user_can('edit_posts')) { |
| 1201 |
$capability = 'edit_posts'; |
| 1202 |
} |
| 1203 |
|
| 1204 |
return $capability; |
| 1205 |
} |
| 1206 |
|
| 1207 |
} |
| 1208 |
|