Changeset 3488242
- Timestamp:
- 03/22/2026 02:18:23 PM (2 weeks ago)
- Location:
- 1platform-content-ai
- Files:
-
- 10 added
- 6 deleted
- 46 edited
- 1 copied
-
tags/2.7.0 (copied) (copied from 1platform-content-ai/trunk)
-
tags/2.7.0/.git/FETCH_HEAD (modified) (1 diff)
-
tags/2.7.0/.git/ORIG_HEAD (modified) (1 diff)
-
tags/2.7.0/.git/config (modified) (1 diff)
-
tags/2.7.0/.git/index (modified) (previous)
-
tags/2.7.0/.git/logs/HEAD (modified) (1 diff)
-
tags/2.7.0/.git/logs/refs/heads/main (modified) (1 diff)
-
tags/2.7.0/.git/logs/refs/remotes/origin/main (modified) (1 diff)
-
tags/2.7.0/.git/objects/pack/pack-51404a2c9ec36e0b80213079ab64990416b38e0c.idx (added)
-
tags/2.7.0/.git/objects/pack/pack-51404a2c9ec36e0b80213079ab64990416b38e0c.pack (added)
-
tags/2.7.0/.git/objects/pack/pack-51404a2c9ec36e0b80213079ab64990416b38e0c.rev (added)
-
tags/2.7.0/.git/objects/pack/pack-c09feb6171357996e22db74eefbb49f730997ba4.idx (deleted)
-
tags/2.7.0/.git/objects/pack/pack-c09feb6171357996e22db74eefbb49f730997ba4.pack (deleted)
-
tags/2.7.0/.git/objects/pack/pack-c09feb6171357996e22db74eefbb49f730997ba4.rev (deleted)
-
tags/2.7.0/.git/refs/heads/main (modified) (1 diff)
-
tags/2.7.0/.git/refs/remotes/origin/main (modified) (1 diff)
-
tags/2.7.0/.git/refs/tags/qa-v2.6.0-rc11 (added)
-
tags/2.7.0/.git/refs/tags/v2.7.0 (added)
-
tags/2.7.0/1platform-content-ai.php (modified) (1 diff)
-
tags/2.7.0/includes/admin/admin-ai-site-generator.php (modified) (1 diff)
-
tags/2.7.0/includes/admin/admin-init-configuration.php (modified) (1 diff)
-
tags/2.7.0/includes/admin/ai-site-generator/site-generator-form.php (modified) (7 diffs)
-
tags/2.7.0/includes/admin/assets/css/admin-ai-site-generator.css (modified) (3 diffs)
-
tags/2.7.0/includes/admin/assets/js/tai-category-sync.js (modified) (3 diffs)
-
tags/2.7.0/includes/admin/init-configuration/site-configuration-form.php (modified) (3 diffs)
-
tags/2.7.0/includes/admin/licenses/WPContentAILicensePanel.php (modified) (1 diff)
-
tags/2.7.0/includes/helpers/crypto.php (modified) (3 diffs)
-
tags/2.7.0/includes/helpers/site-generation.php (modified) (3 diffs)
-
tags/2.7.0/includes/services/api/OnePlatformClient.php (modified) (1 diff)
-
tags/2.7.0/includes/services/setup/SiteConfigService.php (modified) (2 diffs)
-
tags/2.7.0/includes/services/setup/WebsiteGenerationService.php (modified) (2 diffs)
-
tags/2.7.0/readme.txt (modified) (1 diff)
-
trunk/.git/FETCH_HEAD (modified) (1 diff)
-
trunk/.git/ORIG_HEAD (modified) (1 diff)
-
trunk/.git/config (modified) (1 diff)
-
trunk/.git/index (modified) (previous)
-
trunk/.git/logs/HEAD (modified) (1 diff)
-
trunk/.git/logs/refs/heads/main (modified) (1 diff)
-
trunk/.git/logs/refs/remotes/origin/main (modified) (1 diff)
-
trunk/.git/objects/pack/pack-51404a2c9ec36e0b80213079ab64990416b38e0c.idx (added)
-
trunk/.git/objects/pack/pack-51404a2c9ec36e0b80213079ab64990416b38e0c.pack (added)
-
trunk/.git/objects/pack/pack-51404a2c9ec36e0b80213079ab64990416b38e0c.rev (added)
-
trunk/.git/objects/pack/pack-c09feb6171357996e22db74eefbb49f730997ba4.idx (deleted)
-
trunk/.git/objects/pack/pack-c09feb6171357996e22db74eefbb49f730997ba4.pack (deleted)
-
trunk/.git/objects/pack/pack-c09feb6171357996e22db74eefbb49f730997ba4.rev (deleted)
-
trunk/.git/refs/heads/main (modified) (1 diff)
-
trunk/.git/refs/remotes/origin/main (modified) (1 diff)
-
trunk/.git/refs/tags/qa-v2.6.0-rc11 (added)
-
trunk/.git/refs/tags/v2.7.0 (added)
-
trunk/1platform-content-ai.php (modified) (1 diff)
-
trunk/includes/admin/admin-ai-site-generator.php (modified) (1 diff)
-
trunk/includes/admin/admin-init-configuration.php (modified) (1 diff)
-
trunk/includes/admin/ai-site-generator/site-generator-form.php (modified) (7 diffs)
-
trunk/includes/admin/assets/css/admin-ai-site-generator.css (modified) (3 diffs)
-
trunk/includes/admin/assets/js/tai-category-sync.js (modified) (3 diffs)
-
trunk/includes/admin/init-configuration/site-configuration-form.php (modified) (3 diffs)
-
trunk/includes/admin/licenses/WPContentAILicensePanel.php (modified) (1 diff)
-
trunk/includes/helpers/crypto.php (modified) (3 diffs)
-
trunk/includes/helpers/site-generation.php (modified) (3 diffs)
-
trunk/includes/services/api/OnePlatformClient.php (modified) (1 diff)
-
trunk/includes/services/setup/SiteConfigService.php (modified) (2 diffs)
-
trunk/includes/services/setup/WebsiteGenerationService.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
1platform-content-ai/tags/2.7.0/.git/FETCH_HEAD
r3487968 r3488242 1 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05branch 'main' of https://github.com/1platformlabs/1platform-content-ai1 0b507e94120943ce7672264963c81dd809d669f1 branch 'main' of https://github.com/1platformlabs/1platform-content-ai -
1platform-content-ai/tags/2.7.0/.git/ORIG_HEAD
r3487968 r3488242 1 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 1 0b507e94120943ce7672264963c81dd809d669f1 -
1platform-content-ai/tags/2.7.0/.git/config
r3487968 r3488242 10 10 auto = 0 11 11 [http "https://github.com/"] 12 extraheader = AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2hzX 0lyQ1dNZlRNZUNQTTV2V0VIckJrNFY5SDVVSUxFMDJRVW5ycw==12 extraheader = AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2hzXzZmZ1hBU01NQ25ORDF3aHA1aE5Rczl2dVpsRzBYMDNNcUZzVA== 13 13 [branch "main"] 14 14 remote = origin -
1platform-content-ai/tags/2.7.0/.git/logs/HEAD
r3487968 r3488242 1 0000000000000000000000000000000000000000 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 runner <runner@runnervm46oaq.xgcnp5xq0a5uzhbzbke14hj00f.gx.internal.cloudapp.net> 1774128261+0000 checkout: moving from master to main1 0000000000000000000000000000000000000000 0b507e94120943ce7672264963c81dd809d669f1 runner <runner@runnervm46oaq.2d4yuw4mzllehnbsihy5bpj2mb.cx.internal.cloudapp.net> 1774189052 +0000 checkout: moving from master to main -
1platform-content-ai/tags/2.7.0/.git/logs/refs/heads/main
r3487968 r3488242 1 0000000000000000000000000000000000000000 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 runner <runner@runnervm46oaq.xgcnp5xq0a5uzhbzbke14hj00f.gx.internal.cloudapp.net> 1774128261+0000 branch: Created from refs/remotes/origin/main1 0000000000000000000000000000000000000000 0b507e94120943ce7672264963c81dd809d669f1 runner <runner@runnervm46oaq.2d4yuw4mzllehnbsihy5bpj2mb.cx.internal.cloudapp.net> 1774189052 +0000 branch: Created from refs/remotes/origin/main -
1platform-content-ai/tags/2.7.0/.git/logs/refs/remotes/origin/main
r3487968 r3488242 1 0000000000000000000000000000000000000000 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 runner <runner@runnervm46oaq.xgcnp5xq0a5uzhbzbke14hj00f.gx.internal.cloudapp.net> 1774128261+0000 fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head1 0000000000000000000000000000000000000000 0b507e94120943ce7672264963c81dd809d669f1 runner <runner@runnervm46oaq.2d4yuw4mzllehnbsihy5bpj2mb.cx.internal.cloudapp.net> 1774189052 +0000 fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head -
1platform-content-ai/tags/2.7.0/.git/refs/heads/main
r3487968 r3488242 1 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 1 0b507e94120943ce7672264963c81dd809d669f1 -
1platform-content-ai/tags/2.7.0/.git/refs/remotes/origin/main
r3487968 r3488242 1 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 1 0b507e94120943ce7672264963c81dd809d669f1 -
1platform-content-ai/tags/2.7.0/1platform-content-ai.php
r3487968 r3488242 5 5 * Plugin URI: https://1platform.pro/ 6 6 * Description: SaaS client for AI-powered content generation, SEO optimization, and site management. All AI processing happens on 1Platform external servers. Includes free local tools: Table of Contents and Internal Links. 7 * Version: 2. 5.07 * Version: 2.7.0 8 8 * Author: 1Platform 9 9 * License: GPLv2 or later -
1platform-content-ai/tags/2.7.0/includes/admin/admin-ai-site-generator.php
r3483422 r3488242 84 84 'site_language' => sanitize_text_field( wp_unslash( $_POST['contai_site_language'] ?? 'english' ) ), 85 85 'site_category' => sanitize_text_field( wp_unslash( $_POST['contai_site_category'] ?? '' ) ), 86 'wordpress_theme' => sanitize_text_field( wp_unslash( $_POST['contai_wordpress_theme'] ?? ' blogfull' ) ),86 'wordpress_theme' => sanitize_text_field( wp_unslash( $_POST['contai_wordpress_theme'] ?? 'astra' ) ), 87 87 ), 88 88 'legal_info' => array( -
1platform-content-ai/tags/2.7.0/includes/admin/admin-init-configuration.php
r3483422 r3488242 66 66 67 67 if ( empty( $wordpress_theme ) ) { 68 $wordpress_theme = ' blogfull';68 $wordpress_theme = 'astra'; 69 69 } 70 70 -
1platform-content-ai/tags/2.7.0/includes/admin/ai-site-generator/site-generator-form.php
r3483422 r3488242 18 18 <input type="hidden" name="contai_start_site_generation" value="1"> 19 19 20 <!-- Step 1: Site & Business Configuration --> 20 <input type="hidden" id="contai_wordpress_theme" name="contai_wordpress_theme" value="astra"> 21 22 <!-- Step 1: Website Identity --> 21 23 <div class="contai-wizard-section"> 22 24 <div class="contai-section-header"> … … 25 27 </div> 26 28 <div class="contai-section-title-group"> 27 <h2 class="contai-section-title"><?php esc_html_e( ' Site & Business Configuration', '1platform-content-ai' ); ?></h2>28 <p class="contai-section-description"><?php esc_html_e( 'Define your website identity, target audience, and legal information.', '1platform-content-ai' ); ?></p>29 <h2 class="contai-section-title"><?php esc_html_e( 'Website Identity', '1platform-content-ai' ); ?></h2> 30 <p class="contai-section-description"><?php esc_html_e( 'Define what your website is about and who it targets.', '1platform-content-ai' ); ?></p> 29 31 </div> 30 32 </div> … … 37 39 </label> 38 40 <input type="text" id="contai_site_topic" name="contai_site_topic" class="contai-input" placeholder="e.g., Technology News" autocomplete="off" required> 39 </div> 40 41 <div class="contai-form-group"> 42 <label for="contai_wordpress_theme" class="contai-label"> 43 <?php esc_html_e( 'WordPress Theme', '1platform-content-ai' ); ?> 44 <span class="contai-required">*</span> 45 </label> 46 <select id="contai_wordpress_theme" name="contai_wordpress_theme" class="contai-select" autocomplete="off" required> 47 <option value="blogfull" selected>Blogfull</option> 48 <option value="newsmatic">Newsmatic</option> 49 </select> 50 </div> 51 52 <div class="contai-form-group"> 53 <label for="contai_site_language" class="contai-label"> 54 <?php esc_html_e( 'Language', '1platform-content-ai' ); ?> 55 <span class="contai-required">*</span> 56 </label> 57 <select id="contai_site_language" name="contai_site_language" class="contai-select" autocomplete="language" required data-category-select="#contai_site_category"> 58 <option value="english" selected><?php esc_html_e( 'English', '1platform-content-ai' ); ?></option> 59 <option value="spanish"><?php esc_html_e( 'Spanish', '1platform-content-ai' ); ?></option> 60 </select> 41 <span class="contai-help-text"><?php esc_html_e( 'The main subject of your website', '1platform-content-ai' ); ?></span> 61 42 </div> 62 43 … … 76 57 $title_en = esc_html( $category['title']['en'] ?? 'Unnamed Category' ); 77 58 $title_es = esc_html( $category['title']['es'] ?? $title_en ); 59 $category_theme = esc_attr( $category['recommended_theme'] ?? 'astra' ); 78 60 $is_selected = ( $saved_category === $category_id ); 79 61 ?> 80 <option value="<?php echo esc_attr( $category_id ); ?>"<?php selected( $is_selected ); ?> data-title-en="<?php echo esc_attr( $title_en ); ?>" data-title-es="<?php echo esc_attr( $title_es ); ?>" >62 <option value="<?php echo esc_attr( $category_id ); ?>"<?php selected( $is_selected ); ?> data-title-en="<?php echo esc_attr( $title_en ); ?>" data-title-es="<?php echo esc_attr( $title_es ); ?>" data-theme="<?php echo esc_attr( $category_theme ); ?>"> 81 63 <?php echo esc_html( $title_en ); ?> 82 64 </option> … … 84 66 <?php endif; ?> 85 67 </select> 68 <span class="contai-help-text"><?php esc_html_e( 'Determines the theme and content style', '1platform-content-ai' ); ?></span> 69 </div> 70 71 <div class="contai-form-group"> 72 <label for="contai_site_language" class="contai-label"> 73 <?php esc_html_e( 'Language', '1platform-content-ai' ); ?> 74 <span class="contai-required">*</span> 75 </label> 76 <select id="contai_site_language" name="contai_site_language" class="contai-select" autocomplete="language" required data-category-select="#contai_site_category"> 77 <option value="english" selected><?php esc_html_e( 'English', '1platform-content-ai' ); ?></option> 78 <option value="spanish"><?php esc_html_e( 'Spanish', '1platform-content-ai' ); ?></option> 79 </select> 86 80 </div> 87 81 … … 97 91 </div> 98 92 99 <div class="contai-form-group ">93 <div class="contai-form-group contai-span-2"> 100 94 <label for="contai_adsense_publisher" class="contai-label"> 101 95 <?php esc_html_e( 'AdSense Publisher ID', '1platform-content-ai' ); ?> … … 103 97 </label> 104 98 <input type="text" id="contai_adsense_publisher" name="contai_adsense_publisher" class="contai-input" placeholder="pub-1234567890123456" autocomplete="off" spellcheck="false" required> 105 </div> 106 </div> 107 108 <div class="contai-form-divider"></div> 109 110 <div class="contai-form-grid contai-grid-3"> 111 <div class="contai-form-group"> 112 <label for="contai_legal_owner" class="contai-label"> 113 <?php esc_html_e( 'Business Owner', '1platform-content-ai' ); ?> 114 <span class="contai-required">*</span> 115 </label> 116 <input type="text" id="contai_legal_owner" name="contai_legal_owner" class="contai-input" autocomplete="name" required> 117 </div> 118 119 <div class="contai-form-group"> 120 <label for="contai_legal_email" class="contai-label"> 121 <?php esc_html_e( 'Contact Email', '1platform-content-ai' ); ?> 122 <span class="contai-required">*</span> 123 </label> 124 <input type="email" id="contai_legal_email" name="contai_legal_email" class="contai-input" autocomplete="email" spellcheck="false" required> 125 </div> 126 127 <div class="contai-form-group"> 128 <label for="contai_legal_activity" class="contai-label"> 129 <?php esc_html_e( 'Business Activity', '1platform-content-ai' ); ?> 130 <span class="contai-required">*</span> 131 </label> 132 <input type="text" id="contai_legal_activity" name="contai_legal_activity" class="contai-input" autocomplete="organization-title" required> 133 </div> 134 135 <div class="contai-form-group contai-span-full"> 136 <label for="contai_legal_address" class="contai-label"> 137 <?php esc_html_e( 'Business Address', '1platform-content-ai' ); ?> 138 <span class="contai-required">*</span> 139 </label> 140 <input type="text" id="contai_legal_address" name="contai_legal_address" class="contai-input" autocomplete="street-address" required> 141 </div> 142 </div> 143 </div> 144 </div> 145 146 <!-- Step 2: Content Generation Settings --> 99 <span class="contai-help-text"><?php esc_html_e( 'Find it in your Google AdSense account under Account > Account information', '1platform-content-ai' ); ?></span> 100 </div> 101 </div> 102 </div> 103 </div> 104 105 <!-- Step 2: Legal Information --> 147 106 <div class="contai-wizard-section"> 148 107 <div class="contai-section-header"> 149 108 <div class="contai-step-indicator"> 150 109 <span class="contai-step-number">2</span> 110 </div> 111 <div class="contai-section-title-group"> 112 <h2 class="contai-section-title"><?php esc_html_e( 'Legal Information', '1platform-content-ai' ); ?></h2> 113 <p class="contai-section-description"><?php esc_html_e( 'Used to generate privacy policy, terms of service, and cookie consent.', '1platform-content-ai' ); ?></p> 114 </div> 115 </div> 116 <div class="contai-section-body"> 117 <div class="contai-form-grid contai-grid-3"> 118 <div class="contai-form-group"> 119 <label for="contai_legal_owner" class="contai-label"> 120 <?php esc_html_e( 'Business Owner', '1platform-content-ai' ); ?> 121 <span class="contai-required">*</span> 122 </label> 123 <input type="text" id="contai_legal_owner" name="contai_legal_owner" class="contai-input" placeholder="<?php esc_attr_e( 'John Doe', '1platform-content-ai' ); ?>" autocomplete="name" required> 124 </div> 125 126 <div class="contai-form-group"> 127 <label for="contai_legal_email" class="contai-label"> 128 <?php esc_html_e( 'Contact Email', '1platform-content-ai' ); ?> 129 <span class="contai-required">*</span> 130 </label> 131 <input type="email" id="contai_legal_email" name="contai_legal_email" class="contai-input" placeholder="<?php esc_attr_e( 'contact@example.com', '1platform-content-ai' ); ?>" autocomplete="email" spellcheck="false" required> 132 </div> 133 134 <div class="contai-form-group"> 135 <label for="contai_legal_activity" class="contai-label"> 136 <?php esc_html_e( 'Business Activity', '1platform-content-ai' ); ?> 137 <span class="contai-required">*</span> 138 </label> 139 <input type="text" id="contai_legal_activity" name="contai_legal_activity" class="contai-input" placeholder="<?php esc_attr_e( 'e.g., Digital publishing', '1platform-content-ai' ); ?>" autocomplete="organization-title" required> 140 </div> 141 142 <div class="contai-form-group contai-span-full"> 143 <label for="contai_legal_address" class="contai-label"> 144 <?php esc_html_e( 'Business Address', '1platform-content-ai' ); ?> 145 <span class="contai-required">*</span> 146 </label> 147 <input type="text" id="contai_legal_address" name="contai_legal_address" class="contai-input" placeholder="<?php esc_attr_e( '123 Main St, City, Country', '1platform-content-ai' ); ?>" autocomplete="street-address" required> 148 </div> 149 </div> 150 </div> 151 </div> 152 153 <!-- Step 3: Content Generation Settings --> 154 <div class="contai-wizard-section"> 155 <div class="contai-section-header"> 156 <div class="contai-step-indicator"> 157 <span class="contai-step-number">3</span> 151 158 </div> 152 159 <div class="contai-section-title-group"> -
1platform-content-ai/tags/2.7.0/includes/admin/assets/css/admin-ai-site-generator.css
r3483422 r3488242 183 183 .contai-span-full { 184 184 grid-column: 1 / -1; 185 } 186 187 .contai-span-2 { 188 grid-column: span 2; 185 189 } 186 190 … … 663 667 grid-column: 1 / -1; 664 668 } 669 670 .contai-span-2 { 671 grid-column: 1 / -1; 672 } 665 673 } 666 674 … … 711 719 } 712 720 721 .contai-span-2 { 722 grid-column: 1; 723 } 724 713 725 .contai-input, 714 726 .contai-select { -
1platform-content-ai/tags/2.7.0/includes/admin/assets/js/tai-category-sync.js
r3483422 r3488242 1 1 /** 2 * Category language sync for Content AI admin forms.2 * Category language sync and theme auto-selection for Content AI admin forms. 3 3 * 4 * Reads data-category-select / data-lang-select attributes from the language 5 * <select> and updates category option labels when the language changes. 4 * 1. Language sync: Updates category option labels when language changes. 5 * Expects the language select to have data-category-select="#id" pointing at 6 * the category select, and each category <option> to carry data-title-en and 7 * data-title-es attributes. 6 8 * 7 * Expects the language select to have data-category-select="#id" pointing at8 * the category select, and each category <option> to carry data-title-en and9 * data-title-es attributes.9 * 2. Theme auto-selection: When category changes, reads data-theme from the 10 * selected option and updates the hidden contai_wordpress_theme input. 11 * Also updates the readonly display field if present (Settings form). 10 12 * 11 13 * @package ContentAI … … 14 16 'use strict'; 15 17 18 // Language sync 16 19 document.querySelectorAll('select[data-category-select]').forEach(function (languageSelect) { 17 20 var categorySelector = languageSelect.getAttribute('data-category-select'); … … 43 46 }); 44 47 }); 48 49 // Theme auto-selection based on category 50 document.querySelectorAll('select[data-lang-select]').forEach(function (categorySelect) { 51 var themeInput = document.getElementById('contai_wordpress_theme'); 52 var themeDisplay = document.getElementById('contai_wordpress_theme_display'); 53 54 if (!themeInput) { 55 return; 56 } 57 58 function updateTheme() { 59 var selected = categorySelect.options[categorySelect.selectedIndex]; 60 var theme = selected ? selected.getAttribute('data-theme') : null; 61 62 if (theme) { 63 themeInput.value = theme; 64 if (themeDisplay) { 65 themeDisplay.value = theme.charAt(0).toUpperCase() + theme.slice(1); 66 } 67 } 68 } 69 70 categorySelect.addEventListener('change', updateTheme); 71 72 // Set initial theme if a category is already selected 73 if (categorySelect.value) { 74 updateTheme(); 75 } 76 }); 45 77 })(); -
1platform-content-ai/tags/2.7.0/includes/admin/init-configuration/site-configuration-form.php
r3483422 r3488242 10 10 $site_topic = esc_attr( get_option( 'contai_site_theme', 'blog' ) ); 11 11 $site_language = esc_attr( get_option( 'contai_site_language', 'spanish' ) ); 12 $wordpress_theme = esc_attr( get_option( 'contai_wordpress_theme', 'blogfull' ) );13 12 $languages = array( 'english', 'spanish' ); 14 $themes = array( 'blogfull', 'coral-dark', 'news-portal', 'hyper-news', 'celebnews', 'nova-blog' );15 13 16 14 // Fetch categories for the select field … … 79 77 $title_en = esc_html( $category['title']['en'] ?? 'Unnamed Category' ); 80 78 $title_es = esc_html( $category['title']['es'] ?? $title_en ); 79 $category_theme = esc_attr( $category['recommended_theme'] ?? 'astra' ); 81 80 $is_selected = ( $saved_category === $category_id ); 82 81 ?> 83 <option value="<?php echo esc_attr( $category_id ); ?>"<?php selected( $is_selected ); ?> data-title-en="<?php echo esc_attr( $title_en ); ?>" data-title-es="<?php echo esc_attr( $title_es ); ?>" >82 <option value="<?php echo esc_attr( $category_id ); ?>"<?php selected( $is_selected ); ?> data-title-en="<?php echo esc_attr( $title_en ); ?>" data-title-es="<?php echo esc_attr( $title_es ); ?>" data-theme="<?php echo esc_attr( $category_theme ); ?>"> 84 83 <?php 85 84 $current_lang = ContaiCategoryAPIService::normalizeLanguage( $site_language ); … … 94 93 95 94 <div class="contai-form-group"> 96 <label for="contai_wordpress_theme " class="contai-label">95 <label for="contai_wordpress_theme_display" class="contai-label"> 97 96 <span class="dashicons dashicons-art"></span> 98 97 <?php esc_html_e( 'WordPress Theme', '1platform-content-ai' ); ?> 99 98 </label> 100 <select id="contai_wordpress_theme" name="contai_wordpress_theme" class="contai-select"> 101 <?php foreach ( $themes as $theme ) : ?> 102 <option value="<?php echo esc_attr( $theme ); ?>" 103 <?php selected( $wordpress_theme, $theme ); ?>> 104 <?php echo esc_html( ucfirst( str_replace( '-', ' ', $theme ) ) ); ?> 105 </option> 106 <?php endforeach; ?> 107 </select> 108 <p class="contai-help-text"><?php esc_html_e( 'Select the WordPress theme to be installed', '1platform-content-ai' ); ?></p> 99 <input type="text" id="contai_wordpress_theme_display" class="contai-input" readonly 100 value="<?php echo esc_attr( ucfirst( get_option( 'contai_wordpress_theme', 'astra' ) ) ); ?>" 101 style="background-color: #f0f0f1; cursor: default;"> 102 <input type="hidden" id="contai_wordpress_theme" name="contai_wordpress_theme" 103 value="<?php echo esc_attr( get_option( 'contai_wordpress_theme', 'astra' ) ); ?>"> 104 <p class="contai-help-text"><?php esc_html_e( 'Automatically assigned based on the selected category', '1platform-content-ai' ); ?></p> 109 105 </div> 110 106 </div> -
1platform-content-ai/tags/2.7.0/includes/admin/licenses/WPContentAILicensePanel.php
r3483422 r3488242 310 310 } 311 311 312 // First attempt failed — force-refresh all tokens and retry once. 313 // This covers cases where token generation failed transiently 314 // and the OnePlatformClient retry was also exhausted. 315 contai_log('Content AI: Profile fetch failed on first attempt, force-refreshing tokens and retrying'); 316 $authService = ContaiOnePlatformAuthService::create(); 317 $refreshResult = $authService->forceRefreshAllTokens(); 318 319 if (!$refreshResult['success']) { 320 return false; 321 } 322 323 $retryResponse = $this->service->fetchUserProfile(); 324 325 if ($retryResponse->isSuccess()) { 326 $data = $retryResponse->getData(); 327 if ($data) { 328 $this->service->saveUserProfile($data); 329 } 330 return true; 331 } 332 312 333 return false; 313 334 } -
1platform-content-ai/tags/2.7.0/includes/helpers/crypto.php
r3483422 r3488242 24 24 25 25 if ($data === false || strpos($data, '::') === false) { 26 // Not in encrypted format — return original value (legacy unencrypted key) 26 27 return $encrypted_key; 27 28 } … … 30 31 31 32 if (count($parts) !== 2) { 32 return $encrypted_key; 33 contai_log('Content AI Decrypt: invalid encrypted format (unexpected parts)'); 34 return ''; 33 35 } 34 36 … … 36 38 37 39 if (empty($iv)) { 38 return $encrypted_key; 40 contai_log('Content AI Decrypt: invalid encrypted format (empty IV)'); 41 return ''; 39 42 } 40 43 41 44 $decrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $encryption_key, 0, $iv); 42 45 43 return $decrypted !== false ? $decrypted : $encrypted_key; 46 if ($decrypted === false) { 47 contai_log('Content AI Decrypt: openssl_decrypt failed — possible salt change or corrupted data'); 48 return ''; 49 } 50 51 return $decrypted; 44 52 } catch (Exception $e) { 45 contai_log(' Decryptionerror: ' . $e->getMessage());46 return $encrypted_key;53 contai_log('Content AI Decrypt error: ' . $e->getMessage()); 54 return ''; 47 55 } 48 56 } -
1platform-content-ai/tags/2.7.0/includes/helpers/site-generation.php
r3483422 r3488242 19 19 require_once __DIR__ . '/../services/api/OnePlatformEndpoints.php'; 20 20 require_once __DIR__ . '/../providers/WebsiteProvider.php'; 21 22 /** 23 * Get the primary sidebar ID for the active theme. 24 * 25 * Different themes register sidebars with different IDs. This function 26 * detects the correct sidebar by checking common naming conventions. 27 * 28 * @return string The primary sidebar ID 29 */ 30 function contai_get_primary_sidebar_id(): string { 31 global $wp_registered_sidebars; 32 33 if ( empty( $wp_registered_sidebars ) ) { 34 return 'sidebar-1'; 35 } 36 37 $priority = array( 'sidebar-1', 'sidebar', 'sidebar-primary', 'primary-sidebar', 'primary-widget-area' ); 38 foreach ( $priority as $id ) { 39 if ( isset( $wp_registered_sidebars[ $id ] ) ) { 40 return $id; 41 } 42 } 43 44 // Fallback: first registered sidebar 45 $keys = array_keys( $wp_registered_sidebars ); 46 return $keys[0] ?? 'sidebar-1'; 47 } 48 49 /** 50 * Apply theme-specific default settings after installation. 51 * 52 * Each theme may need different reading settings, sidebar layouts, 53 * or other configuration to look good out of the box with generated content. 54 * 55 * @param string $theme Theme slug 56 * @return void 57 */ 58 function contai_apply_theme_defaults( string $theme ): void { 59 // Common defaults for all themes 60 update_option( 'show_on_front', 'posts' ); 61 update_option( 'posts_per_page', 10 ); 62 63 switch ( $theme ) { 64 case 'newsmatic': 65 if ( function_exists( 'contai_set_newsmatic_reading_defaults' ) ) { 66 contai_set_newsmatic_reading_defaults(); 67 } 68 break; 69 70 case 'oceanwp': 71 set_theme_mod( 'ocean_blog_layout', 'right-sidebar' ); 72 break; 73 74 case 'generatepress': 75 set_theme_mod( 'content_layout_setting', 'content-sidebar' ); 76 break; 77 78 case 'colormag': 79 set_theme_mod( 'colormag_site_layout', 'right-sidebar' ); 80 break; 81 82 // astra, neve, blocksy, kadence, sydney: sensible defaults out of the box 83 } 84 } 21 85 22 86 /** … … 117 181 update_option( 'permalink_structure', '/%postname%/' ); 118 182 update_option( 'contai_flush_rewrite', true ); 119 120 if ( function_exists( 'contai_set_newsmatic_reading_defaults' ) ) {121 contai_set_newsmatic_reading_defaults();122 }123 183 124 184 contai_delete_sample_content(); … … 322 382 323 383 $sidebars_widgets = get_option( 'sidebars_widgets', array() ); 324 $sidebar_id = 'sidebar-1';384 $sidebar_id = contai_get_primary_sidebar_id(); 325 385 $sidebars_widgets[ $sidebar_id ] = array(); 326 386 -
1platform-content-ai/tags/2.7.0/includes/services/api/OnePlatformClient.php
r3483441 r3488242 98 98 99 99 if ($auth_headers === null) { 100 if ($retry_count < $this->config->getMaxRetries()) { 101 contai_log('Content AI: Auth token generation failed, force-refreshing and retrying'); 102 $this->auth_service->forceRefreshAllTokens(); 103 return $this->request($method, $url, $data, $retry_count + 1); 104 } 100 105 return $this->createAuthFailedResponse(); 101 106 } -
1platform-content-ai/tags/2.7.0/includes/services/setup/SiteConfigService.php
r3483422 r3488242 9 9 $siteTopic = $config['site_topic'] ?? ''; 10 10 $siteLanguage = $config['site_language'] ?? 'english'; 11 $wordpressTheme = $config['wordpress_theme'] ?? ' blogfull';11 $wordpressTheme = $config['wordpress_theme'] ?? 'astra'; 12 12 13 13 if (empty($siteTopic)) { … … 47 47 'site_topic' => get_option('contai_site_theme', ''), 48 48 'site_language' => get_option('contai_site_language', 'english'), 49 'wordpress_theme' => get_option('contai_wordpress_theme', ' blogfull'),49 'wordpress_theme' => get_option('contai_wordpress_theme', 'astra'), 50 50 ]; 51 51 } -
1platform-content-ai/tags/2.7.0/includes/services/setup/WebsiteGenerationService.php
r3483422 r3488242 4 4 5 5 require_once __DIR__ . '/../../helpers/site-generation.php'; 6 require_once __DIR__ . '/../../providers/WebsiteProvider.php'; 6 7 require_once __DIR__ . '/../legal/LegalPagesGenerator.php'; 7 8 … … 17 18 18 19 try { 19 $theme = get_option('contai_wordpress_theme', ' blogfull');20 $theme = get_option('contai_wordpress_theme', 'astra'); 20 21 21 22 contai_install_theme($theme); 22 $results['steps'][] = 'Theme installed'; 23 contai_apply_theme_defaults($theme); 24 $results['steps'][] = 'Theme installed and configured'; 25 26 try { 27 $website_provider = new ContaiWebsiteProvider(); 28 $website_provider->updateWebsite( array( 'theme' => sanitize_text_field( $theme ) ) ); 29 $results['steps'][] = 'Theme tracked in API'; 30 } catch ( Exception $e ) { 31 $results['errors'][] = 'Theme tracking failed (non-critical): ' . $e->getMessage(); 32 } 23 33 24 34 contai_setup_site_config(); -
1platform-content-ai/tags/2.7.0/readme.txt
r3487968 r3488242 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 2. 5.07 Stable tag: 2.7.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html -
1platform-content-ai/trunk/.git/FETCH_HEAD
r3487968 r3488242 1 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05branch 'main' of https://github.com/1platformlabs/1platform-content-ai1 0b507e94120943ce7672264963c81dd809d669f1 branch 'main' of https://github.com/1platformlabs/1platform-content-ai -
1platform-content-ai/trunk/.git/ORIG_HEAD
r3487968 r3488242 1 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 1 0b507e94120943ce7672264963c81dd809d669f1 -
1platform-content-ai/trunk/.git/config
r3487968 r3488242 10 10 auto = 0 11 11 [http "https://github.com/"] 12 extraheader = AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2hzX 0lyQ1dNZlRNZUNQTTV2V0VIckJrNFY5SDVVSUxFMDJRVW5ycw==12 extraheader = AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2hzXzZmZ1hBU01NQ25ORDF3aHA1aE5Rczl2dVpsRzBYMDNNcUZzVA== 13 13 [branch "main"] 14 14 remote = origin -
1platform-content-ai/trunk/.git/logs/HEAD
r3487968 r3488242 1 0000000000000000000000000000000000000000 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 runner <runner@runnervm46oaq.xgcnp5xq0a5uzhbzbke14hj00f.gx.internal.cloudapp.net> 1774128261+0000 checkout: moving from master to main1 0000000000000000000000000000000000000000 0b507e94120943ce7672264963c81dd809d669f1 runner <runner@runnervm46oaq.2d4yuw4mzllehnbsihy5bpj2mb.cx.internal.cloudapp.net> 1774189052 +0000 checkout: moving from master to main -
1platform-content-ai/trunk/.git/logs/refs/heads/main
r3487968 r3488242 1 0000000000000000000000000000000000000000 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 runner <runner@runnervm46oaq.xgcnp5xq0a5uzhbzbke14hj00f.gx.internal.cloudapp.net> 1774128261+0000 branch: Created from refs/remotes/origin/main1 0000000000000000000000000000000000000000 0b507e94120943ce7672264963c81dd809d669f1 runner <runner@runnervm46oaq.2d4yuw4mzllehnbsihy5bpj2mb.cx.internal.cloudapp.net> 1774189052 +0000 branch: Created from refs/remotes/origin/main -
1platform-content-ai/trunk/.git/logs/refs/remotes/origin/main
r3487968 r3488242 1 0000000000000000000000000000000000000000 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 runner <runner@runnervm46oaq.xgcnp5xq0a5uzhbzbke14hj00f.gx.internal.cloudapp.net> 1774128261+0000 fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head1 0000000000000000000000000000000000000000 0b507e94120943ce7672264963c81dd809d669f1 runner <runner@runnervm46oaq.2d4yuw4mzllehnbsihy5bpj2mb.cx.internal.cloudapp.net> 1774189052 +0000 fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head -
1platform-content-ai/trunk/.git/refs/heads/main
r3487968 r3488242 1 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 1 0b507e94120943ce7672264963c81dd809d669f1 -
1platform-content-ai/trunk/.git/refs/remotes/origin/main
r3487968 r3488242 1 6afa3c8a66ae5d8ab09b2c8d1fc2f42753b26e05 1 0b507e94120943ce7672264963c81dd809d669f1 -
1platform-content-ai/trunk/1platform-content-ai.php
r3487968 r3488242 5 5 * Plugin URI: https://1platform.pro/ 6 6 * Description: SaaS client for AI-powered content generation, SEO optimization, and site management. All AI processing happens on 1Platform external servers. Includes free local tools: Table of Contents and Internal Links. 7 * Version: 2. 5.07 * Version: 2.7.0 8 8 * Author: 1Platform 9 9 * License: GPLv2 or later -
1platform-content-ai/trunk/includes/admin/admin-ai-site-generator.php
r3483422 r3488242 84 84 'site_language' => sanitize_text_field( wp_unslash( $_POST['contai_site_language'] ?? 'english' ) ), 85 85 'site_category' => sanitize_text_field( wp_unslash( $_POST['contai_site_category'] ?? '' ) ), 86 'wordpress_theme' => sanitize_text_field( wp_unslash( $_POST['contai_wordpress_theme'] ?? ' blogfull' ) ),86 'wordpress_theme' => sanitize_text_field( wp_unslash( $_POST['contai_wordpress_theme'] ?? 'astra' ) ), 87 87 ), 88 88 'legal_info' => array( -
1platform-content-ai/trunk/includes/admin/admin-init-configuration.php
r3483422 r3488242 66 66 67 67 if ( empty( $wordpress_theme ) ) { 68 $wordpress_theme = ' blogfull';68 $wordpress_theme = 'astra'; 69 69 } 70 70 -
1platform-content-ai/trunk/includes/admin/ai-site-generator/site-generator-form.php
r3483422 r3488242 18 18 <input type="hidden" name="contai_start_site_generation" value="1"> 19 19 20 <!-- Step 1: Site & Business Configuration --> 20 <input type="hidden" id="contai_wordpress_theme" name="contai_wordpress_theme" value="astra"> 21 22 <!-- Step 1: Website Identity --> 21 23 <div class="contai-wizard-section"> 22 24 <div class="contai-section-header"> … … 25 27 </div> 26 28 <div class="contai-section-title-group"> 27 <h2 class="contai-section-title"><?php esc_html_e( ' Site & Business Configuration', '1platform-content-ai' ); ?></h2>28 <p class="contai-section-description"><?php esc_html_e( 'Define your website identity, target audience, and legal information.', '1platform-content-ai' ); ?></p>29 <h2 class="contai-section-title"><?php esc_html_e( 'Website Identity', '1platform-content-ai' ); ?></h2> 30 <p class="contai-section-description"><?php esc_html_e( 'Define what your website is about and who it targets.', '1platform-content-ai' ); ?></p> 29 31 </div> 30 32 </div> … … 37 39 </label> 38 40 <input type="text" id="contai_site_topic" name="contai_site_topic" class="contai-input" placeholder="e.g., Technology News" autocomplete="off" required> 39 </div> 40 41 <div class="contai-form-group"> 42 <label for="contai_wordpress_theme" class="contai-label"> 43 <?php esc_html_e( 'WordPress Theme', '1platform-content-ai' ); ?> 44 <span class="contai-required">*</span> 45 </label> 46 <select id="contai_wordpress_theme" name="contai_wordpress_theme" class="contai-select" autocomplete="off" required> 47 <option value="blogfull" selected>Blogfull</option> 48 <option value="newsmatic">Newsmatic</option> 49 </select> 50 </div> 51 52 <div class="contai-form-group"> 53 <label for="contai_site_language" class="contai-label"> 54 <?php esc_html_e( 'Language', '1platform-content-ai' ); ?> 55 <span class="contai-required">*</span> 56 </label> 57 <select id="contai_site_language" name="contai_site_language" class="contai-select" autocomplete="language" required data-category-select="#contai_site_category"> 58 <option value="english" selected><?php esc_html_e( 'English', '1platform-content-ai' ); ?></option> 59 <option value="spanish"><?php esc_html_e( 'Spanish', '1platform-content-ai' ); ?></option> 60 </select> 41 <span class="contai-help-text"><?php esc_html_e( 'The main subject of your website', '1platform-content-ai' ); ?></span> 61 42 </div> 62 43 … … 76 57 $title_en = esc_html( $category['title']['en'] ?? 'Unnamed Category' ); 77 58 $title_es = esc_html( $category['title']['es'] ?? $title_en ); 59 $category_theme = esc_attr( $category['recommended_theme'] ?? 'astra' ); 78 60 $is_selected = ( $saved_category === $category_id ); 79 61 ?> 80 <option value="<?php echo esc_attr( $category_id ); ?>"<?php selected( $is_selected ); ?> data-title-en="<?php echo esc_attr( $title_en ); ?>" data-title-es="<?php echo esc_attr( $title_es ); ?>" >62 <option value="<?php echo esc_attr( $category_id ); ?>"<?php selected( $is_selected ); ?> data-title-en="<?php echo esc_attr( $title_en ); ?>" data-title-es="<?php echo esc_attr( $title_es ); ?>" data-theme="<?php echo esc_attr( $category_theme ); ?>"> 81 63 <?php echo esc_html( $title_en ); ?> 82 64 </option> … … 84 66 <?php endif; ?> 85 67 </select> 68 <span class="contai-help-text"><?php esc_html_e( 'Determines the theme and content style', '1platform-content-ai' ); ?></span> 69 </div> 70 71 <div class="contai-form-group"> 72 <label for="contai_site_language" class="contai-label"> 73 <?php esc_html_e( 'Language', '1platform-content-ai' ); ?> 74 <span class="contai-required">*</span> 75 </label> 76 <select id="contai_site_language" name="contai_site_language" class="contai-select" autocomplete="language" required data-category-select="#contai_site_category"> 77 <option value="english" selected><?php esc_html_e( 'English', '1platform-content-ai' ); ?></option> 78 <option value="spanish"><?php esc_html_e( 'Spanish', '1platform-content-ai' ); ?></option> 79 </select> 86 80 </div> 87 81 … … 97 91 </div> 98 92 99 <div class="contai-form-group ">93 <div class="contai-form-group contai-span-2"> 100 94 <label for="contai_adsense_publisher" class="contai-label"> 101 95 <?php esc_html_e( 'AdSense Publisher ID', '1platform-content-ai' ); ?> … … 103 97 </label> 104 98 <input type="text" id="contai_adsense_publisher" name="contai_adsense_publisher" class="contai-input" placeholder="pub-1234567890123456" autocomplete="off" spellcheck="false" required> 105 </div> 106 </div> 107 108 <div class="contai-form-divider"></div> 109 110 <div class="contai-form-grid contai-grid-3"> 111 <div class="contai-form-group"> 112 <label for="contai_legal_owner" class="contai-label"> 113 <?php esc_html_e( 'Business Owner', '1platform-content-ai' ); ?> 114 <span class="contai-required">*</span> 115 </label> 116 <input type="text" id="contai_legal_owner" name="contai_legal_owner" class="contai-input" autocomplete="name" required> 117 </div> 118 119 <div class="contai-form-group"> 120 <label for="contai_legal_email" class="contai-label"> 121 <?php esc_html_e( 'Contact Email', '1platform-content-ai' ); ?> 122 <span class="contai-required">*</span> 123 </label> 124 <input type="email" id="contai_legal_email" name="contai_legal_email" class="contai-input" autocomplete="email" spellcheck="false" required> 125 </div> 126 127 <div class="contai-form-group"> 128 <label for="contai_legal_activity" class="contai-label"> 129 <?php esc_html_e( 'Business Activity', '1platform-content-ai' ); ?> 130 <span class="contai-required">*</span> 131 </label> 132 <input type="text" id="contai_legal_activity" name="contai_legal_activity" class="contai-input" autocomplete="organization-title" required> 133 </div> 134 135 <div class="contai-form-group contai-span-full"> 136 <label for="contai_legal_address" class="contai-label"> 137 <?php esc_html_e( 'Business Address', '1platform-content-ai' ); ?> 138 <span class="contai-required">*</span> 139 </label> 140 <input type="text" id="contai_legal_address" name="contai_legal_address" class="contai-input" autocomplete="street-address" required> 141 </div> 142 </div> 143 </div> 144 </div> 145 146 <!-- Step 2: Content Generation Settings --> 99 <span class="contai-help-text"><?php esc_html_e( 'Find it in your Google AdSense account under Account > Account information', '1platform-content-ai' ); ?></span> 100 </div> 101 </div> 102 </div> 103 </div> 104 105 <!-- Step 2: Legal Information --> 147 106 <div class="contai-wizard-section"> 148 107 <div class="contai-section-header"> 149 108 <div class="contai-step-indicator"> 150 109 <span class="contai-step-number">2</span> 110 </div> 111 <div class="contai-section-title-group"> 112 <h2 class="contai-section-title"><?php esc_html_e( 'Legal Information', '1platform-content-ai' ); ?></h2> 113 <p class="contai-section-description"><?php esc_html_e( 'Used to generate privacy policy, terms of service, and cookie consent.', '1platform-content-ai' ); ?></p> 114 </div> 115 </div> 116 <div class="contai-section-body"> 117 <div class="contai-form-grid contai-grid-3"> 118 <div class="contai-form-group"> 119 <label for="contai_legal_owner" class="contai-label"> 120 <?php esc_html_e( 'Business Owner', '1platform-content-ai' ); ?> 121 <span class="contai-required">*</span> 122 </label> 123 <input type="text" id="contai_legal_owner" name="contai_legal_owner" class="contai-input" placeholder="<?php esc_attr_e( 'John Doe', '1platform-content-ai' ); ?>" autocomplete="name" required> 124 </div> 125 126 <div class="contai-form-group"> 127 <label for="contai_legal_email" class="contai-label"> 128 <?php esc_html_e( 'Contact Email', '1platform-content-ai' ); ?> 129 <span class="contai-required">*</span> 130 </label> 131 <input type="email" id="contai_legal_email" name="contai_legal_email" class="contai-input" placeholder="<?php esc_attr_e( 'contact@example.com', '1platform-content-ai' ); ?>" autocomplete="email" spellcheck="false" required> 132 </div> 133 134 <div class="contai-form-group"> 135 <label for="contai_legal_activity" class="contai-label"> 136 <?php esc_html_e( 'Business Activity', '1platform-content-ai' ); ?> 137 <span class="contai-required">*</span> 138 </label> 139 <input type="text" id="contai_legal_activity" name="contai_legal_activity" class="contai-input" placeholder="<?php esc_attr_e( 'e.g., Digital publishing', '1platform-content-ai' ); ?>" autocomplete="organization-title" required> 140 </div> 141 142 <div class="contai-form-group contai-span-full"> 143 <label for="contai_legal_address" class="contai-label"> 144 <?php esc_html_e( 'Business Address', '1platform-content-ai' ); ?> 145 <span class="contai-required">*</span> 146 </label> 147 <input type="text" id="contai_legal_address" name="contai_legal_address" class="contai-input" placeholder="<?php esc_attr_e( '123 Main St, City, Country', '1platform-content-ai' ); ?>" autocomplete="street-address" required> 148 </div> 149 </div> 150 </div> 151 </div> 152 153 <!-- Step 3: Content Generation Settings --> 154 <div class="contai-wizard-section"> 155 <div class="contai-section-header"> 156 <div class="contai-step-indicator"> 157 <span class="contai-step-number">3</span> 151 158 </div> 152 159 <div class="contai-section-title-group"> -
1platform-content-ai/trunk/includes/admin/assets/css/admin-ai-site-generator.css
r3483422 r3488242 183 183 .contai-span-full { 184 184 grid-column: 1 / -1; 185 } 186 187 .contai-span-2 { 188 grid-column: span 2; 185 189 } 186 190 … … 663 667 grid-column: 1 / -1; 664 668 } 669 670 .contai-span-2 { 671 grid-column: 1 / -1; 672 } 665 673 } 666 674 … … 711 719 } 712 720 721 .contai-span-2 { 722 grid-column: 1; 723 } 724 713 725 .contai-input, 714 726 .contai-select { -
1platform-content-ai/trunk/includes/admin/assets/js/tai-category-sync.js
r3483422 r3488242 1 1 /** 2 * Category language sync for Content AI admin forms.2 * Category language sync and theme auto-selection for Content AI admin forms. 3 3 * 4 * Reads data-category-select / data-lang-select attributes from the language 5 * <select> and updates category option labels when the language changes. 4 * 1. Language sync: Updates category option labels when language changes. 5 * Expects the language select to have data-category-select="#id" pointing at 6 * the category select, and each category <option> to carry data-title-en and 7 * data-title-es attributes. 6 8 * 7 * Expects the language select to have data-category-select="#id" pointing at8 * the category select, and each category <option> to carry data-title-en and9 * data-title-es attributes.9 * 2. Theme auto-selection: When category changes, reads data-theme from the 10 * selected option and updates the hidden contai_wordpress_theme input. 11 * Also updates the readonly display field if present (Settings form). 10 12 * 11 13 * @package ContentAI … … 14 16 'use strict'; 15 17 18 // Language sync 16 19 document.querySelectorAll('select[data-category-select]').forEach(function (languageSelect) { 17 20 var categorySelector = languageSelect.getAttribute('data-category-select'); … … 43 46 }); 44 47 }); 48 49 // Theme auto-selection based on category 50 document.querySelectorAll('select[data-lang-select]').forEach(function (categorySelect) { 51 var themeInput = document.getElementById('contai_wordpress_theme'); 52 var themeDisplay = document.getElementById('contai_wordpress_theme_display'); 53 54 if (!themeInput) { 55 return; 56 } 57 58 function updateTheme() { 59 var selected = categorySelect.options[categorySelect.selectedIndex]; 60 var theme = selected ? selected.getAttribute('data-theme') : null; 61 62 if (theme) { 63 themeInput.value = theme; 64 if (themeDisplay) { 65 themeDisplay.value = theme.charAt(0).toUpperCase() + theme.slice(1); 66 } 67 } 68 } 69 70 categorySelect.addEventListener('change', updateTheme); 71 72 // Set initial theme if a category is already selected 73 if (categorySelect.value) { 74 updateTheme(); 75 } 76 }); 45 77 })(); -
1platform-content-ai/trunk/includes/admin/init-configuration/site-configuration-form.php
r3483422 r3488242 10 10 $site_topic = esc_attr( get_option( 'contai_site_theme', 'blog' ) ); 11 11 $site_language = esc_attr( get_option( 'contai_site_language', 'spanish' ) ); 12 $wordpress_theme = esc_attr( get_option( 'contai_wordpress_theme', 'blogfull' ) );13 12 $languages = array( 'english', 'spanish' ); 14 $themes = array( 'blogfull', 'coral-dark', 'news-portal', 'hyper-news', 'celebnews', 'nova-blog' );15 13 16 14 // Fetch categories for the select field … … 79 77 $title_en = esc_html( $category['title']['en'] ?? 'Unnamed Category' ); 80 78 $title_es = esc_html( $category['title']['es'] ?? $title_en ); 79 $category_theme = esc_attr( $category['recommended_theme'] ?? 'astra' ); 81 80 $is_selected = ( $saved_category === $category_id ); 82 81 ?> 83 <option value="<?php echo esc_attr( $category_id ); ?>"<?php selected( $is_selected ); ?> data-title-en="<?php echo esc_attr( $title_en ); ?>" data-title-es="<?php echo esc_attr( $title_es ); ?>" >82 <option value="<?php echo esc_attr( $category_id ); ?>"<?php selected( $is_selected ); ?> data-title-en="<?php echo esc_attr( $title_en ); ?>" data-title-es="<?php echo esc_attr( $title_es ); ?>" data-theme="<?php echo esc_attr( $category_theme ); ?>"> 84 83 <?php 85 84 $current_lang = ContaiCategoryAPIService::normalizeLanguage( $site_language ); … … 94 93 95 94 <div class="contai-form-group"> 96 <label for="contai_wordpress_theme " class="contai-label">95 <label for="contai_wordpress_theme_display" class="contai-label"> 97 96 <span class="dashicons dashicons-art"></span> 98 97 <?php esc_html_e( 'WordPress Theme', '1platform-content-ai' ); ?> 99 98 </label> 100 <select id="contai_wordpress_theme" name="contai_wordpress_theme" class="contai-select"> 101 <?php foreach ( $themes as $theme ) : ?> 102 <option value="<?php echo esc_attr( $theme ); ?>" 103 <?php selected( $wordpress_theme, $theme ); ?>> 104 <?php echo esc_html( ucfirst( str_replace( '-', ' ', $theme ) ) ); ?> 105 </option> 106 <?php endforeach; ?> 107 </select> 108 <p class="contai-help-text"><?php esc_html_e( 'Select the WordPress theme to be installed', '1platform-content-ai' ); ?></p> 99 <input type="text" id="contai_wordpress_theme_display" class="contai-input" readonly 100 value="<?php echo esc_attr( ucfirst( get_option( 'contai_wordpress_theme', 'astra' ) ) ); ?>" 101 style="background-color: #f0f0f1; cursor: default;"> 102 <input type="hidden" id="contai_wordpress_theme" name="contai_wordpress_theme" 103 value="<?php echo esc_attr( get_option( 'contai_wordpress_theme', 'astra' ) ); ?>"> 104 <p class="contai-help-text"><?php esc_html_e( 'Automatically assigned based on the selected category', '1platform-content-ai' ); ?></p> 109 105 </div> 110 106 </div> -
1platform-content-ai/trunk/includes/admin/licenses/WPContentAILicensePanel.php
r3483422 r3488242 310 310 } 311 311 312 // First attempt failed — force-refresh all tokens and retry once. 313 // This covers cases where token generation failed transiently 314 // and the OnePlatformClient retry was also exhausted. 315 contai_log('Content AI: Profile fetch failed on first attempt, force-refreshing tokens and retrying'); 316 $authService = ContaiOnePlatformAuthService::create(); 317 $refreshResult = $authService->forceRefreshAllTokens(); 318 319 if (!$refreshResult['success']) { 320 return false; 321 } 322 323 $retryResponse = $this->service->fetchUserProfile(); 324 325 if ($retryResponse->isSuccess()) { 326 $data = $retryResponse->getData(); 327 if ($data) { 328 $this->service->saveUserProfile($data); 329 } 330 return true; 331 } 332 312 333 return false; 313 334 } -
1platform-content-ai/trunk/includes/helpers/crypto.php
r3483422 r3488242 24 24 25 25 if ($data === false || strpos($data, '::') === false) { 26 // Not in encrypted format — return original value (legacy unencrypted key) 26 27 return $encrypted_key; 27 28 } … … 30 31 31 32 if (count($parts) !== 2) { 32 return $encrypted_key; 33 contai_log('Content AI Decrypt: invalid encrypted format (unexpected parts)'); 34 return ''; 33 35 } 34 36 … … 36 38 37 39 if (empty($iv)) { 38 return $encrypted_key; 40 contai_log('Content AI Decrypt: invalid encrypted format (empty IV)'); 41 return ''; 39 42 } 40 43 41 44 $decrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $encryption_key, 0, $iv); 42 45 43 return $decrypted !== false ? $decrypted : $encrypted_key; 46 if ($decrypted === false) { 47 contai_log('Content AI Decrypt: openssl_decrypt failed — possible salt change or corrupted data'); 48 return ''; 49 } 50 51 return $decrypted; 44 52 } catch (Exception $e) { 45 contai_log(' Decryptionerror: ' . $e->getMessage());46 return $encrypted_key;53 contai_log('Content AI Decrypt error: ' . $e->getMessage()); 54 return ''; 47 55 } 48 56 } -
1platform-content-ai/trunk/includes/helpers/site-generation.php
r3483422 r3488242 19 19 require_once __DIR__ . '/../services/api/OnePlatformEndpoints.php'; 20 20 require_once __DIR__ . '/../providers/WebsiteProvider.php'; 21 22 /** 23 * Get the primary sidebar ID for the active theme. 24 * 25 * Different themes register sidebars with different IDs. This function 26 * detects the correct sidebar by checking common naming conventions. 27 * 28 * @return string The primary sidebar ID 29 */ 30 function contai_get_primary_sidebar_id(): string { 31 global $wp_registered_sidebars; 32 33 if ( empty( $wp_registered_sidebars ) ) { 34 return 'sidebar-1'; 35 } 36 37 $priority = array( 'sidebar-1', 'sidebar', 'sidebar-primary', 'primary-sidebar', 'primary-widget-area' ); 38 foreach ( $priority as $id ) { 39 if ( isset( $wp_registered_sidebars[ $id ] ) ) { 40 return $id; 41 } 42 } 43 44 // Fallback: first registered sidebar 45 $keys = array_keys( $wp_registered_sidebars ); 46 return $keys[0] ?? 'sidebar-1'; 47 } 48 49 /** 50 * Apply theme-specific default settings after installation. 51 * 52 * Each theme may need different reading settings, sidebar layouts, 53 * or other configuration to look good out of the box with generated content. 54 * 55 * @param string $theme Theme slug 56 * @return void 57 */ 58 function contai_apply_theme_defaults( string $theme ): void { 59 // Common defaults for all themes 60 update_option( 'show_on_front', 'posts' ); 61 update_option( 'posts_per_page', 10 ); 62 63 switch ( $theme ) { 64 case 'newsmatic': 65 if ( function_exists( 'contai_set_newsmatic_reading_defaults' ) ) { 66 contai_set_newsmatic_reading_defaults(); 67 } 68 break; 69 70 case 'oceanwp': 71 set_theme_mod( 'ocean_blog_layout', 'right-sidebar' ); 72 break; 73 74 case 'generatepress': 75 set_theme_mod( 'content_layout_setting', 'content-sidebar' ); 76 break; 77 78 case 'colormag': 79 set_theme_mod( 'colormag_site_layout', 'right-sidebar' ); 80 break; 81 82 // astra, neve, blocksy, kadence, sydney: sensible defaults out of the box 83 } 84 } 21 85 22 86 /** … … 117 181 update_option( 'permalink_structure', '/%postname%/' ); 118 182 update_option( 'contai_flush_rewrite', true ); 119 120 if ( function_exists( 'contai_set_newsmatic_reading_defaults' ) ) {121 contai_set_newsmatic_reading_defaults();122 }123 183 124 184 contai_delete_sample_content(); … … 322 382 323 383 $sidebars_widgets = get_option( 'sidebars_widgets', array() ); 324 $sidebar_id = 'sidebar-1';384 $sidebar_id = contai_get_primary_sidebar_id(); 325 385 $sidebars_widgets[ $sidebar_id ] = array(); 326 386 -
1platform-content-ai/trunk/includes/services/api/OnePlatformClient.php
r3483441 r3488242 98 98 99 99 if ($auth_headers === null) { 100 if ($retry_count < $this->config->getMaxRetries()) { 101 contai_log('Content AI: Auth token generation failed, force-refreshing and retrying'); 102 $this->auth_service->forceRefreshAllTokens(); 103 return $this->request($method, $url, $data, $retry_count + 1); 104 } 100 105 return $this->createAuthFailedResponse(); 101 106 } -
1platform-content-ai/trunk/includes/services/setup/SiteConfigService.php
r3483422 r3488242 9 9 $siteTopic = $config['site_topic'] ?? ''; 10 10 $siteLanguage = $config['site_language'] ?? 'english'; 11 $wordpressTheme = $config['wordpress_theme'] ?? ' blogfull';11 $wordpressTheme = $config['wordpress_theme'] ?? 'astra'; 12 12 13 13 if (empty($siteTopic)) { … … 47 47 'site_topic' => get_option('contai_site_theme', ''), 48 48 'site_language' => get_option('contai_site_language', 'english'), 49 'wordpress_theme' => get_option('contai_wordpress_theme', ' blogfull'),49 'wordpress_theme' => get_option('contai_wordpress_theme', 'astra'), 50 50 ]; 51 51 } -
1platform-content-ai/trunk/includes/services/setup/WebsiteGenerationService.php
r3483422 r3488242 4 4 5 5 require_once __DIR__ . '/../../helpers/site-generation.php'; 6 require_once __DIR__ . '/../../providers/WebsiteProvider.php'; 6 7 require_once __DIR__ . '/../legal/LegalPagesGenerator.php'; 7 8 … … 17 18 18 19 try { 19 $theme = get_option('contai_wordpress_theme', ' blogfull');20 $theme = get_option('contai_wordpress_theme', 'astra'); 20 21 21 22 contai_install_theme($theme); 22 $results['steps'][] = 'Theme installed'; 23 contai_apply_theme_defaults($theme); 24 $results['steps'][] = 'Theme installed and configured'; 25 26 try { 27 $website_provider = new ContaiWebsiteProvider(); 28 $website_provider->updateWebsite( array( 'theme' => sanitize_text_field( $theme ) ) ); 29 $results['steps'][] = 'Theme tracked in API'; 30 } catch ( Exception $e ) { 31 $results['errors'][] = 'Theme tracking failed (non-critical): ' . $e->getMessage(); 32 } 23 33 24 34 contai_setup_site_config(); -
1platform-content-ai/trunk/readme.txt
r3487968 r3488242 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 2. 5.07 Stable tag: 2.7.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html
Note: See TracChangeset
for help on using the changeset viewer.