Changeset 3741840
- Timestamp:
- 10/12/2026 02:08:34 PM (3 weeks ago)
- Location:
- software-license-lite
- Files:
-
- 59 added
- 13 edited
-
tags/1.3 (added)
-
tags/1.3/api (added)
-
tags/1.3/api/class.sl.api-loader.php (added)
-
tags/1.3/api/class.sl.api.1.2.php (added)
-
tags/1.3/api/class.sl.api.php (added)
-
tags/1.3/compatibility (added)
-
tags/1.3/compatibility/woocommerce-give-products.php (added)
-
tags/1.3/compatibility/wp-meteor.php (added)
-
tags/1.3/css (added)
-
tags/1.3/css/admin-licences.css (added)
-
tags/1.3/css/admin-options.css (added)
-
tags/1.3/css/admin-order.css (added)
-
tags/1.3/css/admin-product.css (added)
-
tags/1.3/css/flatpickr.css (added)
-
tags/1.3/css/my-account.css (added)
-
tags/1.3/css/order-details.css (added)
-
tags/1.3/images (added)
-
tags/1.3/images/ajax-loader.gif (added)
-
tags/1.3/images/calendar-icon.jpg (added)
-
tags/1.3/include (added)
-
tags/1.3/include/admin (added)
-
tags/1.3/include/admin/class-licences-list-table.php (added)
-
tags/1.3/include/admin/settings (added)
-
tags/1.3/include/admin/settings/class.sl-settings-licence.php (added)
-
tags/1.3/include/class.admin.php (added)
-
tags/1.3/include/class.sl.admin.licences.php (added)
-
tags/1.3/include/class.sl.admin.order.php (added)
-
tags/1.3/include/class.sl.admin.product.php (added)
-
tags/1.3/include/class.sl.ajax.php (added)
-
tags/1.3/include/class.sl.front.php (added)
-
tags/1.3/include/class.sl.functions.php (added)
-
tags/1.3/include/class.sl.on-update.php (added)
-
tags/1.3/include/class.sl.php (added)
-
tags/1.3/include/emails (added)
-
tags/1.3/include/emails/class-wc-email-customer-licence-expire.php (added)
-
tags/1.3/include/emails/class-wc-email-customer-licence-expired.php (added)
-
tags/1.3/include/wc-template-functions.php (added)
-
tags/1.3/js (added)
-
tags/1.3/js/admin-order.js (added)
-
tags/1.3/js/admin-product.js (added)
-
tags/1.3/js/flatpickr.js (added)
-
tags/1.3/js/front-my-account.js (added)
-
tags/1.3/js/functions.js (added)
-
tags/1.3/js/poshy-tip.js (added)
-
tags/1.3/languages (added)
-
tags/1.3/languages/software-license-lite-for-woocommerce.mo (added)
-
tags/1.3/languages/software-license-lite-for-woocommerce.po (added)
-
tags/1.3/readme.txt (added)
-
tags/1.3/software-license-lite.php (added)
-
tags/1.3/templates (added)
-
tags/1.3/templates/emails (added)
-
tags/1.3/templates/emails/licence-expire.php (added)
-
tags/1.3/templates/emails/licence-expired.php (added)
-
tags/1.3/templates/emails/plain (added)
-
tags/1.3/templates/emails/plain/licence-expire.php (added)
-
tags/1.3/templates/emails/plain/licence-expired.php (added)
-
tags/1.3/templates/myaccount (added)
-
tags/1.3/templates/myaccount/my-licence-manage.php (added)
-
tags/1.3/templates/myaccount/my-licences.php (added)
-
trunk/api/class.sl.api.1.2.php (modified) (3 diffs)
-
trunk/api/class.sl.api.php (modified) (1 diff)
-
trunk/css/admin-product.css (modified) (2 diffs)
-
trunk/include/class.sl.admin.product.php (modified) (5 diffs)
-
trunk/js/admin-product.js (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/software-license-lite.php (modified) (2 diffs)
-
trunk/templates/emails/licence-expire.php (modified) (1 diff)
-
trunk/templates/emails/licence-expired.php (modified) (1 diff)
-
trunk/templates/emails/plain/licence-expire.php (modified) (1 diff)
-
trunk/templates/emails/plain/licence-expired.php (modified) (1 diff)
-
trunk/templates/myaccount/my-licence-manage.php (modified) (1 diff)
-
trunk/templates/myaccount/my-licences.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
software-license-lite/trunk/api/class.sl.api.1.2.php
r3619649 r3741840 736 736 737 737 $allowed_html_tags = $this->get_allowed_html_tags(); 738 739 if(get_post_meta($product_id, '_sl_description', TRUE) != '') 740 { 741 $post_html_content = get_post( get_post_meta($product_id, '_sl_description', TRUE))->post_content; 742 $data->sections['description'] = wp_kses( $post_html_content, $allowed_html_tags ); 743 } 744 if(get_post_meta($product_id, '_sl_installation', TRUE) != '') 745 { 746 $post_html_content = get_post( get_post_meta($product_id, '_sl_installation', TRUE))->post_content; 747 $data->sections['installation'] = wp_kses( $post_html_content, $allowed_html_tags ); 748 } 749 if(get_post_meta($product_id, '_sl_faq', TRUE) != '') 750 { 751 $post_html_content = get_post( get_post_meta($product_id, '_sl_faq', TRUE))->post_content; 752 $data->sections['faq'] = wp_kses( $post_html_content, $allowed_html_tags ); 753 } 754 if(get_post_meta($product_id, '_sl_screenshots', TRUE) != '') 755 { 756 $post_html_content = get_post( get_post_meta($product_id, '_sl_screenshots', TRUE))->post_content; 757 $data->sections['screenshots'] = wp_kses( $post_html_content, $allowed_html_tags ); 758 } 759 if(get_post_meta($product_id, '_sl_changelog', TRUE) != '') 760 { 761 $post_html_content = get_post( get_post_meta($product_id, '_sl_changelog', TRUE))->post_content; 762 $data->sections['changelog'] = wp_kses( $post_html_content, $allowed_html_tags ); 763 } 764 if(get_post_meta($product_id, '_sl_reviews', TRUE) != '') 765 { 766 $post_html_content = get_post( get_post_meta($product_id, '_sl_reviews', TRUE))->post_content; 767 $data->sections['reviews'] = wp_kses( $post_html_content, $allowed_html_tags ); 768 } 769 if(get_post_meta($product_id, '_sl_other_notes', TRUE) != '') 770 { 771 $post_html_content = get_post( get_post_meta($product_id, '_sl_other_notes', TRUE))->post_content; 772 $data->sections['other_notes'] = wp_kses( $post_html_content, $allowed_html_tags ); 773 } 774 738 739 $data->sections = $this->get_product_information_sections( $product_id, $allowed_html_tags ); 775 740 776 741 $data->banners = array( … … 915 880 916 881 $allowed_html_tags = $this->get_allowed_html_tags(); 917 918 if(get_post_meta($product_id, '_sl_description', TRUE) != '') 919 { 920 $post_html_content = get_post( get_post_meta($product_id, '_sl_description', TRUE))->post_content; 921 $data->sections['description'] = wp_kses( $post_html_content, $allowed_html_tags ); 922 } 923 if(get_post_meta($product_id, '_sl_installation', TRUE) != '') 924 { 925 $post_html_content = get_post( get_post_meta($product_id, '_sl_installation', TRUE))->post_content; 926 $data->sections['installation'] = wp_kses( $post_html_content, $allowed_html_tags ); 927 } 928 if(get_post_meta($product_id, '_sl_faq', TRUE) != '') 929 { 930 $post_html_content = get_post( get_post_meta($product_id, '_sl_faq', TRUE))->post_content; 931 $data->sections['faq'] = wp_kses( $post_html_content, $allowed_html_tags ); 932 } 933 if(get_post_meta($product_id, '_sl_screenshots', TRUE) != '') 934 { 935 $post_html_content = get_post( get_post_meta($product_id, '_sl_screenshots', TRUE))->post_content; 936 $data->sections['screenshots'] = wp_kses( $post_html_content, $allowed_html_tags ); 937 } 938 if(get_post_meta($product_id, '_sl_changelog', TRUE) != '') 939 { 940 $post_html_content = get_post( get_post_meta($product_id, '_sl_changelog', TRUE))->post_content; 941 $data->sections['changelog'] = wp_kses( $post_html_content, $allowed_html_tags ); 942 } 943 if(get_post_meta($product_id, '_sl_reviews', TRUE) != '') 944 { 945 $post_html_content = get_post( get_post_meta($product_id, '_sl_reviews', TRUE))->post_content; 946 $data->sections['reviews'] = wp_kses( $post_html_content, $allowed_html_tags ); 947 } 948 if(get_post_meta($product_id, '_sl_other_notes', TRUE) != '') 949 { 950 $post_html_content = get_post( get_post_meta($product_id, '_sl_other_notes', TRUE))->post_content; 951 $data->sections['other_notes'] = wp_kses( $post_html_content, $allowed_html_tags ); 952 } 953 882 883 $data->sections = $this->get_product_information_sections( $product_id, $allowed_html_tags ); 954 884 955 885 $data->banners = array( … … 1057 987 1058 988 $allowed_html_tags = $this->get_allowed_html_tags(); 1059 1060 if(get_post_meta($product_id, '_sl_description', TRUE) != '') 1061 { 1062 $post_html_content = get_post( get_post_meta($product_id, '_sl_description', TRUE))->post_content; 1063 $data->sections['description'] = wp_kses( $post_html_content, $allowed_html_tags ); 1064 } 1065 if(get_post_meta($product_id, '_sl_installation', TRUE) != '') 1066 { 1067 $post_html_content = get_post( get_post_meta($product_id, '_sl_installation', TRUE))->post_content; 1068 $data->sections['installation'] = wp_kses( $post_html_content, $allowed_html_tags ); 1069 } 1070 if(get_post_meta($product_id, '_sl_faq', TRUE) != '') 1071 { 1072 $post_html_content = get_post( get_post_meta($product_id, '_sl_faq', TRUE))->post_content; 1073 $data->sections['faq'] = wp_kses( $post_html_content, $allowed_html_tags ); 1074 } 1075 if(get_post_meta($product_id, '_sl_screenshots', TRUE) != '') 1076 { 1077 $post_html_content = get_post( get_post_meta($product_id, '_sl_screenshots', TRUE))->post_content; 1078 $data->sections['screenshots'] = wp_kses( $post_html_content, $allowed_html_tags ); 1079 } 1080 if(get_post_meta($product_id, '_sl_changelog', TRUE) != '') 1081 { 1082 $post_html_content = get_post( get_post_meta($product_id, '_sl_changelog', TRUE))->post_content; 1083 $data->sections['changelog'] = wp_kses( $post_html_content, $allowed_html_tags ); 1084 } 1085 if(get_post_meta($product_id, '_sl_reviews', TRUE) != '') 1086 { 1087 $post_html_content = get_post( get_post_meta($product_id, '_sl_reviews', TRUE))->post_content; 1088 $data->sections['reviews'] = wp_kses( $post_html_content, $allowed_html_tags ); 1089 } 1090 if(get_post_meta($product_id, '_sl_other_notes', TRUE) != '') 1091 { 1092 $post_html_content = get_post( get_post_meta($product_id, '_sl_other_notes', TRUE))->post_content; 1093 $data->sections['other_notes'] = wp_kses( $post_html_content, $allowed_html_tags ); 1094 } 1095 1096 989 990 $data->sections = $this->get_product_information_sections( $product_id, $allowed_html_tags ); 991 1097 992 $data->banners = array( 1098 993 'low' => get_post_meta($product_id, '_sl_screenshots_high', TRUE), -
software-license-lite/trunk/api/class.sl.api.php
r3619649 r3741840 243 243 244 244 245 246 247 /** 248 * Builds plugin and theme information sections from a local post or custom URL. 249 * 250 * @param int $product_id Product ID. 251 * @param array $allowed_html_tags Allowed HTML for local post content. 252 * @return array 253 */ 254 function get_product_information_sections( $product_id, $allowed_html_tags ) 255 { 256 $section_fields = array( 257 'description' => '_sl_description', 258 'installation' => '_sl_installation', 259 'faq' => '_sl_faq', 260 'screenshots' => '_sl_screenshots', 261 'changelog' => '_sl_changelog', 262 'reviews' => '_sl_reviews', 263 'other_notes' => '_sl_other_notes' 264 ); 265 $sections = array(); 266 267 foreach ( $section_fields as $section_name => $meta_key ) 268 { 269 $custom_url = get_post_meta( $product_id, $meta_key . '_url', true ); 270 if ( ! empty( $custom_url ) ) 271 { 272 $section_content = $this->get_custom_url_section_content( $custom_url, $allowed_html_tags ); 273 if ( $section_content !== '' ) 274 $sections[ $section_name ] = $section_content; 275 276 continue; 277 } 278 279 $post_id = absint( get_post_meta( $product_id, $meta_key, true ) ); 280 if ( empty( $post_id ) ) 281 continue; 282 283 $section_post = get_post( $post_id ); 284 if ( ! is_object( $section_post ) || ! isset( $section_post->post_content ) ) 285 continue; 286 287 $sections[ $section_name ] = wp_kses( $section_post->post_content, $allowed_html_tags ); 288 } 289 290 return $sections; 291 } 292 293 /** 294 * Gets a custom URL section from the local cache or retrieves and caches it. 295 * 296 * This deliberately uses PHP's filesystem and HTTP extensions only. The API can 297 * execute outside WordPress; wp_kses() is the sole WordPress function used here. 298 * 299 * @param string $custom_url Remote section URL. 300 * @param array $allowed_html_tags Allowed HTML for the section response. 301 * @return string 302 */ 303 function get_custom_url_section_content( $custom_url, $allowed_html_tags ) 304 { 305 $custom_url = trim( $custom_url ); 306 if ( ! $this->is_custom_url_section_url( $custom_url ) ) 307 return ''; 308 309 $cache_directory = $this->get_custom_url_section_cache_directory(); 310 $cache_key = hash( 'sha256', $custom_url ); 311 $cached_content = $this->get_cached_custom_url_section_content( $cache_directory, $cache_key ); 312 313 if ( $cached_content !== false ) 314 return $cached_content; 315 316 $remote_content = $this->fetch_custom_url_section_content( $custom_url ); 317 if ( $remote_content === '' ) 318 return ''; 319 320 $section_content = $this->extract_custom_url_section_content( $remote_content ); 321 if ( $section_content === '' ) 322 return ''; 323 324 $section_content = wp_kses( $section_content, $allowed_html_tags ); 325 if ( $section_content === '' ) 326 return ''; 327 328 $this->cache_custom_url_section_content( $cache_directory, $cache_key, $section_content ); 329 330 return $section_content; 331 } 332 333 /** 334 * Validates that a custom section URL uses HTTP(S). 335 * 336 * @param string $url Remote section URL. 337 * @return bool 338 */ 339 function is_custom_url_section_url( $url ) 340 { 341 $url_parts = parse_url( $url ); 342 if ( ! is_array( $url_parts ) || empty( $url_parts['scheme'] ) || empty( $url_parts['host'] ) ) 343 return false; 344 345 return in_array( strtolower( $url_parts['scheme'] ), array( 'http', 'https' ), true ); 346 } 347 348 /** 349 * Returns the uploads subdirectory used for remote section caches. 350 * 351 * @return string 352 */ 353 function get_custom_url_section_cache_directory() 354 { 355 if ( defined( 'WP_UPLOADS' ) && WP_UPLOADS ) { 356 $base_directory = rtrim( WP_UPLOADS, '/\\' ); 357 } elseif ( defined( 'UPLOADS' ) && UPLOADS ) { 358 $base_directory = rtrim( ABSPATH . UPLOADS, '/\\' ); 359 } elseif ( defined( 'WP_CONTENT_DIR' ) && WP_CONTENT_DIR ) { 360 $base_directory = rtrim( WP_CONTENT_DIR, '/\\' ) . DIRECTORY_SEPARATOR . 'uploads'; 361 } else { 362 $base_directory = dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . DIRECTORY_SEPARATOR . 'uploads'; 363 } 364 365 $cache_directory = $base_directory . DIRECTORY_SEPARATOR . 'software-license-sections'; 366 367 if ( ! is_dir( $cache_directory ) ) { 368 @mkdir( $cache_directory, 0755, true ); 369 } 370 371 return is_dir( $cache_directory ) && is_writable( $cache_directory ) ? $cache_directory : ''; 372 } 373 374 /** 375 * Returns an unexpired cached custom section and deletes matching expired files. 376 * Cache filenames end in their Unix expiry timestamp for easy administration. 377 * 378 * @param string $cache_directory Cache directory. 379 * @param string $cache_key URL hash. 380 * @return string|false 381 */ 382 function get_cached_custom_url_section_content( $cache_directory, $cache_key ) 383 { 384 if ( $cache_directory === '' ) 385 return false; 386 387 $cache_files = glob( $cache_directory . DIRECTORY_SEPARATOR . 'section-' . $cache_key . '-*.html' ); 388 if ( ! is_array( $cache_files ) ) 389 return false; 390 391 $now = time(); 392 foreach ( $cache_files as $cache_file ) 393 { 394 if ( ! preg_match( '/-(\d+)\.html$/', basename( $cache_file ), $matches ) ) 395 continue; 396 397 $expires_at = (int) $matches[1]; 398 if ( $expires_at <= $now ) 399 { 400 @unlink( $cache_file ); 401 continue; 402 } 403 404 $cached_content = @file_get_contents( $cache_file ); 405 if ( $cached_content !== false && $cached_content !== '' ) 406 return $cached_content; 407 } 408 409 return false; 410 } 411 412 /** 413 * Stores a sanitized section in uploads for twelve hours. 414 * 415 * @param string $cache_directory Cache directory. 416 * @param string $cache_key URL hash. 417 * @param string $content Section HTML. 418 * @return void 419 */ 420 function cache_custom_url_section_content( $cache_directory, $cache_key, $content ) 421 { 422 if ( $cache_directory === '' ) 423 return; 424 425 $expires_at = time() + ( 12 * 60 * 60 ); 426 $cache_file = $cache_directory . DIRECTORY_SEPARATOR . 'section-' . $cache_key . '-' . $expires_at . '.html'; 427 $temporary_file = tempnam( $cache_directory, 'section-' ); 428 429 if ( $temporary_file === false ) 430 return; 431 432 if ( @file_put_contents( $temporary_file, $content, LOCK_EX ) === false ) 433 { 434 @unlink( $temporary_file ); 435 return; 436 } 437 438 if ( file_exists( $cache_file ) || ! @rename( $temporary_file, $cache_file ) ) 439 @unlink( $temporary_file ); 440 } 441 442 /** 443 * Retrieves a remote custom section with cURL when available, then PHP streams. 444 * 445 * @param string $url Remote section URL. 446 * @return string 447 */ 448 function fetch_custom_url_section_content( $url ) 449 { 450 if ( function_exists( 'curl_init' ) ) 451 { 452 $curl = curl_init( $url ); 453 curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ); 454 curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true ); 455 curl_setopt( $curl, CURLOPT_MAXREDIRS, 3 ); 456 curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 5 ); 457 curl_setopt( $curl, CURLOPT_TIMEOUT, 15 ); 458 curl_setopt( $curl, CURLOPT_USERAGENT, 'Software-License-Section-Cache/1.0' ); 459 460 $content = curl_exec( $curl ); 461 $status_code = (int) curl_getinfo( $curl, CURLINFO_HTTP_CODE ); 462 curl_close( $curl ); 463 464 return is_string( $content ) && $status_code >= 200 && $status_code < 300 ? $content : ''; 465 } 466 467 $context = stream_context_create( 468 array( 469 'http' => array( 470 'method' => 'GET', 471 'timeout' => 15, 472 'follow_location' => 1, 473 'max_redirects' => 3, 474 'ignore_errors' => true, 475 'header' => "User-Agent: Software-License-Section-Cache/1.0\r\n" 476 ) 477 ) 478 ); 479 $content = @file_get_contents( $url, false, $context ); 480 481 $status_code = 0; 482 if ( isset( $http_response_header ) && is_array( $http_response_header ) ) 483 { 484 foreach ( $http_response_header as $header ) 485 { 486 if ( preg_match( '#^HTTP/[^ ]+\s+(\d+)#i', $header, $matches ) ) 487 $status_code = (int) $matches[1]; 488 } 489 } 490 491 return is_string( $content ) && $status_code >= 200 && $status_code < 300 ? $content : ''; 492 } 493 494 /** 495 * Extracts the HTML inside a remote document's body element. 496 * 497 * @param string $content Remote document content. 498 * @return string 499 */ 500 function extract_custom_url_section_content( $content ) 501 { 502 if ( class_exists( 'DOMDocument' ) ) 503 { 504 $previous_libxml_errors = libxml_use_internal_errors( true ); 505 $document = new DOMDocument(); 506 $loaded = @$document->loadHTML( $content ); 507 libxml_clear_errors(); 508 libxml_use_internal_errors( $previous_libxml_errors ); 509 510 if ( $loaded ) 511 { 512 $body = $document->getElementsByTagName( 'body' )->item( 0 ); 513 if ( $body ) 514 { 515 $section_content = ''; 516 foreach ( $body->childNodes as $child ) 517 $section_content .= $document->saveHTML( $child ); 518 519 return trim( $section_content ); 520 } 521 } 522 } 523 524 if ( preg_match( '#<body[^>]*>(.*)</body>#is', $content, $matches ) ) 525 return trim( $matches[1] ); 526 527 return trim( $content ); 528 } 529 530 245 531 } -
software-license-lite/trunk/css/admin-product.css
r3379472 r3741840 8 8 #soliw_keys_root textarea {height: 150px} 9 9 #soliw_keys_root .soliw_keys_groups {min-height: 30px} 10 .select2-container { min-width:200px !important; max-width: 100%!important}10 .select2-container { max-width: 470px !important} 11 11 h2#soliw_keys_menu {padding-bottom: 0px; margin-bottom: 0px} 12 12 #soliw_keys_menu a {font-size: 12px; min-height: 24px;} … … 15 15 a#add_license_group_type {border: none; background-color: transparent; font-weight: bold; font-size: 16px; margin-bottom: 0px} 16 16 #woocommerce-product-data ul.wc-tabs li.sl_tab a::before {content: "\f173";} 17 18 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-select-controls { 19 display: inline-flex; 20 align-items: center; 21 width: calc(100% - 160px); 22 max-width: 960px; 23 vertical-align: middle; 24 } 25 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-select-controls .select2-container { 26 flex: 1 1 auto; 27 width: auto !important; 28 min-width: 200px !important; 29 } 30 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-select-or { 31 margin: 0 16px; 32 color: #646970; 33 } 34 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-url-toggle { 35 flex: 0 0 auto; 36 min-height: 32px; 37 } 38 #sl_data.woocommerce_options_panel .sl-custom-select-field.is-custom-url .sl-custom-url-toggle { 39 color: #2271b1; 40 border-color: #2271b1; 41 box-shadow: 0 0 0 1px #2271b1; 42 } 43 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-url-row { 44 display: flex; 45 align-items: stretch; 46 width: calc(100% - 160px); 47 max-width: 960px; 48 margin: 10px 0 0 0px; 49 } 50 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-url-row[hidden] { 51 display: none; 52 } 53 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-url-row .dashicons { 54 box-sizing: border-box; 55 width: 42px; 56 height: 42px; 57 padding: 10px 9px; 58 border: 1px solid #8c8f94; 59 border-right: 0; 60 border-radius: 3px 0 0 3px; 61 background: #f6f7f7; 62 color: #646970; 63 } 64 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-url-input { 65 flex: 1 1 auto; 66 width: auto; 67 min-height: 32px; 68 margin: 0; 69 border-radius: 0; 70 max-width: 428px; 71 } 72 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-url-clear { 73 min-height: 32px; 74 margin-left: 0; 75 } 76 77 @media screen and (max-width: 782px) { 78 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-select-controls, 79 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-url-row { 80 width: 100%; 81 margin-left: 0; 82 } 83 #sl_data.woocommerce_options_panel .sl-custom-select-field .sl-custom-select-or { 84 margin: 0 8px; 85 } 86 #sl_data.woocommerce_options_panel .sl-custom-select-field > .description { 87 margin-left: 0; 88 } 89 } -
software-license-lite/trunk/include/class.sl.admin.product.php
r3465087 r3741840 475 475 476 476 case 'woo_custom_select' : 477 $custom_url_meta_key = $field['id'] . '_url'; 478 $custom_url = get_post_meta( $post->ID, $custom_url_meta_key, true ); 479 480 // A custom URL and a WordPress post are mutually exclusive sources. 481 if ( ! empty( $custom_url ) ) 482 $field['selected'] = 0; 477 483 ?> 478 <p class="form-field <?php echo esc_html ( $field['class'] ) ?>"<?php if( isset($field['style']) ) { ?> style="<?php echo esc_html( $field['style'] ) ?>"<?php } ?>>479 <label for="<?php echo esc_ html ( $field['id'] ) ?>"><?php echo esc_html ( $field['label'] )?></label>484 <p class="form-field sl-custom-select-field <?php echo esc_attr( $field['class'] ) ?><?php echo ! empty( $custom_url ) ? ' is-custom-url' : ''; ?>" data-field-id="<?php echo esc_attr( $field['id'] ); ?>"<?php if( isset($field['style']) ) { ?> style="<?php echo esc_attr( $field['style'] ) ?>"<?php } ?>> 485 <label for="<?php echo esc_attr( $field['id'] ) ?>"><?php echo esc_html( $field['label'] ); ?></label> 480 486 481 487 <?php … … 537 543 } 538 544 539 if ( ! empty ($output_html))540 {541 ?><select name='<?php echo esc_html ( $field['id'] ) ?>' class='wc-enhanced-select-nostd wc_sl_chosen' data-placeholder='<?php esc_html_e ( 'Select a page', 'software-license-lite' ) ?>' id='<?php echo esc_html ( $field['id'] ) ?>'>545 { 546 ?><span class="sl-custom-select-controls"> 547 <select name="<?php echo esc_attr( $field['id'] ); ?>" class="wc-enhanced-select-nostd wc_sl_chosen sl-custom-select" data-placeholder="<?php esc_attr_e( 'Select a page', 'software-license-lite' ); ?>" id="<?php echo esc_attr( $field['id'] ); ?>"<?php echo ! empty( $custom_url ) ? ' disabled="disabled"' : ''; ?>> 542 548 <option value=''></option> 543 549 <?php … … 557 563 ); 558 564 559 echo wp_kses ( $output_html, $allowed_tags ) ?> 560 </select> 561 <span class='description'><?php echo esc_html ( $field['description'] ) ?></span> 562 <?php 563 564 } 565 565 echo wp_kses ( $output_html, $allowed_tags ); ?> 566 </select> 567 <span class="sl-custom-select-or"><?php esc_html_e( 'or', 'software-license-lite' ); ?></span> 568 <button type="button" class="button sl-custom-url-toggle" aria-expanded="<?php echo ! empty( $custom_url ) ? 'true' : 'false'; ?>"><?php esc_html_e( 'Custom URL', 'software-license-lite' ); ?></button> 569 </span> 570 <span class="sl-custom-url-row"<?php echo empty( $custom_url ) ? ' hidden' : ''; ?>> 571 <span class="dashicons dashicons-admin-links" aria-hidden="true"></span> 572 <input type="text" inputmode="url" class="sl-custom-url-input" name="<?php echo esc_attr( $custom_url_meta_key ); ?>" id="<?php echo esc_attr( $custom_url_meta_key ); ?>" value="<?php echo esc_attr( $custom_url ); ?>" placeholder="<?php esc_attr_e( 'https://example.com/details.html', 'software-license-lite' ); ?>" /> 573 <span class="sl-custom-select-or"><?php esc_html_e( 'or', 'software-license-lite' ); ?></span> 574 <button type="button" class="button sl-custom-url-clear"><?php esc_html_e( 'Post/Page', 'software-license-lite' ); ?></button> 575 </span> 576 <span class="description"><?php echo esc_html( $field['description'] ); ?></span> 577 <?php 578 } 579 566 580 ?> 567 581 </p> … … 694 708 call_user_func($field['function'] . '_save', $product_id); 695 709 } 710 elseif ( $field['type'] === 'woo_custom_select' ) 711 { 712 $custom_url_field = $field['id'] . '_url'; 713 // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 714 $custom_url = isset( $_POST[ $custom_url_field ] ) ? $this->sanitize_custom_url( wp_unslash( $_POST[ $custom_url_field ] ) ) : ''; 715 716 if ( ! empty( $custom_url ) ) 717 { 718 update_post_meta( $product_id, $field['id'], '' ); 719 update_post_meta( $product_id, $custom_url_field, $custom_url ); 720 } 721 else 722 { 723 // phpcs:ignore WordPress.Security.NonceVerification.Missing 724 $data = isset( $_POST[ $field['id'] ] ) ? absint( $_POST[ $field['id'] ] ) : ''; 725 update_post_meta( $product_id, $field['id'], $data ); 726 update_post_meta( $product_id, $custom_url_field, '' ); 727 } 728 } 696 729 else 697 730 { … … 703 736 } 704 737 738 } 739 740 741 /** 742 * Normalizes a custom section URL and only permits HTTP(S) targets. 743 * 744 * @param string $url URL entered in the product editor. 745 * @return string 746 */ 747 private function sanitize_custom_url( $url ) 748 { 749 $url = trim( $url ); 750 if ( $url === '' ) 751 return ''; 752 753 if ( strpos( $url, '//' ) === 0 ) 754 $url = 'https:' . $url; 755 elseif ( ! preg_match( '#^[a-z][a-z0-9+.-]*://#i', $url ) ) 756 $url = 'https://' . $url; 757 758 $url_parts = wp_parse_url( $url ); 759 if ( empty( $url_parts['scheme'] ) || empty( $url_parts['host'] ) || ! in_array( strtolower( $url_parts['scheme'] ), array( 'http', 'https' ), true ) ) 760 return ''; 761 762 return esc_url_raw( $url, array( 'http', 'https' ) ); 705 763 } 706 764 -
software-license-lite/trunk/js/admin-product.js
r3465087 r3741840 11 11 12 12 /* Searchable pull-down menus */ 13 /* 13 14 jQuery( 'select.wc_sl_chosen' ).select2({ 14 15 allow_single_deselect: true, 15 16 width: '60%' 16 17 }); 18 */ 19 20 jQuery( '.sl-custom-select-field.is-custom-url' ).each( function() { 21 sl_custom_url_toggle( jQuery( this ), true, false ); 22 } ); 23 24 jQuery( '#sl_data' ).on( 'click', '.sl-custom-url-toggle', function() { 25 var field = jQuery( this ).closest( '.sl-custom-select-field' ); 26 27 field.find( 'select.sl-custom-select' ).val( '' ).trigger( 'change' ); 28 sl_custom_url_toggle( field, true ); 29 field.find( '.sl-custom-url-input' ).trigger( 'focus' ); 30 } ); 31 32 jQuery( '#sl_data' ).on( 'click', '.sl-custom-url-clear', function() { 33 var field = jQuery( this ).closest( '.sl-custom-select-field' ); 34 35 field.find( '.sl-custom-url-input' ).val( '' ); 36 sl_custom_url_toggle( field, false ); 37 } ); 38 39 jQuery( '#sl_data' ).on( 'change', 'select.sl-custom-select', function() { 40 var field = jQuery( this ).closest( '.sl-custom-select-field' ); 41 42 if ( jQuery( this ).val() ) { 43 field.find( '.sl-custom-url-input' ).val( '' ); 44 sl_custom_url_toggle( field, false ); 45 } 46 } ); 47 17 48 18 49 // Tooltips … … 89 120 } 90 121 } 122 123 function sl_custom_url_toggle( field, show, animate ) 124 { 125 var controls = field.find( '.sl-custom-select-controls' ); 126 var url_row = field.find( '.sl-custom-url-row' ); 127 128 if ( typeof animate === 'undefined' ) { 129 animate = true; 130 } 131 132 field.toggleClass( 'is-custom-url', show ); 133 field.find( '.sl-custom-url-toggle' ).attr( 'aria-expanded', show ? 'true' : 'false' ); 134 field.find( 'select.sl-custom-select' ).prop( 'disabled', show ).trigger( 'change.select2' ); 135 136 if ( show ) { 137 url_row.prop( 'hidden', false ); 138 if ( animate ) { 139 controls.stop( true, true ).slideUp( 200 ); 140 url_row.stop( true, true ).hide().slideDown( 200 ); 141 } else { 142 controls.hide(); 143 url_row.show(); 144 } 145 } else if ( animate ) { 146 url_row.stop( true, true ).slideUp( 200, function() { 147 jQuery( this ).prop( 'hidden', true ); 148 } ); 149 controls.stop( true, true ).slideDown( 200 ); 150 } else { 151 url_row.prop( 'hidden', true ); 152 controls.show(); 153 } 154 } 91 155 92 156 function sl_predefined_keys_toggle(element) -
software-license-lite/trunk/readme.txt
r3619649 r3741840 3 3 Tags: license manager, software license, license key, licence 4 4 Requires at least: 3.0 5 Tested up to: 7. 0.26 Stable tag: 1. 2.95 Tested up to: 7.1.3 6 Stable tag: 1.3 7 7 License: GPLv2 or later 8 8 … … 190 190 191 191 == Changelog == 192 193 = 1.3 = 194 - 'Select a page' or 'Custom URL' functionality for Product Meta. 195 - WordPress 7.1.3 compatibility check and tag update. 196 - WooCommerce 11.2.1 compatibility check and tag update. 192 197 193 198 = 1.2.9 = -
software-license-lite/trunk/software-license-lite.php
r3619649 r3741840 6 6 * Author: Nsp Code 7 7 * Author URI: https://nsp-code.com/ 8 * Version: 1. 2.98 * Version: 1.3 9 9 * Text Domain: software-license-lite 10 10 * License: GPLv2 or later … … 23 23 define('SOLIW_URL', plugins_url('', __FILE__)); 24 24 25 define('SOLIW_VERSION', '1. 2.9');25 define('SOLIW_VERSION', '1.3'); 26 26 define('SOLIW_DB_VERSION', '1.1'); 27 27 -
software-license-lite/trunk/templates/emails/licence-expire.php
r3619649 r3741840 12 12 * 13 13 * @package WOO_SL/Templates/Emails 14 * @version 1. 0.014 * @version 1.2.9 15 15 */ 16 16 -
software-license-lite/trunk/templates/emails/licence-expired.php
r3619649 r3741840 12 12 * 13 13 * @package WOO_SL/Templates/Emails 14 * @version 1. 0.014 * @version 1.2.9 15 15 */ 16 16 -
software-license-lite/trunk/templates/emails/plain/licence-expire.php
r3619649 r3741840 12 12 * 13 13 * @package WOO_SL/Templates/Emails/Plain 14 * @version 1. 0.014 * @version 1.2.9 15 15 */ 16 16 -
software-license-lite/trunk/templates/emails/plain/licence-expired.php
r3619649 r3741840 12 12 * 13 13 * @package WOO_SL/Templates/Emails/Plain 14 * @version 1. 0.014 * @version 1.2.9 15 15 */ 16 16 -
software-license-lite/trunk/templates/myaccount/my-licence-manage.php
r3619649 r3741840 12 12 * 13 13 * @package WOO_SL/Templates 14 * @version 1. 0.014 * @version 1.2.9 15 15 */ 16 16 -
software-license-lite/trunk/templates/myaccount/my-licences.php
r3619649 r3741840 14 14 * 15 15 * @package WOO_SL/Templates 16 * @version 1. 0.016 * @version 1.2.9 17 17 */ 18 18
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)