Changeset 3349746
- Timestamp:
- 08/25/2025 01:54:52 PM (7 months ago)
- Location:
- ansera-search
- Files:
-
- 3 edited
- 127 copied
-
tags/1.1.4 (copied) (copied from ansera-search/trunk)
-
tags/1.1.4/ansera_search.php (copied) (copied from ansera-search/trunk/ansera_search.php) (40 diffs)
-
tags/1.1.4/css (copied) (copied from ansera-search/trunk/css)
-
tags/1.1.4/css/ansera_search_admin_dashboard.css (copied) (copied from ansera-search/trunk/css/ansera_search_admin_dashboard.css)
-
tags/1.1.4/css/ansera_search_admin_settings.css (copied) (copied from ansera-search/trunk/css/ansera_search_admin_settings.css)
-
tags/1.1.4/css/ansera_search_chat.css (copied) (copied from ansera-search/trunk/css/ansera_search_chat.css)
-
tags/1.1.4/embed.js (copied) (copied from ansera-search/trunk/embed.js)
-
tags/1.1.4/images (copied) (copied from ansera-search/trunk/images)
-
tags/1.1.4/includes (copied) (copied from ansera-search/trunk/includes)
-
tags/1.1.4/includes/action-scheduler/README.md (copied) (copied from ansera-search/trunk/includes/action-scheduler/README.md)
-
tags/1.1.4/includes/action-scheduler/action-scheduler.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/action-scheduler.php)
-
tags/1.1.4/includes/action-scheduler/changelog.txt (copied) (copied from ansera-search/trunk/includes/action-scheduler/changelog.txt)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_ActionClaim.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_ActionClaim.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_ActionFactory.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_ActionFactory.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_AdminView.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_AdminView.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_Compatibility.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_Compatibility.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_DataController.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_DataController.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_DateTime.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_DateTime.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_Exception.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_Exception.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_FatalErrorMonitor.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_FatalErrorMonitor.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_InvalidActionException.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_InvalidActionException.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_ListTable.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_ListTable.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_LogEntry.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_LogEntry.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_NullLogEntry.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_NullLogEntry.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_OptionLock.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_OptionLock.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_QueueCleaner.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_QueueCleaner.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_QueueRunner.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_QueueRunner.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_SystemInformation.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_SystemInformation.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_Versions.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_Versions.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php)
-
tags/1.1.4/includes/action-scheduler/classes/ActionScheduler_wcSystemStatus.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/ActionScheduler_wcSystemStatus.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Action/Cancel_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Action/Cancel_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Action/Create_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Action/Create_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Action/Delete_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Action/Delete_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Action/Generate_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Action/Generate_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Action/Get_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Action/Get_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Action/List_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Action/List_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Action/Next_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Action/Next_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Action/Run_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Action/Run_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Clean_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Clean_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Action_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Action_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/Migration_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/Migration_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/ProgressBar.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/ProgressBar.php)
-
tags/1.1.4/includes/action-scheduler/classes/WP_CLI/System_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/WP_CLI/System_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_Lock.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_Lock.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_Logger.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_Logger.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_Store.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_Store.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php)
-
tags/1.1.4/includes/action-scheduler/classes/abstracts/ActionScheduler_WPCLI_Command.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/abstracts/ActionScheduler_WPCLI_Command.php)
-
tags/1.1.4/includes/action-scheduler/classes/actions/ActionScheduler_Action.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/actions/ActionScheduler_Action.php)
-
tags/1.1.4/includes/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php)
-
tags/1.1.4/includes/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php)
-
tags/1.1.4/includes/action-scheduler/classes/actions/ActionScheduler_NullAction.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/actions/ActionScheduler_NullAction.php)
-
tags/1.1.4/includes/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php)
-
tags/1.1.4/includes/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php)
-
tags/1.1.4/includes/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php)
-
tags/1.1.4/includes/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php)
-
tags/1.1.4/includes/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php)
-
tags/1.1.4/includes/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php)
-
tags/1.1.4/includes/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php)
-
tags/1.1.4/includes/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/ActionMigrator.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/ActionMigrator.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/BatchFetcher.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/BatchFetcher.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/Config.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/Config.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/Controller.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/Controller.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/DryRun_ActionMigrator.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/DryRun_ActionMigrator.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/DryRun_LogMigrator.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/DryRun_LogMigrator.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/LogMigrator.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/LogMigrator.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/Runner.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/Runner.php)
-
tags/1.1.4/includes/action-scheduler/classes/migration/Scheduler.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/migration/Scheduler.php)
-
tags/1.1.4/includes/action-scheduler/classes/schedules/ActionScheduler_CanceledSchedule.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/schedules/ActionScheduler_CanceledSchedule.php)
-
tags/1.1.4/includes/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php)
-
tags/1.1.4/includes/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php)
-
tags/1.1.4/includes/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php)
-
tags/1.1.4/includes/action-scheduler/classes/schedules/ActionScheduler_Schedule.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/schedules/ActionScheduler_Schedule.php)
-
tags/1.1.4/includes/action-scheduler/classes/schedules/ActionScheduler_SimpleSchedule.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/schedules/ActionScheduler_SimpleSchedule.php)
-
tags/1.1.4/includes/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php)
-
tags/1.1.4/includes/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php)
-
tags/1.1.4/includes/action-scheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php)
-
tags/1.1.4/includes/action-scheduler/deprecated/ActionScheduler_AdminView_Deprecated.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/deprecated/ActionScheduler_AdminView_Deprecated.php)
-
tags/1.1.4/includes/action-scheduler/deprecated/ActionScheduler_Schedule_Deprecated.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/deprecated/ActionScheduler_Schedule_Deprecated.php)
-
tags/1.1.4/includes/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php)
-
tags/1.1.4/includes/action-scheduler/deprecated/functions.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/deprecated/functions.php)
-
tags/1.1.4/includes/action-scheduler/functions.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/functions.php)
-
tags/1.1.4/includes/action-scheduler/lib/WP_Async_Request.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/WP_Async_Request.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression_AbstractField.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression_AbstractField.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression_DayOfMonthField.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression_DayOfMonthField.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression_DayOfWeekField.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression_DayOfWeekField.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression_FieldFactory.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression_FieldFactory.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression_FieldInterface.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression_FieldInterface.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression_HoursField.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression_HoursField.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression_MinutesField.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression_MinutesField.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression_MonthField.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression_MonthField.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/CronExpression_YearField.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/CronExpression_YearField.php)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/LICENSE (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/LICENSE)
-
tags/1.1.4/includes/action-scheduler/lib/cron-expression/README.md (copied) (copied from ansera-search/trunk/includes/action-scheduler/lib/cron-expression/README.md)
-
tags/1.1.4/includes/action-scheduler/license.txt (copied) (copied from ansera-search/trunk/includes/action-scheduler/license.txt)
-
tags/1.1.4/includes/action-scheduler/readme.txt (copied) (copied from ansera-search/trunk/includes/action-scheduler/readme.txt)
-
tags/1.1.4/includes/action-scheduler/vendor/autoload.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/autoload.php)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/ClassLoader.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/ClassLoader.php)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/InstalledVersions.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/InstalledVersions.php)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/LICENSE (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/LICENSE)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/autoload_classmap.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/autoload_classmap.php)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/autoload_namespaces.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/autoload_namespaces.php)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/autoload_psr4.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/autoload_psr4.php)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/autoload_real.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/autoload_real.php)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/autoload_static.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/autoload_static.php)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/installed.json (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/installed.json)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/installed.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/installed.php)
-
tags/1.1.4/includes/action-scheduler/vendor/composer/platform_check.php (copied) (copied from ansera-search/trunk/includes/action-scheduler/vendor/composer/platform_check.php)
-
tags/1.1.4/js (copied) (copied from ansera-search/trunk/js)
-
tags/1.1.4/js/ansera_search_admin.js (copied) (copied from ansera-search/trunk/js/ansera_search_admin.js)
-
tags/1.1.4/js/ansera_search_admin_dashboard.js (copied) (copied from ansera-search/trunk/js/ansera_search_admin_dashboard.js)
-
tags/1.1.4/js/ansera_search_admin_settings.js (copied) (copied from ansera-search/trunk/js/ansera_search_admin_settings.js) (1 diff)
-
tags/1.1.4/js/ansera_search_menu.js (copied) (copied from ansera-search/trunk/js/ansera_search_menu.js)
-
tags/1.1.4/readme.txt (copied) (copied from ansera-search/trunk/readme.txt) (4 diffs)
-
trunk/ansera_search.php (modified) (40 diffs)
-
trunk/js/ansera_search_admin_settings.js (modified) (1 diff)
-
trunk/readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
ansera-search/tags/1.1.4/ansera_search.php
r3337395 r3349746 3 3 * Plugin Name: Ansera Search 4 4 * Description: Ansera AI-powered search plugin provides answers based on your existing Wordpress content. 5 * Version: 1.1. 35 * Version: 1.1.4 6 6 * Author: Ansera.AI 7 7 * Author URI: https://www.ansera.ai/ … … 162 162 163 163 function ansera_search_send_page_data_to_ansera_on_publish($post_ID, $post = null) { 164 //error_log("*************************** ansera_search_send_page_data_to_ansera_on_publish: " . $post_ID);165 164 $sync_status = ansera_check_post_sync_status($post_ID); 166 165 if($sync_status) { 167 //error_log("***************************if ansera_search_send_page_data_to_ansera_on_publish: " . $post_ID);168 166 global $wpdb; 169 167 // Update the sync status to 'modified' … … 184 182 } 185 183 } 186 else{187 //error_log("***************************else ansera_search_send_page_data_to_ansera_on_publish: " . $post_ID);188 }189 184 } 190 185 191 186 function ansera_search_send_media_data_to_ansera_on_update($post_ID, $post = null) { 192 //error_log("*************************** ansera_search_send_media_data_to_ansera_on_update: " . $post_ID);193 187 $sync_status = ansera_check_post_sync_status($post_ID); 194 188 if($sync_status) { 195 //error_log("***************************if ansera_search_send_media_data_to_ansera_on_update: " . $post_ID);196 189 ansera_update_media_sync_status($post_ID);//modified 197 190 … … 200 193 do_action('ansera_search_sync_batch_event'); 201 194 } 202 }203 else{204 //error_log("***************************else ansera_search_send_media_data_to_ansera_on_update: " . $post_ID);205 195 } 206 196 } … … 496 486 $removed_ids_array = $data['removed_ids_array']; 497 487 498 //error_log("*************************** removed_ids_array: " . print_r($removed_ids_array, true));499 //error_log("*************************** newly_selected_ids_array: " . print_r($newly_selected_ids_array, true));500 //error_log("*************************** modified_ids_array: " . print_r($modified_ids_array, true));501 488 global $wpdb; 502 489 … … 524 511 } 525 512 526 // Only trigger sync if not already in progress527 //error_log("*************************** before ansera_search_sync_batch_event");528 513 if(!get_transient('ansera_search_syn_in_progress')){ 529 514 wp_schedule_single_event(time() + 5, 'ansera_search_sync_batch_event'); 530 515 } 531 else{532 //error_log("*************************** ansera_search_syn_in_progress is already set");533 }534 //error_log("*************************** after ansera_search_sync_batch_event");535 516 536 517 wp_send_json_success([ … … 563 544 $video_title = esc_html($video_title); 564 545 565 //error_log("video_link: " . $video_link);566 //error_log("video_title: " . $video_title);567 568 569 546 global $wpdb; 570 547 $table_name = $wpdb->prefix . 'ansera_search_video_links'; 571 548 572 //error_log("video_link: " . $video_link); 573 //error_log("video_title: " . $video_title); 574 575 576 // Insert video link into database 577 $result = $wpdb->insert( 578 $table_name, 579 array( 580 'video_url' => $video_link, 581 'video_title' => $video_title, 582 'sync_status' => 'new' 583 ), 584 array('%s', '%s', '%s') 585 ); 549 $result = $wpdb->insert( 550 $table_name, 551 array( 552 'video_url' => $video_link, 553 'video_title' => $video_title, 554 'sync_status' => 'new' 555 ), 556 array('%s', '%s', '%s') 557 ); 586 558 587 559 if ($result === false) { … … 709 681 // Check if video sync is already in progress 710 682 if (get_transient('ansera_video_sync_in_progress')) { 711 // error_log("Video sync already in progress, skipping new sync request");683 // Video sync already in progress, skipping new sync request 712 684 return; 713 685 } … … 728 700 } 729 701 730 //error_log("Video sync batch scheduled for processing");731 702 } 732 703 … … 734 705 global $wpdb; 735 706 $table_name = $wpdb->prefix . 'ansera_search_video_links'; 736 737 707 try { 738 708 // Get up to 10 videos with 'new' or 'error' status, ordered by ID … … 747 717 748 718 if (empty($new_videos)) { 749 // error_log("No more videos with 'new' status found for sync");719 // No more videos with 'new' status found for sync; 750 720 // Clear the transient since we're done 751 721 delete_transient('ansera_video_sync_in_progress'); 752 722 return; 753 723 } 754 755 //error_log("Processing batch of " . count($new_videos) . " videos");756 724 757 725 $processed_count = 0; … … 770 738 ); 771 739 740 //$media_type = (false == strpos($video['video_url'], 'youtube')) ? "document" : "video"; 741 $media_type = "document"; 772 742 $page_id = 'vid_' . $video_id; 743 773 744 $video_data = [ 774 745 'media_data' => '', 775 746 'url' => $video['video_url'], 776 747 'page_title' => $video['video_title'], 777 'page_id' => $page_id, 778 'page_type' => 'video' 748 'page_id' => $page_id 779 749 ]; 780 750 … … 783 753 // Fire-and-forget approach - don't wait for response 784 754 // Use a very short timeout (2 seconds) just to ensure the request is sent 785 $response = wp_remote_request( esc_url(get_option("ansera_search_host_url") . '/api/media-content'), array(755 $response = wp_remote_request(esc_url(get_option("ansera_search_host_url") . '/api/media-content'), array( 786 756 'method' => 'POST', 787 757 'headers' => $headers, 788 758 'body' => wp_json_encode( $video_data ), 789 'timeout' => 2, // Very short timeout - just to send the request790 'blocking' => false , // Non-blocking request759 'timeout' => 2, 760 'blocking' => false 791 761 ) ); 792 793 762 // Since we're using fire-and-forget, we assume the request was sent successfully 794 763 // The backend will process the video asynchronously … … 801 770 802 771 } catch (Exception $e) { 803 //error_log("Error processing video $video_id: " . $e->getMessage());804 772 // Mark this video as error and continue with next video 805 773 $wpdb->update( … … 814 782 } 815 783 816 //error_log("Batch completed: $processed_count videos sent to backend for processing");817 784 818 785 // Check if there are more videos to process (including error videos for retry) 819 786 $remaining_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name WHERE sync_status IN ('new', 'error')"); 820 //error_log("*************************** inside ansera_search_sync_video_batch");821 //error_log("remaining_count: $remaining_count");822 787 if ($remaining_count > 0) { 823 //error_log("$remaining_count videos remaining, scheduling next batch");824 788 // Schedule next batch with a 5-second delay 825 789 if (class_exists('ActionScheduler')) { … … 833 797 } 834 798 } else { 835 //error_log("All videos sent for processing, clearing sync progress");836 799 // Clear the transient since we're done sending videos 837 800 delete_transient('ansera_video_sync_in_progress'); … … 839 802 840 803 } catch (Exception $e) { 841 //error_log("Critical error in video sync batch: " . $e->getMessage());842 804 // Clear the transient to prevent sync from being stuck 843 805 delete_transient('ansera_video_sync_in_progress'); … … 1140 1102 <div style="color: #000; background: none; font-family: inherit; line-height: 1.6; font-size: inherit;"> 1141 1103 <p style="margin-top:10px;"> 1142 Sync your external audios and videos with Ansera.1104 Sync your external documents, audios and videos with Ansera. 1143 1105 </p> 1144 1106 <ul> 1107 <li> Documents Supported Formats: <b>(doc,docx,pdf,ppt,pptx,xls,xlsx) </b></li> 1145 1108 <li> Audio Supported Formats: <b>(mp3,m4a,ogg,wav,wma) </b></li> 1146 1109 <li> Video Supported Formats: <b>(mp4,m4v,webm,wmv,ogv) </b></li> … … 2574 2537 $current_timeout = $base_timeout * pow(2, $attempt - 1); // Exponential backoff: 30s, 60s, 120s 2575 2538 2576 //error_log("Ansera sync attempt $attempt for post $post_id with timeout {$current_timeout}s");2577 2578 2539 $response = wp_remote_post($url, array( 2579 2540 'body' => wp_json_encode($json), … … 2582 2543 )); 2583 2544 2584 //error_log("************************start*************************");2585 //error_log("Request: " . $post_id);2586 //error_log("url: " . wp_json_encode($json));2587 //error_log("*************************************************");2588 ////error_log("Response: " . print_r($response['body'], true));2589 //error_log("************************end*************************");2590 2591 2545 if (is_wp_error($response)) { 2592 2546 // Safely get error message with fallback … … 2600 2554 // Check if it's a timeout error 2601 2555 if (strpos($error_message, 'timeout') !== false || strpos($error_message, 'cURL error 28') !== false) { 2602 //error_log("Timeout on attempt $attempt for post $post_id: $error_message");2603 2604 2556 if ($attempt < $max_retries) { 2605 2557 // Wait before retry (exponential backoff) 2606 2558 $wait_time = min(30, pow(2, $attempt)); // Cap at 30 seconds 2607 //error_log("Waiting {$wait_time}s before retry for post $post_id");2608 2559 sleep($wait_time); 2609 2560 continue; … … 2629 2580 if ($status_code == 200) { 2630 2581 update_option(ANSERA_SEARCH_SYNC_COUNT, 1); 2631 //error_log("Successfully synced post $post_id on attempt $attempt");2632 2582 return true; 2633 2583 } else { … … 2644 2594 2645 2595 } catch (Exception $e) { 2646 //error_log("Exception in ansera_search_send_synchronous_request for post $post_id: " . $e->getMessage());2647 2596 ansera_search_mark_post_as_synced_with_status($post_id, 'error', "Exception: " . $e->getMessage()); 2648 2597 return false; … … 2652 2601 function ansera_search_send_post_to_rag($post) 2653 2602 { 2654 //error_log("*************************** inside ansera_search_send_post_to_rag");2655 2603 if (empty($post->page_title)) { 2656 2604 ansera_search_mark_post_as_synced_with_status($post->ID, 'error',"Post ID: " . $post->ID . " is missing data(title or web_data). Skipping..."); … … 2689 2637 function ansera_search_send_media_file_to_rag($post) 2690 2638 { 2691 //error_log("*************************** inside ansera_search_send_media_file_to_rag");2692 2639 try { 2693 2640 $post_id = $post->ID; … … 2750 2697 } 2751 2698 catch(Exception $e){ 2752 //error_log("*************************** inside ansera_search_send_media_file_to_rag exception");2699 2753 2700 } 2754 2701 return true; … … 2757 2704 function ansera_search_sync_data_with_rag() 2758 2705 { 2759 //error_log("*************************** inside ansera_search_sync_data_with_rag");2760 2706 // Check if sync is already in progress to prevent overlap 2761 2707 if (get_transient('ansera_search_syn_in_progress')) { … … 2763 2709 $lock_time = get_transient('ansera_search_syn_in_progress_time'); 2764 2710 if ($lock_time && (time() - $lock_time) > 900) { // 15 minutes 2765 //error_log("Ansera search sync lock is stale, clearing it");2766 2711 delete_transient('ansera_search_syn_in_progress'); 2767 2712 delete_transient('ansera_search_syn_in_progress_time'); 2768 2713 } else { 2769 // error_log("Ansera search sync already in progress, skipping this execution");2714 // Ansera search sync already in progress, skipping this execution 2770 2715 return; 2771 2716 } … … 2794 2739 if($post->post_type == 'attachment') 2795 2740 { 2796 //error_log("*************************** inside ansera_search_send_media_file_to_rag");2797 2741 ansera_search_send_media_file_to_rag($post); 2798 2742 } 2799 2743 else 2800 2744 { 2801 //error_log("*************************** inside ansera_search_send_post_to_rag");2802 2745 ansera_search_send_post_to_rag($post); 2803 2746 } … … 2823 2766 catch(Exception $e){ 2824 2767 ansera_search_mark_post_as_synced_with_status($row->post_id, 'error', "Post-level error: " . $e->getMessage()); 2825 //error_log("Ansera search sync error: " . $e->getMessage());2826 2768 continue; // move to next post 2827 2769 } … … 2855 2797 delete_transient('ansera_search_syn_in_progress'); 2856 2798 delete_transient('ansera_search_syn_in_progress_time'); 2857 //error_log("Ansera search sync error: " . $e->getMessage());2858 2799 } 2859 2800 } else { … … 2925 2866 // Prepare video data for API 2926 2867 $page_id = 'vid_' . $video_id; 2868 // $media_type = (false == strpos($video->video_url, 'youtube')) ? "document" : "video"; 2869 $media_type = "document"; 2927 2870 $video_data = [ 2928 2871 'media_data' => '', … … 3096 3039 delete_transient('ansera_search_syn_in_progress'); 3097 3040 delete_transient('ansera_search_syn_in_progress_time'); 3098 //error_log("Ansera search sync lock cleared manually");3099 3041 } 3100 3042 … … 3147 3089 3148 3090 if ($recent_failures && $recent_failures >= $max_failures) { 3149 //error_log("Circuit breaker open for $url - too many recent failures");3150 3091 ansera_search_mark_post_as_synced_with_status($post_id, 'new', "Circuit breaker open - will retry later"); 3151 3092 return false; … … 3158 3099 $max_timeout = 120; // Cap at 2 minutes 3159 3100 $timeout = min($adaptive_timeout, $max_timeout); 3160 3161 //error_log("Ansera sync for post $post_id with adaptive timeout {$timeout}s (content size: " . round($content_size/1024, 2) . "KB)");3162 3101 3163 3102 $response = wp_remote_post($url, array( … … 3183 3122 // Handle different types of errors 3184 3123 if (strpos($error_message, 'timeout') !== false || strpos($error_message, 'cURL error 28') !== false) { 3185 //error_log("Timeout error for post $post_id: $error_message");3186 3124 ansera_search_mark_post_as_synced_with_status($post_id, 'new', "Timeout - will retry with longer timeout"); 3187 3125 } elseif (strpos($error_message, 'connection') !== false || strpos($error_message, 'cURL error 7') !== false) { 3188 //error_log("Connection error for post $post_id: $error_message");3189 3126 ansera_search_mark_post_as_synced_with_status($post_id, 'new', "Connection error - will retry"); 3190 3127 } else { 3191 //error_log("Other error for post $post_id: $error_message");3192 3128 ansera_search_mark_post_as_synced_with_status($post_id, 'error', $error_message); 3193 3129 } … … 3203 3139 if ($status_code == 200) { 3204 3140 update_option(ANSERA_SEARCH_SYNC_COUNT, 1); 3205 //error_log("Successfully synced post $post_id");3206 3141 return true; 3207 3142 } else { … … 3217 3152 3218 3153 } catch (Exception $e) { 3219 //error_log("Exception in ansera_search_send_synchronous_request_advanced for post $post_id: " . $e->getMessage());3220 3154 ansera_search_mark_post_as_synced_with_status($post_id, 'error', "Exception: " . $e->getMessage()); 3221 3155 return false; … … 3352 3286 $sync_data_posts = $data['result']['posts'] ?? []; 3353 3287 $sync_data_pdfs = $data['result']['media']['pdfs'] ?? []; 3354 $sync_data_videos = $data['result']['media'][' videos'] ?? [];3288 $sync_data_videos = $data['result']['media']['documents'] ?? []; 3355 3289 3356 3290 … … 3436 3370 3437 3371 foreach ($media_data_array as $media_data) { 3438 $media_id_string = explode('_', $media_data['video_id'])[1]; 3372 $post_id_arr = explode('_', $media_data['post_id']); 3373 $media_id_string = isset($post_id_arr[1]) ? $post_id_arr[1] : ''; 3439 3374 $backend_status = sanitize_text_field($media_data['status'] ?? ''); 3440 3375 $last_synced = sanitize_text_field($media_data['last_synced'] ?? current_time('mysql')); -
ansera-search/tags/1.1.4/js/ansera_search_admin_settings.js
r3337395 r3349746 897 897 url = url.trim(); 898 898 // Accept all YouTube links (with or without protocol/www) 899 const youtubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+/i; 899 // const youtubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+/i; 900 const pattern = new RegExp( 901 '^(https?:\\/\\/)?' + // protocol 902 '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name 903 '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR IP (v4) address 904 '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path 905 '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string 906 '(\\#[-a-z\\d_]*)?$','i' // fragment locator 907 ); 900 908 // Accept direct video/audio file links (any domain, must end with extension) 901 const extRegex = /\.((mp3|m4a|ogg|wav|wma|mp4|m4v|webm|wmv|ogv )(\?.*)?)$/i;902 return youtubeRegex.test(url) || extRegex.test(url);909 const extRegex = /\.((mp3|m4a|ogg|wav|wma|mp4|m4v|webm|wmv|ogv|doc|docx|pdf|ppt|pptx|xls|xlsx|)(\?.*)?)$/i; 910 return pattern.test(url) || extRegex.test(url); 903 911 } -
ansera-search/tags/1.1.4/readme.txt
r3337395 r3349746 1 1 === Ansera Search === 2 2 Contributors: Ansera01 3 Tags: search, chatbot, openAI, AI search, chatgpt3 Tags: ai search, chatbot, search, lead gen, relevance 4 4 Requires at least: 5.0 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.2 7 Stable tag: 1.1. 37 Stable tag: 1.1.4 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 12 12 13 13 == Description == 14 Ansera Search replaces the default WordPress search with a powerful Generative AI (GenAI)-driven experience.14 Ansera Search replaces the default WordPress search with an intuitive AI powered answer engine based on your site's existing content. 15 15 16 Ansera is based off of your site's content so it will only provide responses based off of what you wish to train it on. Ansera solves the issue of visitors leaving in frustration when they can't find answers on your site. Ansera analytics let you see what your users are searching for to help you improve your content and conversion rates. Built on top of OpenAI, it understands your visitors' queries and delivers meaningful, summarized answers—far beyond keyword matches. 16 We all know that when website visitors can't find the answers they're looking for, they will leave in frustration never to return. Traditional website search just returns a list of links for visitors to sort through themselves while most chatbot solutions are annoying and require significant set up. 17 18 Ansera solves for these issues and more by providing your website visitors with human readable natural language search responses based only on your site's content. 19 20 Unlike traditional website search tools, Ansera can be up and running in as little as 5 minutes by even the least technical users. Once you install Ansera on your site, all you have to do is select the pages you want to train it to answer on. Additionally, you can link to externally stored content like youtube and vimeo videos or presentations. 21 22 Ansera's analytics let you see what answers your users are actually seeking and how to improve your content and conversion to better serve them. 17 23 18 24 **Features:** 19 - Human-readable natural language search results 20 - AI responses are automatically trained off of your site's content 21 - Replaces default search seamlessly 22 - Real-time sync with your content 23 - Customize and edit AI answers 24 - Floating search box or menu icon option 25 - Built using OpenAI’s advanced language models 26 - Visitors can email results to themselves 25 - Out of the box set up while also providing several visual customization options for more advanced users 26 - Human readable natural language search results 27 - Real-time sync that updates answers as site content is updated 28 - User analytics for all search queries 29 - Customizable guiding questions 30 - Visitors can email results to themselves 31 - Integrate a custom lead generation form into the Ansera widget 27 32 28 Bring conversational AI search to your site in minutes —no code required.33 Bring conversational AI search to your site in minutes - no coding required! 29 34 30 35 == Installation == … … 36 41 == Frequently Asked Questions == 37 42 38 = How does the plugin work? =39 The plugin syncs your site content with Ansera's GenAI backend. Users get contextual, summarized results powered by AI.43 = What is Ansera? = 44 Ansera is an AI-powered tool that transforms WordPress websites into intelligent, conversational platforms. Leveraging the content already on your site, Ansera delivers contextual, summarized answers to visitors that make for a more intuitive and engaging user experience than traditional search or chatbots. 40 45 41 = Can I customize the AI responses? = 42 Yes! We provide you with the option to edit any previously provided answers and ensure new users will receive an updated response. 46 = Is Ansera a replacement for Search? = 47 Yes, Ansera is an enhanced replacement for search functionality on your wordpress site. Unlike traditional search, however, Ansera doesn’t just return a list of links for visitors to sort through. 48 It provides a natural language response interface for visitors to ask questions and get complete conversational responses 43 49 44 = Where does the AI model run? = 45 Search queries are securely processed via the Ansera backend which is built on OpenAI. 50 = Can Ansera replace my chatbot? = 51 Ansera can be used in addition to or instead of a chatbot. You can configure Ansera to visually appear like a chatbot icon on the page as well as select up to 5 default questions to guide visitors. 52 53 = What data does Ansera sync with automatically? = 54 Ansera syncs with any pages from your website that you select. You can select or unselect a page at any time; Ansera will update responses accordingly. 55 56 = What other type of files can Ansera sync with? = 57 In addition to your website content, you can link to externally stored content such as YouTube/Vimeo videos, podcasts, pdfs, and presentations 58 59 = Can I customize the look of Ansera? = 60 Yes! You can customize almost everything about Ansera from how the widget is displayed to the default questions customers can ask to how Ansera responds to questions that are out of scope. Ansera’s color scheme will match your Wordpress site theme so you can use it out of the box if you would like. 61 62 = Is my information being used to train an LLM? = 63 Your information remains local and will not be used to train an LLM or outside resource. 64 65 = How do you prevent bot traffic? = 66 Ansera integrates with Google reCAPTCHA v3 for invisible spam protection that doesn't interfere with genuine visitor conversations. 67 68 = What happens when Ansera can’t answer a question? = 69 A customizable message will be shown to the user stating that the question could not be answered. Additionally, you’ll be able to see which questions were not answered. This allows you to either guide your content strategy or train Ansera to train similar questions in the future. 70 71 = Can I edit the answers Ansera generates? = 72 You can edit answers in the Ansera dashboard. Ansera will learn from the edited responses to answer similar future questions. 73 74 = What metrics can I see in the Ansera dashboard? = 75 The Ansera dashboard lets you see information such as how many visitors and queries were generated during a certain time period. Additionally, you can see all queries and how users rated the answers they received. 46 76 47 77 … … 63 93 64 94 == Changelog == 95 = 1.1.4 = 96 * Added support for external documents syncing (Google Drive or Direct File URLs) 97 * Introduced custom color theme and you can customize the widget UI. 98 * Updated FAQ 65 99 66 100 = 1.1.0 = -
ansera-search/trunk/ansera_search.php
r3337395 r3349746 3 3 * Plugin Name: Ansera Search 4 4 * Description: Ansera AI-powered search plugin provides answers based on your existing Wordpress content. 5 * Version: 1.1. 35 * Version: 1.1.4 6 6 * Author: Ansera.AI 7 7 * Author URI: https://www.ansera.ai/ … … 162 162 163 163 function ansera_search_send_page_data_to_ansera_on_publish($post_ID, $post = null) { 164 //error_log("*************************** ansera_search_send_page_data_to_ansera_on_publish: " . $post_ID);165 164 $sync_status = ansera_check_post_sync_status($post_ID); 166 165 if($sync_status) { 167 //error_log("***************************if ansera_search_send_page_data_to_ansera_on_publish: " . $post_ID);168 166 global $wpdb; 169 167 // Update the sync status to 'modified' … … 184 182 } 185 183 } 186 else{187 //error_log("***************************else ansera_search_send_page_data_to_ansera_on_publish: " . $post_ID);188 }189 184 } 190 185 191 186 function ansera_search_send_media_data_to_ansera_on_update($post_ID, $post = null) { 192 //error_log("*************************** ansera_search_send_media_data_to_ansera_on_update: " . $post_ID);193 187 $sync_status = ansera_check_post_sync_status($post_ID); 194 188 if($sync_status) { 195 //error_log("***************************if ansera_search_send_media_data_to_ansera_on_update: " . $post_ID);196 189 ansera_update_media_sync_status($post_ID);//modified 197 190 … … 200 193 do_action('ansera_search_sync_batch_event'); 201 194 } 202 }203 else{204 //error_log("***************************else ansera_search_send_media_data_to_ansera_on_update: " . $post_ID);205 195 } 206 196 } … … 496 486 $removed_ids_array = $data['removed_ids_array']; 497 487 498 //error_log("*************************** removed_ids_array: " . print_r($removed_ids_array, true));499 //error_log("*************************** newly_selected_ids_array: " . print_r($newly_selected_ids_array, true));500 //error_log("*************************** modified_ids_array: " . print_r($modified_ids_array, true));501 488 global $wpdb; 502 489 … … 524 511 } 525 512 526 // Only trigger sync if not already in progress527 //error_log("*************************** before ansera_search_sync_batch_event");528 513 if(!get_transient('ansera_search_syn_in_progress')){ 529 514 wp_schedule_single_event(time() + 5, 'ansera_search_sync_batch_event'); 530 515 } 531 else{532 //error_log("*************************** ansera_search_syn_in_progress is already set");533 }534 //error_log("*************************** after ansera_search_sync_batch_event");535 516 536 517 wp_send_json_success([ … … 563 544 $video_title = esc_html($video_title); 564 545 565 //error_log("video_link: " . $video_link);566 //error_log("video_title: " . $video_title);567 568 569 546 global $wpdb; 570 547 $table_name = $wpdb->prefix . 'ansera_search_video_links'; 571 548 572 //error_log("video_link: " . $video_link); 573 //error_log("video_title: " . $video_title); 574 575 576 // Insert video link into database 577 $result = $wpdb->insert( 578 $table_name, 579 array( 580 'video_url' => $video_link, 581 'video_title' => $video_title, 582 'sync_status' => 'new' 583 ), 584 array('%s', '%s', '%s') 585 ); 549 $result = $wpdb->insert( 550 $table_name, 551 array( 552 'video_url' => $video_link, 553 'video_title' => $video_title, 554 'sync_status' => 'new' 555 ), 556 array('%s', '%s', '%s') 557 ); 586 558 587 559 if ($result === false) { … … 709 681 // Check if video sync is already in progress 710 682 if (get_transient('ansera_video_sync_in_progress')) { 711 // error_log("Video sync already in progress, skipping new sync request");683 // Video sync already in progress, skipping new sync request 712 684 return; 713 685 } … … 728 700 } 729 701 730 //error_log("Video sync batch scheduled for processing");731 702 } 732 703 … … 734 705 global $wpdb; 735 706 $table_name = $wpdb->prefix . 'ansera_search_video_links'; 736 737 707 try { 738 708 // Get up to 10 videos with 'new' or 'error' status, ordered by ID … … 747 717 748 718 if (empty($new_videos)) { 749 // error_log("No more videos with 'new' status found for sync");719 // No more videos with 'new' status found for sync; 750 720 // Clear the transient since we're done 751 721 delete_transient('ansera_video_sync_in_progress'); 752 722 return; 753 723 } 754 755 //error_log("Processing batch of " . count($new_videos) . " videos");756 724 757 725 $processed_count = 0; … … 770 738 ); 771 739 740 //$media_type = (false == strpos($video['video_url'], 'youtube')) ? "document" : "video"; 741 $media_type = "document"; 772 742 $page_id = 'vid_' . $video_id; 743 773 744 $video_data = [ 774 745 'media_data' => '', 775 746 'url' => $video['video_url'], 776 747 'page_title' => $video['video_title'], 777 'page_id' => $page_id, 778 'page_type' => 'video' 748 'page_id' => $page_id 779 749 ]; 780 750 … … 783 753 // Fire-and-forget approach - don't wait for response 784 754 // Use a very short timeout (2 seconds) just to ensure the request is sent 785 $response = wp_remote_request( esc_url(get_option("ansera_search_host_url") . '/api/media-content'), array(755 $response = wp_remote_request(esc_url(get_option("ansera_search_host_url") . '/api/media-content'), array( 786 756 'method' => 'POST', 787 757 'headers' => $headers, 788 758 'body' => wp_json_encode( $video_data ), 789 'timeout' => 2, // Very short timeout - just to send the request790 'blocking' => false , // Non-blocking request759 'timeout' => 2, 760 'blocking' => false 791 761 ) ); 792 793 762 // Since we're using fire-and-forget, we assume the request was sent successfully 794 763 // The backend will process the video asynchronously … … 801 770 802 771 } catch (Exception $e) { 803 //error_log("Error processing video $video_id: " . $e->getMessage());804 772 // Mark this video as error and continue with next video 805 773 $wpdb->update( … … 814 782 } 815 783 816 //error_log("Batch completed: $processed_count videos sent to backend for processing");817 784 818 785 // Check if there are more videos to process (including error videos for retry) 819 786 $remaining_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name WHERE sync_status IN ('new', 'error')"); 820 //error_log("*************************** inside ansera_search_sync_video_batch");821 //error_log("remaining_count: $remaining_count");822 787 if ($remaining_count > 0) { 823 //error_log("$remaining_count videos remaining, scheduling next batch");824 788 // Schedule next batch with a 5-second delay 825 789 if (class_exists('ActionScheduler')) { … … 833 797 } 834 798 } else { 835 //error_log("All videos sent for processing, clearing sync progress");836 799 // Clear the transient since we're done sending videos 837 800 delete_transient('ansera_video_sync_in_progress'); … … 839 802 840 803 } catch (Exception $e) { 841 //error_log("Critical error in video sync batch: " . $e->getMessage());842 804 // Clear the transient to prevent sync from being stuck 843 805 delete_transient('ansera_video_sync_in_progress'); … … 1140 1102 <div style="color: #000; background: none; font-family: inherit; line-height: 1.6; font-size: inherit;"> 1141 1103 <p style="margin-top:10px;"> 1142 Sync your external audios and videos with Ansera.1104 Sync your external documents, audios and videos with Ansera. 1143 1105 </p> 1144 1106 <ul> 1107 <li> Documents Supported Formats: <b>(doc,docx,pdf,ppt,pptx,xls,xlsx) </b></li> 1145 1108 <li> Audio Supported Formats: <b>(mp3,m4a,ogg,wav,wma) </b></li> 1146 1109 <li> Video Supported Formats: <b>(mp4,m4v,webm,wmv,ogv) </b></li> … … 2574 2537 $current_timeout = $base_timeout * pow(2, $attempt - 1); // Exponential backoff: 30s, 60s, 120s 2575 2538 2576 //error_log("Ansera sync attempt $attempt for post $post_id with timeout {$current_timeout}s");2577 2578 2539 $response = wp_remote_post($url, array( 2579 2540 'body' => wp_json_encode($json), … … 2582 2543 )); 2583 2544 2584 //error_log("************************start*************************");2585 //error_log("Request: " . $post_id);2586 //error_log("url: " . wp_json_encode($json));2587 //error_log("*************************************************");2588 ////error_log("Response: " . print_r($response['body'], true));2589 //error_log("************************end*************************");2590 2591 2545 if (is_wp_error($response)) { 2592 2546 // Safely get error message with fallback … … 2600 2554 // Check if it's a timeout error 2601 2555 if (strpos($error_message, 'timeout') !== false || strpos($error_message, 'cURL error 28') !== false) { 2602 //error_log("Timeout on attempt $attempt for post $post_id: $error_message");2603 2604 2556 if ($attempt < $max_retries) { 2605 2557 // Wait before retry (exponential backoff) 2606 2558 $wait_time = min(30, pow(2, $attempt)); // Cap at 30 seconds 2607 //error_log("Waiting {$wait_time}s before retry for post $post_id");2608 2559 sleep($wait_time); 2609 2560 continue; … … 2629 2580 if ($status_code == 200) { 2630 2581 update_option(ANSERA_SEARCH_SYNC_COUNT, 1); 2631 //error_log("Successfully synced post $post_id on attempt $attempt");2632 2582 return true; 2633 2583 } else { … … 2644 2594 2645 2595 } catch (Exception $e) { 2646 //error_log("Exception in ansera_search_send_synchronous_request for post $post_id: " . $e->getMessage());2647 2596 ansera_search_mark_post_as_synced_with_status($post_id, 'error', "Exception: " . $e->getMessage()); 2648 2597 return false; … … 2652 2601 function ansera_search_send_post_to_rag($post) 2653 2602 { 2654 //error_log("*************************** inside ansera_search_send_post_to_rag");2655 2603 if (empty($post->page_title)) { 2656 2604 ansera_search_mark_post_as_synced_with_status($post->ID, 'error',"Post ID: " . $post->ID . " is missing data(title or web_data). Skipping..."); … … 2689 2637 function ansera_search_send_media_file_to_rag($post) 2690 2638 { 2691 //error_log("*************************** inside ansera_search_send_media_file_to_rag");2692 2639 try { 2693 2640 $post_id = $post->ID; … … 2750 2697 } 2751 2698 catch(Exception $e){ 2752 //error_log("*************************** inside ansera_search_send_media_file_to_rag exception");2699 2753 2700 } 2754 2701 return true; … … 2757 2704 function ansera_search_sync_data_with_rag() 2758 2705 { 2759 //error_log("*************************** inside ansera_search_sync_data_with_rag");2760 2706 // Check if sync is already in progress to prevent overlap 2761 2707 if (get_transient('ansera_search_syn_in_progress')) { … … 2763 2709 $lock_time = get_transient('ansera_search_syn_in_progress_time'); 2764 2710 if ($lock_time && (time() - $lock_time) > 900) { // 15 minutes 2765 //error_log("Ansera search sync lock is stale, clearing it");2766 2711 delete_transient('ansera_search_syn_in_progress'); 2767 2712 delete_transient('ansera_search_syn_in_progress_time'); 2768 2713 } else { 2769 // error_log("Ansera search sync already in progress, skipping this execution");2714 // Ansera search sync already in progress, skipping this execution 2770 2715 return; 2771 2716 } … … 2794 2739 if($post->post_type == 'attachment') 2795 2740 { 2796 //error_log("*************************** inside ansera_search_send_media_file_to_rag");2797 2741 ansera_search_send_media_file_to_rag($post); 2798 2742 } 2799 2743 else 2800 2744 { 2801 //error_log("*************************** inside ansera_search_send_post_to_rag");2802 2745 ansera_search_send_post_to_rag($post); 2803 2746 } … … 2823 2766 catch(Exception $e){ 2824 2767 ansera_search_mark_post_as_synced_with_status($row->post_id, 'error', "Post-level error: " . $e->getMessage()); 2825 //error_log("Ansera search sync error: " . $e->getMessage());2826 2768 continue; // move to next post 2827 2769 } … … 2855 2797 delete_transient('ansera_search_syn_in_progress'); 2856 2798 delete_transient('ansera_search_syn_in_progress_time'); 2857 //error_log("Ansera search sync error: " . $e->getMessage());2858 2799 } 2859 2800 } else { … … 2925 2866 // Prepare video data for API 2926 2867 $page_id = 'vid_' . $video_id; 2868 // $media_type = (false == strpos($video->video_url, 'youtube')) ? "document" : "video"; 2869 $media_type = "document"; 2927 2870 $video_data = [ 2928 2871 'media_data' => '', … … 3096 3039 delete_transient('ansera_search_syn_in_progress'); 3097 3040 delete_transient('ansera_search_syn_in_progress_time'); 3098 //error_log("Ansera search sync lock cleared manually");3099 3041 } 3100 3042 … … 3147 3089 3148 3090 if ($recent_failures && $recent_failures >= $max_failures) { 3149 //error_log("Circuit breaker open for $url - too many recent failures");3150 3091 ansera_search_mark_post_as_synced_with_status($post_id, 'new', "Circuit breaker open - will retry later"); 3151 3092 return false; … … 3158 3099 $max_timeout = 120; // Cap at 2 minutes 3159 3100 $timeout = min($adaptive_timeout, $max_timeout); 3160 3161 //error_log("Ansera sync for post $post_id with adaptive timeout {$timeout}s (content size: " . round($content_size/1024, 2) . "KB)");3162 3101 3163 3102 $response = wp_remote_post($url, array( … … 3183 3122 // Handle different types of errors 3184 3123 if (strpos($error_message, 'timeout') !== false || strpos($error_message, 'cURL error 28') !== false) { 3185 //error_log("Timeout error for post $post_id: $error_message");3186 3124 ansera_search_mark_post_as_synced_with_status($post_id, 'new', "Timeout - will retry with longer timeout"); 3187 3125 } elseif (strpos($error_message, 'connection') !== false || strpos($error_message, 'cURL error 7') !== false) { 3188 //error_log("Connection error for post $post_id: $error_message");3189 3126 ansera_search_mark_post_as_synced_with_status($post_id, 'new', "Connection error - will retry"); 3190 3127 } else { 3191 //error_log("Other error for post $post_id: $error_message");3192 3128 ansera_search_mark_post_as_synced_with_status($post_id, 'error', $error_message); 3193 3129 } … … 3203 3139 if ($status_code == 200) { 3204 3140 update_option(ANSERA_SEARCH_SYNC_COUNT, 1); 3205 //error_log("Successfully synced post $post_id");3206 3141 return true; 3207 3142 } else { … … 3217 3152 3218 3153 } catch (Exception $e) { 3219 //error_log("Exception in ansera_search_send_synchronous_request_advanced for post $post_id: " . $e->getMessage());3220 3154 ansera_search_mark_post_as_synced_with_status($post_id, 'error', "Exception: " . $e->getMessage()); 3221 3155 return false; … … 3352 3286 $sync_data_posts = $data['result']['posts'] ?? []; 3353 3287 $sync_data_pdfs = $data['result']['media']['pdfs'] ?? []; 3354 $sync_data_videos = $data['result']['media'][' videos'] ?? [];3288 $sync_data_videos = $data['result']['media']['documents'] ?? []; 3355 3289 3356 3290 … … 3436 3370 3437 3371 foreach ($media_data_array as $media_data) { 3438 $media_id_string = explode('_', $media_data['video_id'])[1]; 3372 $post_id_arr = explode('_', $media_data['post_id']); 3373 $media_id_string = isset($post_id_arr[1]) ? $post_id_arr[1] : ''; 3439 3374 $backend_status = sanitize_text_field($media_data['status'] ?? ''); 3440 3375 $last_synced = sanitize_text_field($media_data['last_synced'] ?? current_time('mysql')); -
ansera-search/trunk/js/ansera_search_admin_settings.js
r3337395 r3349746 897 897 url = url.trim(); 898 898 // Accept all YouTube links (with or without protocol/www) 899 const youtubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+/i; 899 // const youtubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+/i; 900 const pattern = new RegExp( 901 '^(https?:\\/\\/)?' + // protocol 902 '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name 903 '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR IP (v4) address 904 '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path 905 '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string 906 '(\\#[-a-z\\d_]*)?$','i' // fragment locator 907 ); 900 908 // Accept direct video/audio file links (any domain, must end with extension) 901 const extRegex = /\.((mp3|m4a|ogg|wav|wma|mp4|m4v|webm|wmv|ogv )(\?.*)?)$/i;902 return youtubeRegex.test(url) || extRegex.test(url);909 const extRegex = /\.((mp3|m4a|ogg|wav|wma|mp4|m4v|webm|wmv|ogv|doc|docx|pdf|ppt|pptx|xls|xlsx|)(\?.*)?)$/i; 910 return pattern.test(url) || extRegex.test(url); 903 911 } -
ansera-search/trunk/readme.txt
r3337395 r3349746 1 1 === Ansera Search === 2 2 Contributors: Ansera01 3 Tags: search, chatbot, openAI, AI search, chatgpt3 Tags: ai search, chatbot, search, lead gen, relevance 4 4 Requires at least: 5.0 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.2 7 Stable tag: 1.1. 37 Stable tag: 1.1.4 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 12 12 13 13 == Description == 14 Ansera Search replaces the default WordPress search with a powerful Generative AI (GenAI)-driven experience.14 Ansera Search replaces the default WordPress search with an intuitive AI powered answer engine based on your site's existing content. 15 15 16 Ansera is based off of your site's content so it will only provide responses based off of what you wish to train it on. Ansera solves the issue of visitors leaving in frustration when they can't find answers on your site. Ansera analytics let you see what your users are searching for to help you improve your content and conversion rates. Built on top of OpenAI, it understands your visitors' queries and delivers meaningful, summarized answers—far beyond keyword matches. 16 We all know that when website visitors can't find the answers they're looking for, they will leave in frustration never to return. Traditional website search just returns a list of links for visitors to sort through themselves while most chatbot solutions are annoying and require significant set up. 17 18 Ansera solves for these issues and more by providing your website visitors with human readable natural language search responses based only on your site's content. 19 20 Unlike traditional website search tools, Ansera can be up and running in as little as 5 minutes by even the least technical users. Once you install Ansera on your site, all you have to do is select the pages you want to train it to answer on. Additionally, you can link to externally stored content like youtube and vimeo videos or presentations. 21 22 Ansera's analytics let you see what answers your users are actually seeking and how to improve your content and conversion to better serve them. 17 23 18 24 **Features:** 19 - Human-readable natural language search results 20 - AI responses are automatically trained off of your site's content 21 - Replaces default search seamlessly 22 - Real-time sync with your content 23 - Customize and edit AI answers 24 - Floating search box or menu icon option 25 - Built using OpenAI’s advanced language models 26 - Visitors can email results to themselves 25 - Out of the box set up while also providing several visual customization options for more advanced users 26 - Human readable natural language search results 27 - Real-time sync that updates answers as site content is updated 28 - User analytics for all search queries 29 - Customizable guiding questions 30 - Visitors can email results to themselves 31 - Integrate a custom lead generation form into the Ansera widget 27 32 28 Bring conversational AI search to your site in minutes —no code required.33 Bring conversational AI search to your site in minutes - no coding required! 29 34 30 35 == Installation == … … 36 41 == Frequently Asked Questions == 37 42 38 = How does the plugin work? =39 The plugin syncs your site content with Ansera's GenAI backend. Users get contextual, summarized results powered by AI.43 = What is Ansera? = 44 Ansera is an AI-powered tool that transforms WordPress websites into intelligent, conversational platforms. Leveraging the content already on your site, Ansera delivers contextual, summarized answers to visitors that make for a more intuitive and engaging user experience than traditional search or chatbots. 40 45 41 = Can I customize the AI responses? = 42 Yes! We provide you with the option to edit any previously provided answers and ensure new users will receive an updated response. 46 = Is Ansera a replacement for Search? = 47 Yes, Ansera is an enhanced replacement for search functionality on your wordpress site. Unlike traditional search, however, Ansera doesn’t just return a list of links for visitors to sort through. 48 It provides a natural language response interface for visitors to ask questions and get complete conversational responses 43 49 44 = Where does the AI model run? = 45 Search queries are securely processed via the Ansera backend which is built on OpenAI. 50 = Can Ansera replace my chatbot? = 51 Ansera can be used in addition to or instead of a chatbot. You can configure Ansera to visually appear like a chatbot icon on the page as well as select up to 5 default questions to guide visitors. 52 53 = What data does Ansera sync with automatically? = 54 Ansera syncs with any pages from your website that you select. You can select or unselect a page at any time; Ansera will update responses accordingly. 55 56 = What other type of files can Ansera sync with? = 57 In addition to your website content, you can link to externally stored content such as YouTube/Vimeo videos, podcasts, pdfs, and presentations 58 59 = Can I customize the look of Ansera? = 60 Yes! You can customize almost everything about Ansera from how the widget is displayed to the default questions customers can ask to how Ansera responds to questions that are out of scope. Ansera’s color scheme will match your Wordpress site theme so you can use it out of the box if you would like. 61 62 = Is my information being used to train an LLM? = 63 Your information remains local and will not be used to train an LLM or outside resource. 64 65 = How do you prevent bot traffic? = 66 Ansera integrates with Google reCAPTCHA v3 for invisible spam protection that doesn't interfere with genuine visitor conversations. 67 68 = What happens when Ansera can’t answer a question? = 69 A customizable message will be shown to the user stating that the question could not be answered. Additionally, you’ll be able to see which questions were not answered. This allows you to either guide your content strategy or train Ansera to train similar questions in the future. 70 71 = Can I edit the answers Ansera generates? = 72 You can edit answers in the Ansera dashboard. Ansera will learn from the edited responses to answer similar future questions. 73 74 = What metrics can I see in the Ansera dashboard? = 75 The Ansera dashboard lets you see information such as how many visitors and queries were generated during a certain time period. Additionally, you can see all queries and how users rated the answers they received. 46 76 47 77 … … 63 93 64 94 == Changelog == 95 = 1.1.4 = 96 * Added support for external documents syncing (Google Drive or Direct File URLs) 97 * Introduced custom color theme and you can customize the widget UI. 98 * Updated FAQ 65 99 66 100 = 1.1.0 =
Note: See TracChangeset
for help on using the changeset viewer.