Changeset 3350309
- Timestamp:
- 08/26/2025 10:41:34 AM (6 months ago)
- Location:
- lyxity/trunk
- Files:
-
- 5 edited
-
assets/js/main-page.js (modified) (7 diffs)
-
includes/class-lyxity-api.php (modified) (1 diff)
-
lyxity.php (modified) (8 diffs)
-
readme.txt (modified) (2 diffs)
-
templates/settings-page.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
lyxity/trunk/assets/js/main-page.js
r3348958 r3350309 8 8 alertify.defaults.theme.cancel = "btn btn-danger"; 9 9 alertify.defaults.theme.input = "form-control"; 10 11 // Fetch categories for Write Articles 12 function fetchCategories() { 13 const $list = $('#categories-list'); 14 const $loading = $('#categories-loading'); 15 const $error = $('#categories-error'); 16 17 if ($list.length === 0) return; // UI not present 18 19 $error.hide(); 20 $loading.show(); 21 $list.empty(); 22 23 console.log('[Lyxity] AJAX lyxity_get_categories - sending'); 24 $.ajax({ 25 url: lyxityVars.ajaxUrl, 26 type: 'POST', 27 data: { 28 action: 'lyxity_get_categories', 29 nonce: lyxityVars.nonce 30 }, 31 success: function(response) { 32 console.log('[Lyxity] AJAX lyxity_get_categories - success raw:', response); 33 if (response.success) { 34 // Response may be like { categories: [...] } or root array 35 const cats = response.data && (response.data.categories || response.data); 36 if (Array.isArray(cats) && cats.length > 0) { 37 categoriesCache = cats; 38 renderCategories(cats); 39 categoriesLoaded = true; 40 $error.hide(); 41 console.log('[Lyxity] Categories loaded:', cats.length); 42 } else { 43 showCategoriesError('No categories returned.'); 44 console.warn('[Lyxity] No categories in response'); 45 } 46 } else { 47 const message = (response.data && response.data.message) || 'Failed to fetch categories'; 48 showCategoriesError(message); 49 console.error('[Lyxity] Categories fetch error (server message):', message); 50 } 51 }, 52 error: function(xhr, status, error) { 53 showCategoriesError('Error fetching categories. Please try again.'); 54 console.error('[Lyxity] AJAX lyxity_get_categories - error:', status, error, xhr); 55 }, 56 complete: function() { 57 $loading.hide(); 58 console.log('[Lyxity] AJAX lyxity_get_categories - complete'); 59 } 60 }); 61 62 function showCategoriesError(msg) { 63 $error.find('p').text(msg); 64 $error.show(); 65 } 66 } 67 68 // Render categories as checkboxes 69 function renderCategories(categories) { 70 const $list = $('#categories-list'); 71 if ($list.length === 0) return; 72 73 $list.empty(); 74 categories.forEach(function(cat) { 75 const id = cat.id || cat.ID || cat.categoryId; 76 const name = cat.name || cat.title || cat.categoryName || ('Category ' + id); 77 if (!id) return; 78 const $item = $('<label style="display:block; margin:4px 0;">') 79 .append(`<input type="checkbox" class="lyxity-category" value="${id}"> `) 80 .append(document.createTextNode(name)); 81 $list.append($item); 82 }); 83 } 10 84 11 85 // Add bulk action handler … … 581 655 // Write Articles functionality 582 656 let suggestedKeywords = []; 657 let categoriesLoaded = false; 658 let categoriesCache = []; 583 659 584 660 // Handle keyword source selection … … 625 701 document.getElementById('metrics-column').style.display = 'block'; 626 702 703 // Fetch categories once when entering the article generation step 704 if (!categoriesLoaded) { 705 console.log('[Lyxity] Triggering fetchCategories() on keyword selection'); 706 fetchCategories(); 707 } else { 708 console.log('[Lyxity] Categories already loaded, count=', (categoriesCache||[]).length); 709 } 710 627 711 // Fetch and display keyword metrics 628 712 fetchKeywordMetrics(keyword); … … 843 927 const ctaLink = $('#cta-link').val().trim(); 844 928 const ctaCaption = $('#cta-caption').val().trim(); 929 const selectedCategories = $('#categories-list input.lyxity-category:checked').map(function(){ return parseInt(this.value, 10); }).get(); 930 console.log('[Lyxity] Write Articles - selectedCategories=', selectedCategories); 845 931 846 932 … … 895 981 896 982 // Make request via WordPress AJAX to proxy through PHP 983 console.log('[Lyxity] AJAX lyxity_generate_articles - sending', requestData, selectedCategories); 897 984 $.ajax({ 898 985 url: lyxityVars.ajaxUrl, … … 905 992 site_url: requestData.SiteUrl, 906 993 cta_text: requestData.ClickToActionText, 907 cta_link: requestData.ClickToActionLink 994 cta_link: requestData.ClickToActionLink, 995 // Send as JSON string; PHP handler normalizes both array and JSON 996 categories: JSON.stringify(selectedCategories) 908 997 }, 909 998 success: function(response) { 910 999 // Show a single white-background message per requirements 911 1000 console.log('[Lyxity] AJAX lyxity_generate_articles - success raw:', response); 912 1001 alertify.success('Article is being generated in background, you can track progress using Dashboard.'); 913 1002 }, 914 1003 error: function(xhr, status, error) { 1004 console.error('[Lyxity] AJAX lyxity_generate_articles - error:', status, error, xhr); 915 1005 alertify.error('Error generating articles: ' + (xhr.responseJSON?.message || error || 'Unknown error')); 916 1006 }, … … 918 1008 // Restore button state 919 1009 $button.prop('disabled', false).html(originalText); 1010 console.log('[Lyxity] AJAX lyxity_generate_articles - complete'); 920 1011 } 921 1012 }); -
lyxity/trunk/includes/class-lyxity-api.php
r3348958 r3350309 936 936 937 937 /** 938 * Get categories from the API for Write Article 939 * 940 * @return array|WP_Error Response array or WP_Error on failure 941 */ 942 public function get_categories() { 943 $site_url = get_site_url(); 944 $api_key = $this->get_api_key(); 945 if (empty($api_key)) { 946 return new WP_Error('missing_api_key', 'API key is not configured'); 947 } 948 $data = array( 949 // Follow existing keyword endpoint casing 950 'siteUrl' => $site_url, 951 'apiKey' => $api_key, 952 ); 953 // Debug: log request 954 error_log('Lyxity Debug - get_categories - Request: ' . json_encode($data)); 955 $result = $this->make_request('articles/categories', $data); 956 // Debug: log response (truncate to avoid huge logs) 957 $truncated = is_array($result) ? json_encode(array_slice($result, 0, 1)) : (is_string($result) ? substr($result, 0, 500) : print_r($result, true)); 958 error_log('Lyxity Debug - get_categories - Response (truncated): ' . $truncated); 959 return $result; 960 } 961 962 /** 938 963 * Apply rewrite content 939 964 * -
lyxity/trunk/lyxity.php
r3350053 r3350309 3 3 Plugin Name: Lyxity 4 4 Description: The art of modern search engine optimization 5 Version: 1. 6.05 Version: 1.7.0 6 6 Author: Infoforte 7 7 Author URI: https://infoforte.com … … 20 20 21 21 // Define plugin constants 22 define('LYXITY_VERSION', '1. 6.0');22 define('LYXITY_VERSION', '1.7.0'); 23 23 define('LYXITY_FILE', __FILE__); 24 24 define('LYXITY_PATH', plugin_dir_path(__FILE__)); … … 77 77 add_action('wp_ajax_lyxity_save_api_key', array($this, 'ajax_save_api_key')); 78 78 add_action('wp_ajax_lyxity_get_suggested_keywords', array($this, 'ajax_get_suggested_keywords')); 79 // New: Get categories for Write Articles 80 add_action('wp_ajax_lyxity_get_categories', array($this, 'ajax_get_categories')); 79 81 // New: Generate articles via Lyxity API 80 82 add_action('wp_ajax_lyxity_generate_articles', array($this, 'ajax_generate_articles')); … … 602 604 603 605 /** 606 * AJAX handler: Get categories list from API 607 */ 608 public function ajax_get_categories() { 609 // Security 610 if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'lyxity-ajax-nonce')) { 611 wp_send_json_error(array('message' => 'Security check failed.')); 612 } 613 if (!current_user_can('edit_posts')) { 614 wp_send_json_error(array('message' => 'You do not have permission to perform this action.')); 615 } 616 // Debug: incoming request 617 error_log('Lyxity Debug - ajax_get_categories - triggered by user ' . get_current_user_id()); 618 $api = new Lyxity_API(); 619 $response = $api->get_categories(); 620 if (is_wp_error($response)) { 621 error_log('Lyxity Debug - ajax_get_categories - WP_Error: ' . $response->get_error_message()); 622 wp_send_json_error(array('message' => 'API Error: ' . $response->get_error_message())); 623 } 624 // Expect API to return something like ['categories' => [ ['id'=>..,'name'=>..], ... ]] 625 $count = 0; 626 if (is_array($response)) { 627 if (isset($response['categories']) && is_array($response['categories'])) { $count = count($response['categories']); } 628 else { $count = count($response); } 629 } 630 error_log('Lyxity Debug - ajax_get_categories - success, categories count: ' . $count); 631 wp_send_json_success($response); 632 } 633 634 /** 604 635 * AJAX handler: Generate articles via Lyxity API 605 636 */ … … 619 650 $cta_text = isset($_POST['cta_text']) ? sanitize_text_field(wp_unslash($_POST['cta_text'])) : ''; 620 651 $cta_link = isset($_POST['cta_link']) ? esc_url_raw(wp_unslash($_POST['cta_link'])) : ''; 652 // Categories can arrive as array (categories[]) or JSON string; normalize to array of ints 653 $categories = array(); 654 if (isset($_POST['categories'])) { 655 $raw = wp_unslash($_POST['categories']); 656 if (is_array($raw)) { 657 $categories = array_map('absint', $raw); 658 } elseif (is_string($raw) && !empty($raw)) { 659 $decoded = json_decode($raw, true); 660 if (is_array($decoded)) { 661 $categories = array_map('absint', $decoded); 662 } 663 } 664 } 665 // Debug: log incoming 666 error_log('Lyxity Debug - ajax_generate_articles - incoming: keywords=' . $keywords . ', count=' . $number_of_articles . ', categories=' . json_encode($categories) . ', cta_link=' . $cta_link); 621 667 622 668 if (empty($keywords) || $number_of_articles <= 0) { … … 644 690 'ClickToActionLink' => $cta_link, 645 691 ); 692 if (!empty($categories)) { 693 // API expects parameter named "categories" as array of integers 694 $payload['categories'] = array_values(array_filter($categories)); 695 } 696 // Debug: log payload (safe fields only) 697 error_log('Lyxity Debug - ajax_generate_articles - payload: ' . json_encode($payload)); 646 698 647 699 // Call API via centralized class … … 650 702 651 703 if (is_wp_error($response)) { 704 error_log('Lyxity Debug - ajax_generate_articles - WP_Error: ' . $response->get_error_message()); 652 705 wp_send_json_error(array('message' => 'API Error: ' . $response->get_error_message())); 653 706 } 654 707 708 // Debug success 709 error_log('Lyxity Debug - ajax_generate_articles - success response received'); 655 710 wp_send_json_success($response); 656 711 } … … 1120 1175 </tr> 1121 1176 <tr> 1177 <th scope="row" style="width: 150px;"><label><?php esc_html_e('Categories:', 'lyxity'); ?></label></th> 1178 <td> 1179 <div id="categories-loading" style="display:none"><i class="fas fa-spinner fa-spin"></i> <?php esc_html_e('Loading categories...', 'lyxity'); ?></div> 1180 <div id="categories-error" class="notice notice-error" style="display:none;"><p></p></div> 1181 <div id="categories-list" style="max-height:160px; overflow:auto; border:1px solid #ccd0d4; padding:8px; border-radius:4px;"></div> 1182 <p class="description"><?php esc_html_e('Select one or more categories to assign to generated articles.', 'lyxity'); ?></p> 1183 </td> 1184 </tr> 1185 <tr> 1122 1186 <th scope="row" style="width: 150px;"><label for="cta-link"><?php esc_html_e('Call to Action Link:', 'lyxity'); ?></label></th> 1123 1187 <td> -
lyxity/trunk/readme.txt
r3350053 r3350309 4 4 Requires at least: 5.0 5 5 Tested up to: 6.8 6 Stable tag: 1. 6.06 Stable tag: 1.7.0 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 113 113 114 114 == Changelog == 115 = 1.7.0 = 116 - Bug fixes and other improvements 117 - Added category selection in create articles 118 115 119 = 1.6.0 = 116 120 - Bug fixes and other improvements -
lyxity/trunk/templates/settings-page.php
r3348958 r3350309 250 250 <?php esc_html_e('English (US)', 'lyxity'); ?> 251 251 </option> 252 <option value="fr-FR" <?php selected($default_language, 'fr-FR'); ?>>253 <?php esc_html_e('French', 'lyxity'); ?>254 </option>255 <option value="de-DE" <?php selected($default_language, 'de-DE'); ?>>256 <?php esc_html_e('German', 'lyxity'); ?>257 </option>258 <option value="es-ES" <?php selected($default_language, 'es-ES'); ?>>259 <?php esc_html_e('Spanish', 'lyxity'); ?>260 </option>261 252 </select> 262 253 </div>
Note: See TracChangeset
for help on using the changeset viewer.