This file is a merged representation of the entire codebase, combined into a single document by Repomix.
The content has been processed where content has been compressed (code blocks are separated by ⋮---- delimiter).

================================================================
File Summary
================================================================

Purpose:
--------
This file contains a packed representation of the entire repository's contents.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.

File Format:
------------
The content is organized as follows:
1. This summary section
2. Repository information
3. Directory structure
4. Multiple file entries, each consisting of:
  a. A separator line (================)
  b. The file path (File: path/to/file)
  c. Another separator line
  d. The full contents of the file
  e. A blank line

Usage Guidelines:
-----------------
- This file should be treated as read-only. Any changes should be made to the
  original repository files, not this packed version.
- When processing this file, use the file path to distinguish
  between different files in the repository.
- Be aware that this file may contain sensitive information. Handle it with
  the same level of security as you would the original repository.

Notes:
------
- Some files may have been excluded based on .gitignore rules and Repomix's configuration
- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
- Files matching patterns in .gitignore are excluded
- Files matching default ignore patterns are excluded
- Content has been compressed - code blocks are separated by ⋮---- delimiter
- Files are sorted by Git change count (files with more changes are at the bottom)

Additional Info:
----------------

================================================================
Directory Structure
================================================================
.cursor/
  rules/
    moodle.mdc
    rules.mdc
    wordpress.mdc
amd/
  build/
    edwiser_bridge.min.js
    edwiser_bridge.min.js.map
    settings.min.js
    settings.min.js.map
    sso_settings.min.js
    sso_settings.min.js.map
  src/
    edwiser_bridge.js
    settings.js
    sso_settings.js
classes/
  external/
    api.php
    create_service.php
    delete_cohort.php
    enable_plugin_settings.php
    get_course_enrollment_method.php
    get_course_progress.php
    get_courses.php
    get_edwiser_plugins_info.php
    get_mandatory_settings.php
    get_service_info.php
    get_site_data.php
    get_users.php
    link_service.php
    manage_cohort_enrollment.php
    manage_user_cohort_enrollment.php
    setup_test_connection.php
    setup_wizard_save_and_continue.php
    test_connection.php
    update_course_enrollment_method.php
    validate_token.php
    verify_sso_token.php
  local/
    api_handler.php
    eb_pro_license_controller.php
    migration_helper.php
    settings_handler.php
    setup_wizard.php
    update.php
  privacy/
    provider.php
  settings/
    connection_form.php
    navigation_form.php
    service_form.php
    settings_form.php
    sso_form.php
    summary_form.php
    synchronization_form.php
  observer.php
db/
  access.php
  events.php
  install.php
  services.php
  upgrade.php
lang/
  en/
    auth_edwiserbridge.php
specs/
  1_Activity_Overview_Page_Integration.md
  10 AI_Compatibility_Workflow.md
  2_Human_Date_Renderers.md
  3_Course_Format_Migration.md
  4_Plugin_Type_Deprecation.md
  5_Subplugin_Type_Deprecation.md
  6_Bootstrap_5_Migration.md
  7_PHPUnit_11_Upgrade.md
  8 AI_Compatibility_Check_Implementation.md
  9 AI_Compatibility_Enhancement_Strategy.md
  Roadmap.md
styles/
  setup-wizard.css
  style.css
templates/
  create_token_field.mustache
  installation_guide.mustache
  license_form.mustache
  permalink.mustache
  plugin_configuration.mustache
  plugin_update_notification.mustache
  setup_close.mustache
  setup_complete_details.mustache
  setup_completion_popup.mustache
  setup_redirection_popup.mustache
  setup_steps.mustache
  setup_wizard_footer.mustache
  setup_wizard_header.mustache
  setup_wizard_template.mustache
  test_connection.mustache
  user_and_course_sync.mustache
  web_service.mustache
  wordpress_site_details.mustache
auth.php
changes.txt
edwiserbridge.php
install_update.php
lib.php
LICENSE.md
login.php
mod_form.php
README.md
settings.php
setup_wizard.php
styles.css
version.php
wdmwplogin.php

================================================================
Files
================================================================

================
File: .cursor/rules/moodle.mdc
================
---
description: 
globs: 
alwaysApply: true
---
You are an a senior developer with superpowers! ⚡ who is an expert in Moodle, PHP, and related web development technologies.

# Agent Behavior
- Read repomix-output.xml file first
- Read Roadmap.md in the specs directory second
- Provide suggestions for updates, fixes, or modifications needed to ensure compatibility with Moodle 5.0
- Plan database schema changes
- Write tests for critical paths
- Start making the plugin compatible with Moodle 5.0 after finding any potential compatibility issues.
- Run the generated tests and keep making changes till all the tests pass.
- Please prompt me for details if you need clarification somewhere.

# Core Principles
- Provide precise, technical Moodle and PHP examples.
- Adhere to Moodle best practices for consistency and readability.
- Emphasize object-oriented programming (OOP) for better modularity.
- Focus on code reusability through iteration and modularization, avoiding duplication.
- Use descriptive and meaningful function, variable, and file names.
- Directory naming conventions: lowercase with hyphens (e.g., moodle/mod/myplugin).
- Utilize Moodle’s hooks (events and callbacks) for extending functionality.
- Add clear, descriptive comments to improve code clarity and maintainability.

# PHP/Moodle Coding Practices
- Utilize features of PHP 8.2+ (e.g., typed properties, arrow functions) where applicable.
- Follow Moodle coding standards throughout the codebase.
- Enable strict typing by adding declare(strict_types=1); at the top of PHP files.
- Leverage core Moodle functions and APIs wherever possible.
- Maintain Moodle plugin and theme directory structure and naming conventions.
- Implement robust error handling:
    - Use Moodle’s built-in debugging functions ($DB->get_record).
    - Implement custom error handlers if necessary.
    - Apply try-catch blocks for controlled exception handling.
- Always use Moodle’s built-in functions for data validation and sanitization.
- Ensure secure form handling by verifying nonces in submissions and using $PAGE->requires->js() for AJAX.
- For database interactions:
    - Use Moodle’s $DB class for database queries.
    - Apply prepare() for all dynamic queries to prevent SQL injection.
    - Use the upgrade() function for managing database schema changes.

# Dependencies
- Ensure compatibility with the latest stable version of Moodle.
- Use Composer for dependency management in advanced plugins or modules.

# Moodle Best Practices
- Use Moodle’s plugin API to develop features and extend Moodle core functionality.
- Never modify core Moodle files—extend functionality using plugins, themes, and blocks.
- Organize plugin-specific functions within lib.php or a dedicated class for better maintainability.
- Use Moodle’s user roles and capabilities for managing permissions in custom plugins.
- Use Moodle’s cache API for caching data and optimizing performance.
- Implement background processing tasks using Moodle’s scheduled_task API for long-running operations.
- Write unit tests using Moodle’s built-in testing framework.
- Follow best practices for internationalization (i18n) by using Moodle’s get_string() function for language strings.
- Implement proper security practices such as nonce verification, input sanitization, and data escaping.
- Use Moodle’s theme and renderer for managing templates and front-end logic.
- Use Moodle’s custom post types (e.g., modules, blocks, and filters) when extending Moodle’s features.
- Store configuration data securely using Moodle’s set_config() and get_config() functions.
- Implement pagination effectively with Moodle’s core_renderer::pagination() function.

# Key Conventions
1. Follow Moodle’s plugin API to extend functionality in a modular and scalable manner.
2. Use Moodle’s templating system (output) for consistent rendering across themes.
3. Apply Moodle’s built-in functions for data sanitization and validation to secure user inputs.
4. Implement Moodle’s core_renderer class for managing theme-based dynamic content.
5. For custom queries, use $DB or get_records_sql() for database interactions.
6. Use Moodle’s authentication and authorization mechanisms for secure access control.
7. For AJAX requests, use Moodle’s ajax class or the Moodle REST API for handling backend requests.
8. Always apply Moodle’s event-driven architecture for extensible and modular code (e.g., using core\event).
9. Implement database operations using transactional functions where needed, such as $DB->start_delegated_transaction().
10. Schedule tasks using Moodle’s scheduled_task API for automated workflows.

# Coding Rules Documentation

This document is converted from the JSON configuration file to a Markdown document. It outlines the rules applied for JS, PHP, CSS, SQL, and Security.

---

## JavaScript Rules

### Style
- **indent**: 2
- **quotes**: single
- **semicolons**: always
- **variableCase**: camelCase

### Lint
- **noVar**: true
- **preferConst**: true

#### moodleEslintRules
- **extends**: plugin:moodle/recommended

#### requireAMDModules
- **enabled**: true
- **message**: "Use AMD modules (define()) for Moodle JS."

#### disallowJQueryAlias
- **enabled**: true
- **message**: "Use `document` or native methods instead of `$` (jQuery)."

#### preferPromises
- **enabled**: true
- **message**: "Use Promises or async/await instead of callbacks."

---

## PHP Rules

### Style
- **indent**: 4

#### braces
- **class**: same-line
- **function**: same-line
- **control**: next-line

#### operators
- **spacing**:
  - after: true
  - before: true

#### docblock
- **align**: true

### Lint
- **disallowShortOpenTag**: true
- **requireStrictTypes**: true
- **forbidInlineHTML**: true

#### disallowRawSQL
- **enabled**: true
- **message**: "Use Moodle's $DB API (e.g., $DB->get_records()) instead of raw SQL."

#### requireParamValidation
- **enabled**: true
- **message**: "Validate parameters using clean_param() or PARAM_* types."

#### frankenstyleComponent
- **enabled**: true
- **pattern**: "^[a-z]+(_[a-z0-9]+)+$"
- **message**: "Component names must follow Frankenstyle (e.g., mod_forum, tool_log)."

#### frankenstyleClass
- **enabled**: true
- **pattern**: "^[A-Z][a-zA-Z0-9_]+(_[a-zA-Z0-9_]+)*$"
- **message**: "Class names must follow Frankenstyle (e.g., mod_forum\output\renderer)."

#### webserviceFunctionNaming
- **enabled**: true
- **pattern**: "^core_[a-z0-9_]+(_[a-z0-9_]+)*$"
- **message**: "Web service functions must follow core_componentname_verb (e.g., core_course_get_courses)."

---

## CSS Rules

### Style
- **indent**: 2
- **propertySorting**: alphabetical
- **colorFormat**: lowercaseHex

### Lint
- **noIdSelectors**: true
- **noImportant**: true

#### requireBEM
- **enabled**: true
- **pattern**: "^[a-z][a-z-]*(__[a-z][a-z-]*)?(--[a-z][a-z-]*)?$"
- **message**: "Follow BEM naming (e.g., .block__element--modifier)."

#### disallowIdSelectors
- **enabled**: true

---

## SQL Rules

### Lint
- **disallowRawSQL**: true

#### requirePlaceholders
- **enabled**: true
- **message**: "Use named placeholders (e.g., :param) in SQL queries."

#### disallowUnsafeFunctions
- **enabled**: true
- **functions**: mysql_*, mysqli_*, pg_*
- **message**: "Use Moodle's $DB API instead of raw database functions."

#### disallowRawUpdates
- **enabled**: true
- **message**: "Avoid raw UPDATE/DELETE queries; use $DB->update_records() or $DB->delete_records()."

---

## Security Rules

### requireCSRFToken
- **enabled**: true
- **message**: "Include sesskey (CSRF token) in forms/ajax calls."

### disallowUnsafeOutput
- **enabled**: true
- **message**: "Escape output with format_string(), format_text(), or htmlspecialchars()."

### requireLoginCheck
- **enabled**: true
- **pattern**: "require_login|require_capability"
- **message**: "Check authentication/capabilities with require_login() or require_capability()."

### escapeOutput
- **enabled**: true
- **functions**: format_string, format_text, s, htmlspecialchars
- **message**: "Escape output using format_string(), s(), or htmlspecialchars()."

### disallowUnescapedInput
- **enabled**: true
- **pattern**: "\$_(GET|POST|REQUEST)\[[^]]+\]"
- **message**: "Sanitize input with optional_param() or clean_param()."

### requireSesskey
- **enabled**: true
- **pattern**: "(require_sesskey|sesskey)"
- **message**: "Include sesskey in forms/AJAX requests."

### disallowUnsafeShell
- **enabled**: true
- **functions**: exec, system, passthru
- **message**: "Use escapeshellarg() or Moodle utilities for shell commands."

### disallowDebugCode
- **enabled**: true
- **pattern**: "var_dump|print_r|die\("
- **message**: "Remove debugging code (var_dump, die()) before commits."

### disallowSensitiveLogs
- **enabled**: true
- **pattern**: "logging.*password|logging.*token"
- **message**: "Avoid logging sensitive data (passwords, tokens)."

### requireSessionRegeneration
- **enabled**: true
- **pattern**: "session_regenerate_id\(true\)"
- **message**: "Regenerate session IDs after privilege changes." 

## Security References

- @Moodle Security Policies
- @XSS Prevention
- @SQL Standards 


## Further Resources

- [Official Documentation](mdc:https:/docs.moodle.org/dev/Main_Page)
- [GitHub Repository](mdc:https:/github.com/moodle/moodle)

================
File: .cursor/rules/rules.mdc
================
---
description: 
globs: 
alwaysApply: false
---
You are instructed, a senior PHP developer with superpowers! ⚡

# Agent Behavior
- Read Roadmap.md first
- Plan database schema changes
- Write system tests for critical paths

# Code Standards
- Follow Rails conventions
- Use concerns for shared logic
- Tests must pass before merge

# Coding Rules Documentation

This document is converted from the JSON configuration file to a Markdown document. It outlines the rules applied for JS, PHP, CSS, SQL, and Security.

---

## JavaScript Rules

### Style
- **indent**: 2
- **quotes**: single
- **semicolons**: always
- **variableCase**: camelCase

### Lint
- **noVar**: true
- **preferConst**: true

#### moodleEslintRules
- **extends**: plugin:moodle/recommended

#### requireAMDModules
- **enabled**: true
- **message**: "Use AMD modules (define()) for Moodle JS."

#### disallowJQueryAlias
- **enabled**: true
- **message**: "Use `document` or native methods instead of `$` (jQuery)."

#### preferPromises
- **enabled**: true
- **message**: "Use Promises or async/await instead of callbacks."

---

## PHP Rules

### Style
- **indent**: 4

#### braces
- **class**: same-line
- **function**: same-line
- **control**: next-line

#### operators
- **spacing**:
  - after: true
  - before: true

#### docblock
- **align**: true

### Lint
- **disallowShortOpenTag**: true
- **requireStrictTypes**: true
- **forbidInlineHTML**: true

#### disallowRawSQL
- **enabled**: true
- **message**: "Use Moodle's $DB API (e.g., $DB->get_records()) instead of raw SQL."

#### requireParamValidation
- **enabled**: true
- **message**: "Validate parameters using clean_param() or PARAM_* types."

#### frankenstyleComponent
- **enabled**: true
- **pattern**: "^[a-z]+(_[a-z0-9]+)+$"
- **message**: "Component names must follow Frankenstyle (e.g., mod_forum, tool_log)."

#### frankenstyleClass
- **enabled**: true
- **pattern**: "^[A-Z][a-zA-Z0-9_]+(_[a-zA-Z0-9_]+)*$"
- **message**: "Class names must follow Frankenstyle (e.g., mod_forum\output\renderer)."

#### webserviceFunctionNaming
- **enabled**: true
- **pattern**: "^core_[a-z0-9_]+(_[a-z0-9_]+)*$"
- **message**: "Web service functions must follow core_componentname_verb (e.g., core_course_get_courses)."

---

## CSS Rules

### Style
- **indent**: 2
- **propertySorting**: alphabetical
- **colorFormat**: lowercaseHex

### Lint
- **noIdSelectors**: true
- **noImportant**: true

#### requireBEM
- **enabled**: true
- **pattern**: "^[a-z][a-z-]*(__[a-z][a-z-]*)?(--[a-z][a-z-]*)?$"
- **message**: "Follow BEM naming (e.g., .block__element--modifier)."

#### disallowIdSelectors
- **enabled**: true

---

## SQL Rules

### Lint
- **disallowRawSQL**: true

#### requirePlaceholders
- **enabled**: true
- **message**: "Use named placeholders (e.g., :param) in SQL queries."

#### disallowUnsafeFunctions
- **enabled**: true
- **functions**: mysql_*, mysqli_*, pg_*
- **message**: "Use Moodle's $DB API instead of raw database functions."

#### disallowRawUpdates
- **enabled**: true
- **message**: "Avoid raw UPDATE/DELETE queries; use $DB->update_records() or $DB->delete_records()."

---

## Security Rules

### requireCSRFToken
- **enabled**: true
- **message**: "Include sesskey (CSRF token) in forms/ajax calls."

### disallowUnsafeOutput
- **enabled**: true
- **message**: "Escape output with format_string(), format_text(), or htmlspecialchars()."

### requireLoginCheck
- **enabled**: true
- **pattern**: "require_login|require_capability"
- **message**: "Check authentication/capabilities with require_login() or require_capability()."

### escapeOutput
- **enabled**: true
- **functions**: format_string, format_text, s, htmlspecialchars
- **message**: "Escape output using format_string(), s(), or htmlspecialchars()."

### disallowUnescapedInput
- **enabled**: true
- **pattern**: "\$_(GET|POST|REQUEST)\[[^]]+\]"
- **message**: "Sanitize input with optional_param() or clean_param()."

### requireSesskey
- **enabled**: true
- **pattern**: "(require_sesskey|sesskey)"
- **message**: "Include sesskey in forms/AJAX requests."

### disallowUnsafeShell
- **enabled**: true
- **functions**: exec, system, passthru
- **message**: "Use escapeshellarg() or Moodle utilities for shell commands."

### disallowDebugCode
- **enabled**: true
- **pattern**: "var_dump|print_r|die\("
- **message**: "Remove debugging code (var_dump, die()) before commits."

### disallowSensitiveLogs
- **enabled**: true
- **pattern**: "logging.*password|logging.*token"
- **message**: "Avoid logging sensitive data (passwords, tokens)."

### requireSessionRegeneration
- **enabled**: true
- **pattern**: "session_regenerate_id\(true\)"
- **message**: "Regenerate session IDs after privilege changes." 

## Security References

- [Moodle Security Policies](mdc:https:/moodledev.io/general/development/policies/security)
- [XSS Prevention](mdc:https:/moodledev.io/general/development/policies/security/crosssite-scripting)
- [SQL Standards](mdc:https:/moodledev.io/general/development/policies/codingstyle/sql)

================
File: .cursor/rules/wordpress.mdc
================
---
description: 
globs: 
alwaysApply: false
---

You are an a senior developer with superpowers! ⚡ who is an expert in Moodle, PHP, and related web development technologies.
     
# Core Principles
  - Provide precise, technical PHP and WordPress examples.
  - Adhere to PHP and WordPress best practices for consistency and readability.
  - Emphasize object-oriented programming (OOP) for better modularity.
  - Focus on code reusability through iteration and modularization, avoiding duplication.
  - Use descriptive and meaningful function, variable, and file names.
  - Directory naming conventions: lowercase with hyphens (e.g., wp-content/themes/my-theme).
  - Use WordPress hooks (actions and filters) for extending functionality.
  - Add clear, descriptive comments to improve code clarity and maintainability.
    
# PHP/WordPress Coding Practices
  - Utilize features of PHP 7.4+ (e.g., typed properties, arrow functions) where applicable.
  - Follow WordPress PHP coding standards throughout the codebase.
  - Enable strict typing by adding declare(strict_types=1); at the top of PHP files.
  - Leverage core WordPress functions and APIs wherever possible.
  - Maintain WordPress theme and plugin directory structure and naming conventions.
  - Implement robust error handling:
    - Use WordPress's built-in debug logging (WP_DEBUG_LOG).
    - Implement custom error handlers if necessary.
    - Apply try-catch blocks for controlled exception handling.
  - Always use WordPress’s built-in functions for data validation and sanitization.
  - Ensure secure form handling by verifying nonces in submissions.
  - For database interactions:
    - Use WordPress’s $wpdb abstraction layer.
    - Apply prepare() statements for all dynamic queries to prevent SQL injection.
    - Use the dbDelta() function for managing database schema changes.

# Dependencies
  - Ensure compatibility with the latest stable version of WordPress.
  - Use Composer for dependency management in advanced plugins or themes.

# WordPress Best Practices
  - Use child themes for customizations to preserve update compatibility.
  - Never modify core WordPress files—extend using hooks (actions and filters).
  - Organize theme-specific functions within functions.php.
  - Use WordPress’s user roles and capabilities for managing permissions.
  - Apply the transients API for caching data and optimizing performance.
  - Implement background processing tasks using wp_cron() for long-running operations.
  - Write unit tests using WordPress’s built-in WP_UnitTestCase framework.
  - Follow best practices for internationalization (i18n) by using WordPress localization functions.
  - Apply proper security practices such as nonce verification, input sanitization, and data escaping.
  - Manage scripts and styles by using wp_enqueue_script() and wp_enqueue_style().
  - Use custom post types and taxonomies when necessary to extend WordPress functionality.
  - Store configuration data securely using WordPress's options API.
  - Implement pagination effectively with functions like paginate_links().

# Key Conventions
  1. Follow WordPress’s plugin API to extend functionality in a modular and scalable manner.
  2. Use WordPress’s template hierarchy when developing themes to ensure flexibility.
  3. Apply WordPress’s built-in functions for data sanitization and validation to secure user inputs.
  4. Implement WordPress’s template tags and conditional tags in themes for dynamic content handling.
  5. For custom queries, use $wpdb or WP_Query for database interactions.
  6. Use WordPress’s authentication and authorization mechanisms for secure access control.
  7. For AJAX requests, use admin-ajax.php or the WordPress REST API for handling backend requests.
  8. Always apply WordPress’s hook system (actions and filters) for extensible and modular code.
  9. Implement database operations using transactional functions where needed.
  10. Schedule tasks using WordPress’s WP_Cron API for automated workflows.

## Further Resources

- [Official Documentation](https://developer.wordpress.org/)
- [GitHub Repository](https://github.com/WordPress/WordPress)

================
File: amd/build/edwiser_bridge.min.js
================
/**
 * JS file to handle edwiser bridge.
 *
 * @package
 * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license     https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @author      Wisdmlabs
 * @module      auth_edwiserbridge/edwiser_bridge
 */
define("auth_edwiserbridge/edwiser_bridge",["jquery","core/ajax","core/url","core/str"],(function($,ajax,url){return{init:function($params){$(document).ready((function(){function onRemoveHideElemnts(index){$("#id_wp_name_"+index).closest("fieldset").css("display","none")}if($('input[name^="wp_name"]').on({keydown:function(e){if(32===e.which)return!1},change:function(){this.value=this.value.replace(/\s/g,"")}}),$("[id$=_eb_test_connection]").click((function(event){event.preventDefault(),$(document.body).css({cursor:"wait"});var id=$(this).prop("id"),index=(id=(id=id.replace("eb_test_connection","")).replace("id_eb_buttons","")).replace(/\_/g,""),url=$("#id_wp_url_"+index).val(),token=$("#id_wp_token_"+index).val(),parent=$(this).parent().parent();(parent=parent.parent()).find("#eb_test_conne_response_old").css("display","none"),ajax.call([{methodname:"auth_edwiserbridge_test_connection",args:{wp_url:url,wp_token:token}}])[0].done((function(response){parent.find("#eb_test_conne_response_old").html(response.msg),parent.find("#eb_test_conne_response_old").css("display","block"),1==response.status?(parent.find("#eb_test_conne_response_old").addClass("eb-success-msg"),parent.find("#eb_test_conne_response_old").removeClass("eb-error-msg")):(parent.find("#eb_test_conne_response_old").removeClass("eb-success-msg"),parent.find("#eb_test_conne_response_old").addClass("eb-error-msg")),$(document.body).css({cursor:"default"})})).fail((function(ex){$(document.body).css({cursor:"default"})}))})),$("[id$=_eb_remove_site]").click((function(event){event.preventDefault();var id=$(this).prop("id"),index=(id=(id=id.replace("eb_remove_site","")).replace("id_eb_buttons","")).replace(/\_/g,"");$("#id_wp_url_"+index).val(""),$("#id_wp_token_"+index).val(""),$("#id_wp_name_"+index).val(""),onRemoveHideElemnts(index),$("input[name='wp_remove["+index+"]']").val("yes")})),$("input[name='wp_remove[0]']").length)for(var repeatQty=$("input[name='eb_connection_setting_repeats']").val(),i=0;i<repeatQty;i++)"yes"==$("input[name='wp_remove["+i+"]']").val()&&onRemoveHideElemnts(i);$("#id_wp_site_list").on("change",(function(){ajax.call([{methodname:"auth_edwiserbridge_get_site_data",args:{site_index:$(this).val()}}])[0].done((function(response){$("#id_course_enrollment").prop("checked",response.course_enrollment),$("#id_course_un_enrollment").prop("checked",response.course_un_enrollment),$("#id_user_creation").prop("checked",response.user_creation),$("#id_user_deletion").prop("checked",response.user_deletion),$("#id_course_creation").prop("checked",response.course_creation),$("#id_course_deletion").prop("checked",response.course_deletion),$("#id_user_updation").prop("checked",response.user_updation)})).fail((function(ex){}))}))}))}}}));
⋮----
//# sourceMappingURL=edwiser_bridge.min.js.map

================
File: amd/build/edwiser_bridge.min.js.map
================
{"version":3,"file":"edwiser_bridge.min.js","sources":["../src/edwiser_bridge.js"],"sourcesContent":["/* eslint-disable no-unused-vars */\n// This file is part of Moodle - https://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n/**\n * JS file to handle edwiser bridge.\n *\n * @package\n * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>\n * @license     https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @author      Wisdmlabs\n * @module      auth_edwiserbridge/edwiser_bridge\n */\ndefine(['jquery', 'core/ajax', 'core/url', 'core/str'], function($, ajax, url) {\n    return {\n        init: function($params) {\n            $(document).ready(function() {\n\n                /**\n                 * Functionality to avoid space in the site name.\n                 */\n                $('input[name^=\"wp_name\"]').on({\n                    keydown: function(e) {\n                        if (e.which === 32) {\n                            return false;\n                        }\n                    },\n                    change: function() {\n                        this.value = this.value.replace(/\\s/g, \"\");\n                    }\n                });\n\n\n                /**\n                 * Functionality to test connection.\n                 */\n                $(\"[id$=_eb_test_connection]\").click(function(event) {\n                    event.preventDefault();\n                    $(document.body).css({ 'cursor': 'wait' });\n                    var id = $(this).prop(\"id\");\n                    id = id.replace(\"eb_test_connection\", '');\n                    id = id.replace(\"id_eb_buttons\", '');\n                    var index = id.replace(/\\_/g, '');\n                    var url = $(\"#id_wp_url_\" + index).val();\n                    var token = $(\"#id_wp_token_\" + index).val();\n                    var parent = $(this).parent().parent();\n                    parent = parent.parent();\n\n                    // Display none the error div.\n                    parent.find(\"#eb_test_conne_response_old\").css(\"display\", \"none\");\n\n                    var promises = ajax.call([\n                        { methodname: 'auth_edwiserbridge_test_connection', args: { wp_url: url, wp_token: token } }\n                    ]);\n\n                    promises[0].done(function(response) {\n                        parent.find(\"#eb_test_conne_response_old\").html(response.msg);\n                        parent.find(\"#eb_test_conne_response_old\").css(\"display\", \"block\");\n\n                        if (response.status == 1) {\n                            parent.find(\"#eb_test_conne_response_old\").addClass(\"eb-success-msg\");\n                            parent.find(\"#eb_test_conne_response_old\").removeClass(\"eb-error-msg\");\n                        } else {\n                            parent.find(\"#eb_test_conne_response_old\").removeClass(\"eb-success-msg\");\n                            parent.find(\"#eb_test_conne_response_old\").addClass(\"eb-error-msg\");\n                        }\n                        $(document.body).css({ 'cursor': 'default' });\n                    }).fail(function(ex) {\n                        // Do something with the exception.\n                        $(document.body).css({ 'cursor': 'default' });\n                    });\n                });\n\n                /**\n                 * Functionality to remove site from the sites list.\n                 */\n                $(\"[id$=_eb_remove_site]\").click(function(event) {\n                    event.preventDefault();\n                    var id = $(this).prop(\"id\");\n                    id = id.replace(\"eb_remove_site\", '');\n                    id = id.replace(\"id_eb_buttons\", '');\n                    var index = id.replace(/\\_/g, '');\n\n                    $(\"#id_wp_url_\" + index).val(\"\");\n                    $(\"#id_wp_token_\" + index).val(\"\");\n                    $(\"#id_wp_name_\" + index).val(\"\");\n\n                    // Hiding elemnts.\n                    onRemoveHideElemnts(index);\n                    $(\"input[name='wp_remove[\" + index + \"]']\").val(\"yes\");\n                });\n\n                /**\n                 * Hide the elements removed from the remove button.\n                 * @param {number} index - Index of the element.\n                 */\n                function onRemoveHideElemnts(index) {\n                    $(\"#id_wp_name_\" + index).closest('fieldset').css(\"display\", \"none\");\n                }\n\n                // Hiding js elements which are already removed.\n                if ($(\"input[name='wp_remove[0]']\").length) {\n                    var repeatQty = $(\"input[name='eb_connection_setting_repeats']\").val();\n                    for (var i = 0; i < repeatQty; i++) {\n                        if (\"yes\" == $(\"input[name='wp_remove[\" + i + \"]']\").val()) {\n                            onRemoveHideElemnts(i);\n                        }\n                    }\n                }\n\n                /**\n                 * Functionlaity to get site synch values on the site change.\n                 */\n                $(\"#id_wp_site_list\").on(\"change\", function() {\n                    var promises = ajax.call([\n                        { methodname: 'auth_edwiserbridge_get_site_data', args: { site_index: $(this).val() } }\n                    ]);\n                    promises[0].done(function(response) {\n                        $('#id_course_enrollment').prop('checked', response.course_enrollment);\n                        $('#id_course_un_enrollment').prop('checked', response.course_un_enrollment);\n                        $('#id_user_creation').prop('checked', response.user_creation);\n                        $('#id_user_deletion').prop('checked', response.user_deletion);\n                        $('#id_course_creation').prop('checked', response.course_creation);\n                        $('#id_course_deletion').prop('checked', response.course_deletion);\n                        $('#id_user_updation').prop('checked', response.user_updation);\n                    }).fail(function(ex) {});\n                });\n            });\n        }\n    };\n\n});\n"],"names":["define","$","ajax","url","init","$params","document","ready","onRemoveHideElemnts","index","closest","css","on","keydown","e","which","change","value","this","replace","click","event","preventDefault","body","id","prop","val","token","parent","find","call","methodname","args","wp_url","wp_token","done","response","html","msg","status","addClass","removeClass","fail","ex","length","repeatQty","i","site_index","course_enrollment","course_un_enrollment","user_creation","user_deletion","course_creation","course_deletion","user_updation"],"mappings":";;;;;;;;;AAwBAA,2CAAO,CAAC,SAAU,YAAa,WAAY,aAAa,SAASC,EAAGC,KAAMC,WAC/D,CACHC,KAAM,SAASC,SACXJ,EAAEK,UAAUC,OAAM,oBAgFLC,oBAAoBC,OACzBR,EAAE,eAAiBQ,OAAOC,QAAQ,YAAYC,IAAI,UAAW,WA5EjEV,EAAE,0BAA0BW,GAAG,CAC3BC,QAAS,SAASC,MACE,KAAZA,EAAEC,aACK,GAGfC,OAAQ,gBACCC,MAAQC,KAAKD,MAAME,QAAQ,MAAO,OAQ/ClB,EAAE,6BAA6BmB,OAAM,SAASC,OAC1CA,MAAMC,iBACNrB,EAAEK,SAASiB,MAAMZ,IAAI,QAAY,aAC7Ba,GAAKvB,EAAEiB,MAAMO,KAAK,MAGlBhB,OADJe,IADAA,GAAKA,GAAGL,QAAQ,qBAAsB,KAC9BA,QAAQ,gBAAiB,KAClBA,QAAQ,MAAO,IAC1BhB,IAAMF,EAAE,cAAgBQ,OAAOiB,MAC/BC,MAAQ1B,EAAE,gBAAkBQ,OAAOiB,MACnCE,OAAS3B,EAAEiB,MAAMU,SAASA,UAC9BA,OAASA,OAAOA,UAGTC,KAAK,+BAA+BlB,IAAI,UAAW,QAE3CT,KAAK4B,KAAK,CACrB,CAAEC,WAAY,qCAAsCC,KAAM,CAAEC,OAAQ9B,IAAK+B,SAAUP,UAG9E,GAAGQ,MAAK,SAASC,UACtBR,OAAOC,KAAK,+BAA+BQ,KAAKD,SAASE,KACzDV,OAAOC,KAAK,+BAA+BlB,IAAI,UAAW,SAEnC,GAAnByB,SAASG,QACTX,OAAOC,KAAK,+BAA+BW,SAAS,kBACpDZ,OAAOC,KAAK,+BAA+BY,YAAY,kBAEvDb,OAAOC,KAAK,+BAA+BY,YAAY,kBACvDb,OAAOC,KAAK,+BAA+BW,SAAS,iBAExDvC,EAAEK,SAASiB,MAAMZ,IAAI,QAAY,eAClC+B,MAAK,SAASC,IAEb1C,EAAEK,SAASiB,MAAMZ,IAAI,QAAY,kBAOzCV,EAAE,yBAAyBmB,OAAM,SAASC,OACtCA,MAAMC,qBACFE,GAAKvB,EAAEiB,MAAMO,KAAK,MAGlBhB,OADJe,IADAA,GAAKA,GAAGL,QAAQ,iBAAkB,KAC1BA,QAAQ,gBAAiB,KAClBA,QAAQ,MAAO,IAE9BlB,EAAE,cAAgBQ,OAAOiB,IAAI,IAC7BzB,EAAE,gBAAkBQ,OAAOiB,IAAI,IAC/BzB,EAAE,eAAiBQ,OAAOiB,IAAI,IAG9BlB,oBAAoBC,OACpBR,EAAE,yBAA2BQ,MAAQ,OAAOiB,IAAI,UAYhDzB,EAAE,8BAA8B2C,eAC5BC,UAAY5C,EAAE,+CAA+CyB,MACxDoB,EAAI,EAAGA,EAAID,UAAWC,IACvB,OAAS7C,EAAE,yBAA2B6C,EAAI,OAAOpB,OACjDlB,oBAAoBsC,GAQhC7C,EAAE,oBAAoBW,GAAG,UAAU,WAChBV,KAAK4B,KAAK,CACrB,CAAEC,WAAY,mCAAoCC,KAAM,CAAEe,WAAY9C,EAAEiB,MAAMQ,UAEzE,GAAGS,MAAK,SAASC,UACtBnC,EAAE,yBAAyBwB,KAAK,UAAWW,SAASY,mBACpD/C,EAAE,4BAA4BwB,KAAK,UAAWW,SAASa,sBACvDhD,EAAE,qBAAqBwB,KAAK,UAAWW,SAASc,eAChDjD,EAAE,qBAAqBwB,KAAK,UAAWW,SAASe,eAChDlD,EAAE,uBAAuBwB,KAAK,UAAWW,SAASgB,iBAClDnD,EAAE,uBAAuBwB,KAAK,UAAWW,SAASiB,iBAClDpD,EAAE,qBAAqBwB,KAAK,UAAWW,SAASkB,kBACjDZ,MAAK,SAASC"}

================
File: amd/build/settings.min.js
================
/**
 * Js file to handle settings.
 *
 * @package
 * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @author      Wisdmlabs
 * @module      auth_edwiserbridge/settings
 */
define("auth_edwiserbridge/settings",["jquery","core/ajax","core/url","core/str"],(function($,ajax,url,str){return{init:function(){str.get_strings([{key:"dialog_title",component:"auth_edwiserbridge"},{key:"site_url",component:"auth_edwiserbridge"},{key:"token",component:"auth_edwiserbridge"},{key:"copy",component:"auth_edwiserbridge"},{key:"copied",component:"auth_edwiserbridge"},{key:"link",component:"auth_edwiserbridge"},{key:"create",component:"auth_edwiserbridge"},{key:"eb_empty_name_err",component:"auth_edwiserbridge"},{key:"eb_empty_user_err",component:"auth_edwiserbridge"},{key:"eb_service_select_err",component:"auth_edwiserbridge"},{key:"click_to_copy",component:"auth_edwiserbridge"},{key:"pop_up_info",component:"auth_edwiserbridge"},{key:"eb_settings_msg",component:"auth_edwiserbridge"},{key:"click_here",component:"auth_edwiserbridge"}]),$(document).ready((function(){function checkMissingServices(service_id){let messge_ele=arguments.length>1&&void 0!==arguments[1]&&arguments[1];var promises=ajax.call([{methodname:"auth_edwiserbridge_get_service_info",args:{service_id:service_id}}]);promises[0].done((function(response){var message="";if($("body").css("cursor","default"),response.status)$("#web_service_status span").hasClass("summ_error")?($(".eb_summary_tab").removeClass("summary_tab_sucess"),$(".eb_summary_tab").addClass("summary_tab_error")):($(".eb_summary_tab").addClass("summary_tab_sucess"),$(".eb_summary_tab").removeClass("summary_tab_error")),messge_ele&&(message='<span style="color: #7ad03a;"><span class="summ_success" style="font-weight:bolder;color:#7ad03a;font-size:22px;">&#10003;</span></span>',$(messge_ele).empty().append(message));else if($(".eb_summary_tab").removeClass("summary_tab_sucess"),$(".eb_summary_tab").addClass("summary_tab_error"),messge_ele){if(messge_ele){var link=window.location.origin+window.location.pathname+"?tab=service",fix_link=M.util.get_string("more_details","auth_edwiserbridge")+" <a href='"+link+"'  target='_blank'>"+M.util.get_string("here","auth_edwiserbridge")+"</a>.";message="<span class='summ_error'>"+response.msg+fix_link+"</span>",$(messge_ele).empty().append(message)}}else $("#eb_common_err").text(response.msg),$("#eb_common_err").css("display","block");return response})).fail((function(response){return $("body").css("cursor","default"),0}))}if($(document).on("click",".eb_test_connection_log_open",(function(event){$(".eb_test_connection_log_open").addClass("eb_test_connection_log_close"),$(".eb_test_connection_log_close").removeClass("eb_test_connection_log_open"),$(".eb_test_connection_log").slideDown()})),$(document).on("click",".eb_test_connection_log_close",(function(event){$(".eb_test_connection_log_close").addClass("eb_test_connection_log_open"),$(".eb_test_connection_log_open").removeClass("eb_test_connection_log_close"),$(".eb_test_connection_log").slideUp()})),window.location.href.indexOf("edwiserbridge.php")>1){let searchParams=new URLSearchParams(window.location.search);if(searchParams.has("tab")&&"service"===searchParams.get("tab"))""!=(service_id=$("#id_eb_sevice_list").val())&&"create"!=service_id&&checkMissingServices(service_id);else if(searchParams.has("tab")&&"summary"===searchParams.get("tab")){var service_id;checkMissingServices(service_id=$("#web_service_status").data("serviceid"),"#web_service_status"),function(){let messge_ele=arguments.length>0&&void 0!==arguments[0]&&arguments[0];var wp_url=$("#eb_wp_url").text(),wp_token=$("#eb_wp_token").text();ajax.call([{methodname:"auth_edwiserbridge_test_connection",args:{wp_url:wp_url,wp_token:wp_token}}])[0].done((function(response){var message="";if($("body").css("cursor","default"),"0"==response.status)if($(".eb_summary_tab").removeClass("summary_tab_sucess"),$(".eb_summary_tab").addClass("summary_tab_error"),messge_ele){if(messge_ele){var fix_link=" Check more detials <a href='"+(window.location.origin+window.location.pathname)+"?tab=connection'  target='_blank'>here</a>.";message="<span class='summ_error'>"+response.msg+fix_link+"</span>",$(messge_ele).empty().append(message)}}else $("#eb_common_err").text(response.msg),$("#eb_common_err").css("display","block");else $("#test_connection_status span").hasClass("summ_error")?($(".eb_summary_tab").removeClass("summary_tab_sucess"),$(".eb_summary_tab").addClass("summary_tab_error")):($(".eb_summary_tab").addClass("summary_tab_sucess"),$(".eb_summary_tab").removeClass("summary_tab_error")),messge_ele&&(message='<span style="color: #7ad03a;"><span class="summ_success" style="font-weight: bolder; color: #7ad03a; font-size: 22px;">&#10003; '+response.msg+"</span></span>",$(messge_ele).empty().append(message));return response})).fail((function(response){return $("body").css("cursor","default"),0}))}("#test_connection_status")}}function toaster(title){let time=arguments.length>1&&void 0!==arguments[1]?arguments[1]:2e3;const id="auth_edwiserbridge_copy",toast=$('<div id="'+id+'">'+M.util.get_string("copied","auth_edwiserbridge")+"<div>").get(0);document.querySelector("body").appendChild(toast),toast.classList.add("show"),setTimeout((function(){toast.classList.add("fade"),setTimeout((function(){toast.classList.remove("fade"),setTimeout((function(){toast.remove()}),time)}),time)}))}$("#id_eb_sevice_list").change((function(){var service_id=$(this).val();$("#eb_common_success").css("display","none"),$("#eb_common_err").css("display","none"),$("#id_eb_token option:selected").removeAttr("selected"),$('#id_eb_token option[value=""]').attr("selected",!0),function(condition,condition_var,element){let btn=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";condition==condition_var?($(btn).text(M.util.get_string("create","auth_edwiserbridge")),$(element).css("display","flex")):($(btn).text(M.util.get_string("link","auth_edwiserbridge")),$(element).css("display","none"))}("create",service_id,".eb_service_field","#id_eb_mform_create_service"),""!=$(this).val()&&($("#id_eb_token").children("option").hide(),$("#id_eb_token").children("option[data-id^="+$(this).val()+"]").show(),"create"!=$(this).val()&&($("body").css("cursor","progress"),checkMissingServices(service_id)))})),$("#service_submit_continue").click((function(){$(this).closest("form").attr("action",M.cfg.wwwroot+"/auth/edwiserbridge/edwiserbridge.php?tab=connection")})),$("#conne_submit_continue").click((function(){$(this).closest("form").attr("action",M.cfg.wwwroot+"/auth/edwiserbridge/edwiserbridge.php?tab=synchronization")})),$("#sync_submit_continue").click((function(){$(this).closest("form").attr("action",M.cfg.wwwroot+"/auth/edwiserbridge/edwiserbridge.php?tab=sso")})),$("#sso_submit_continue").click((function(){$(this).closest("form").attr("action",M.cfg.wwwroot+"/auth/edwiserbridge/edwiserbridge.php?tab=summary")})),$("#settings_submit_continue").click((function(){$(this).closest("form").attr("action",M.cfg.wwwroot+"/auth/edwiserbridge/edwiserbridge.php?tab=service")})),$(".eb_settings_btn_cont").length||$("#admin-eb_setup_wizard_field").before('<div class="eb_settings_btn_cont" style="padding: 30px;"> '+M.util.get_string("eb_settings_msg","auth_edwiserbridge")+' <a target="_blank" style="border-radius:4px;margin-left:5px;padding:7px 18px;" class="eb_settings_btn btn btn-primary" href="'+M.cfg.wwwroot+'/auth/edwiserbridge/setup_wizard.php"> '+M.util.get_string("click_here","auth_edwiserbridge")+" </a></div>"),$("#admin-eb_setup_wizard_field").css("display","none"),$("#admin-ebnewserviceuserselect").length&&($("#eb_create_service").length||$("#admin-ebnewserviceuserselect").after('<div class="row eb_create_service_wrap">  <div class="offset-sm-3 col-sm-3">    <button type="submit" id="eb_create_service" class="btn">'+M.util.get_string("link","auth_edwiserbridge")+"</button>  </div></div>")),$(".eb_create_service_wrap").length&&$(".eb_create_service_wrap").before('<div class="row eb_common_err_wrap">  <div class="offset-sm-3 col-sm-3">    <span id="eb_common_err" class="btn"></span>    <span id="eb_common_success" class="btn"></span>  </div></div>'),$("#id_eb_mform_create_service").click((function(event){event.preventDefault();var error=0,web_service_name=$("#id_eb_service_inp").val(),user_id=$("#id_eb_auth_users_list").val(),service_id=$("#id_eb_sevice_list").val(),token=$("#id_eb_token").val();if($(".eb_settings_err").remove(),$("#eb_common_success").css("display","none"),$("#eb_common_err").css("display","none"),""==user_id&&($("#eb_common_err").text(M.util.get_string("eb_empty_user_err","auth_edwiserbridge")),$("#eb_common_err").css("display","block"),error=1),"create"==service_id){if(""==web_service_name&&($("#eb_common_err").css("display","block"),$("#eb_common_err").text(M.util.get_string("eb_empty_name_err","auth_edwiserbridge")),error=1),error)return;!function(web_service_name,user_id,service_select_fld,common_errr_fld,is_mform){$("body").css("cursor","progress"),$("#eb_common_err").css("display","none"),$("#id_eb_token option:selected").removeAttr("selected"),$('#id_eb_token option[value=""]').attr("selected",!0);var promises=ajax.call([{methodname:"auth_edwiserbridge_create_service",args:{web_service_name:web_service_name,user_id:user_id}}]);promises[0].done((function(response){if($("body").css("cursor","default"),response.status){var eb_dialog_content="<div> "+M.util.get_string("pop_up_info","auth_edwiserbridge")+' </div><table class="eb_toke_detail_tbl">  <tr>     <th width="17%">'+M.util.get_string("site_url","auth_edwiserbridge")+'</th>     <td> : <span class="eb_copy_text" title="'+M.util.get_string("click_to_copy","auth_edwiserbridge")+'">'+response.site_url+'</span>        <span class="eb_copy_btn">'+M.util.get_string("copy","auth_edwiserbridge")+'</span></td>  </tr>  <tr>     <th width="17%">'+M.util.get_string("token","auth_edwiserbridge")+'</th>     <td> : <span class="eb_copy_text" title="'+M.util.get_string("click_to_copy","auth_edwiserbridge")+'">'+response.token+'</span>        <span class="eb_copy_btn">'+M.util.get_string("copy","auth_edwiserbridge")+"</span></td>  </tr></table>";$("body").append('<div class="eb_service_pop_up_cont"><div class="eb_service_pop_up"><span class="helper"></span><div><div class="eb_service_pop_up_close">&times;</div><div><div class="eb_service_pop_up_title"></div><div class="eb_service_pop_up_content"></div></div></div></div></div>'),$(".eb_service_pop_up_content").html(eb_dialog_content),$(".eb_service_pop_up").show(),element=service_select_fld,name=web_service_name,id=response.service_id,$(element+"option:selected").removeAttr("selected"),$(element).append('<option value="'+id+'" selected> '+name+" </option>"),function(element,token,id){$(element+"option:selected").removeAttr("selected"),$(element).append('<option data-id="'+id+'" value="'+token+'" selected> '+token+" </option>")}("#id_eb_token",response.token,response.service_id)}else $("#eb_common_err").css("display","block"),$(common_errr_fld).text(response.msg);var element,name,id;return response})).fail((function(response){return $("body").css("cursor","default"),0}))}(web_service_name,user_id,"#id_eb_sevice_list","#eb_common_err")}else{if(""==$("#id_eb_token").val())return $("#eb_common_err").css("display","block"),$("#eb_common_err").text(M.util.get_string("token_empty","auth_edwiserbridge")),error=1,0;if(error)return;""!=service_id?function(service_id,token,common_errr_fld,common_success_fld){$("body").css("cursor","progress"),$("#eb_common_err").css("display","none"),ajax.call([{methodname:"auth_edwiserbridge_link_service",args:{service_id:service_id,token:token}}])[0].done((function(response){return $("body").css("cursor","default"),response.status?($(common_success_fld).text(response.msg),$(common_success_fld).css("display","block")):($(common_errr_fld).text(response.msg),$(common_success_fld).css("display","block")),response})).fail((function(response){return $("body").css("cursor","default"),0}))}(service_id,token,"#eb_common_err","#eb_common_success"):$("#eb_common_err").text(M.util.get_string("eb_service_select_err","auth_edwiserbridge"))}})),$(document).on("mouseenter",".eb_copy_text_wrap",(function(){$(this).find(".eb_copy_btn").css("visibility","visible")})),$(document).on("mouseleave",".eb_copy_text_wrap",(function(){$(this).find(".eb_copy_btn").css("visibility","hidden")})),$(document).on("click",".eb_copy_text_wrap",(function(event){event.preventDefault();var copyText=$(this).find(".eb_copy_text").html().trim();navigator.clipboard.writeText(copyText).then((()=>{toaster(M.util.get_string("copied","auth_edwiserbridge"),400)}))})),$(document).on("click",".eb_primary_copy_btn",(function(event){event.preventDefault();var parent=$(this).parent().parent();if("id_eb_token"==(parent=parent.find(".eb_copy")).attr("id"))var copyText=parent.val().trim();else copyText=parent.text().trim();navigator.clipboard.writeText(copyText).then((()=>{toaster(M.util.get_string("copied","auth_edwiserbridge"),200)}))})),$(document).on("click",".eb_service_pop_up_close",(function(){$(".eb_service_pop_up").hide()}));$("body").append('<div id="eb-lading-parent" class="eb-lading-parent-wrap"><div class="eb-loader-progsessing-anim"></div></div>'),$(document).on("click",".eb_setup_save_and_continue",(function(event){$(this);var current_step=$(this).data("step"),next_step=$(this).data("next-step"),is_next_sub_step=$(this).data("is-next-sub-step"),data={current_step:current_step,next_step:next_step,is_next_sub_step:is_next_sub_step};switch(current_step){case"installtion_guide":case"mdl_plugin_config":$("#eb-lading-parent").show(),data={current_step:current_step,next_step:next_step,is_next_sub_step:is_next_sub_step};break;case"web_service":var service_name=$(".eb_setup_web_service_list").val();if("create"==service_name&&""==$("#eb_setup_web_service_name").val())return event.preventDefault(),void $("#eb_setup_web_service_name").css("border-color","red");$("#eb-lading-parent").show();var existing_service=1;"create"==service_name&&""!=service_name&&(service_name=$(".eb_setup_web_service_name").val(),existing_service=0),data={current_step:current_step,next_step:next_step,is_next_sub_step:is_next_sub_step,service_name:service_name,existing_service:existing_service};break;case"wordpress_site_details":if(""!=site_name&&(""==$("#eb_setup_site_name").val()||""==$("#eb_setup_site_url").val()))return event.preventDefault(),""==$("#eb_setup_site_name").val()?$("#eb_setup_site_name").css("border-color","red"):$("#eb_setup_site_name").css("border-color","#E5E5E5"),void(""==$("#eb_setup_site_url").val()?$("#eb_setup_site_url").css("border-color","red"):$("#eb_setup_site_url").css("border-color","#E5E5E5"));$("#eb-lading-parent").show();var site_name=$(".eb_setup_wp_sites").val(),url="";""!=site_name&&(site_name=$(".eb_setup_site_name").val(),url=$(".eb_setup_site_url").val()),data={current_step:current_step,next_step:next_step,is_next_sub_step:is_next_sub_step,site_name:site_name,url:url};break;case"user_and_course_sync":$("#eb-lading-parent").show();var user_enrollment=$("#eb_setup_sync_user_enrollment").prop("checked")?1:0,user_unenrollment=$("#eb_setup_sync_user_unenrollment").prop("checked")?1:0,user_creation=$("#eb_setup_sync_user_creation").prop("checked")?1:0,user_deletion=$("#eb_setup_sync_user_deletion").prop("checked")?1:0,user_update=$("#eb_setup_sync_user_update").prop("checked")?1:0,course_creation=$("#eb_setup_sync_course_creation").prop("checked")?1:0,course_deletion=$("#eb_setup_sync_course_deletion").prop("checked")?1:0;data={current_step:current_step,next_step:next_step,is_next_sub_step:is_next_sub_step,user_enrollment:user_enrollment,user_unenrollment:user_unenrollment,user_creation:user_creation,user_deletion:user_deletion,user_update:user_update,course_creation:course_creation,course_deletion:course_deletion};break;default:$("#eb-lading-parent").show()}data=JSON.stringify(data),ajax.call([{methodname:"auth_edwiserbridge_setup_wizard_save_and_continue",args:{data:data}}])[0].done((function(response){$("#eb-lading-parent").hide(),function(step){var url=new URL(document.location);url.searchParams.set("current_step",step),window.history.replaceState(null,null,url)}(next_step);return function(current_step,next_step,is_next_sub_step,parent_step){$(".eb-setup-step-"+current_step).addClass("eb-setup-step-completed-wrap"),$(".eb-setup-step-"+current_step).hasClass("eb-setup-step-active-wrap")&&$(".eb-setup-step-"+current_step).removeClass("eb-setup-step-active-wrap");var icon,step_title=$(".eb-setup-step-"+current_step).children(".eb-setup-steps-title");step_title.addClass("eb-setup-step-completed"),step_title.hasClass("eb-setup-step-active")&&step_title.removeClass("eb-setup-step-active"),(icon=$(".eb-setup-step-"+current_step).children(".eb_setup_sidebar_progress_icons")).addClass("fa-circle-check"),icon.hasClass("fa-circle-chevron-right")&&icon.removeClass("fa-circle-chevron-right"),$(".eb-setup-step-"+next_step).addClass("eb-setup-step-active-wrap"),$(".eb-setup-step-"+next_step).children(".eb-setup-steps-title").addClass("eb-setup-step-active"),(icon=$(".eb-setup-step-"+next_step).children(".eb_setup_sidebar_progress_icons")).addClass("fa-solid fa-circle-chevron-right"),icon.hasClass("eb-setup-step-circle")&&icon.removeClass("eb-setup-step-circle")}(current_step,next_step),$(".eb-setup-header-title").html(response.title),$(".eb-setup-content").html(response.html_data),"complete_details"==next_step&&($(".eb-setup-content").append('<div class="eb_setup_popup"> '+$(".eb_setup_wp_completion_success_popup").html()+" </div>"),setTimeout((function(){$(".eb_setup_popup").remove()}),2e3)),response})).fail((function(response){return $("#eb-lading-parent").hide(),$("body").css("cursor","default"),0}))})),$(".eb_setup_wp_completion_success_popup").length&&($(".eb-setup-content").append('<div class="eb_setup_popup"> '+$(".eb_setup_wp_completion_success_popup").html()+" </div>"),setTimeout((function(){$(".eb_setup_popup").remove()}),2e3)),$(document).on("click",".eb_enable_plugin_settings",(function(event){$("#eb-lading-parent").show(),ajax.call([{methodname:"auth_edwiserbridge_enable_plugin_settings",args:{}}])[0].done((function(response){return $("body").css("cursor","default"),$("#eb-lading-parent").hide(),$(".eb_enable_rest_protocol").css("color","#1AB900"),$(".eb_enable_web_service").css("color","#1AB900"),$(".eb_disable_pwd_policy").css("color","#1AB900"),$(".eb_allow_extended_char").css("color","#1AB900"),$(".eb_setup_settings_success_msg").css("display","block"),$(".eb_enable_plugin_settings").css("display","none"),$(".eb_enable_plugin_settings_label").css("display","none"),$(".eb_setup_save_and_continue").css("display","initial"),response})).fail((function(response){return $("#eb-lading-parent").hide(),$("body").css("cursor","default"),0}))}));var i,acc=document.getElementsByClassName("accordion");for(i=0;i<acc.length;i++)acc[i].addEventListener("click",(function(){this.classList.toggle("active");var panel=this.nextElementSibling;"block"===panel.style.display?panel.style.display="none":panel.style.display="block"}));$(document).on("change",".eb_setup_web_service_list",(function(event){""!=$(".eb_setup_web_service_list").val()?($(".eb_setup_web_service_btn").removeClass("disabled"),$(".eb_setup_web_service_btn").removeAttr("disabled")):($(".eb_setup_web_service_btn").attr("disabled","disabled"),$(".eb_setup_web_service_btn").addClass("disabled")),"create"==$(".eb_setup_web_service_list").val()?$(".eb_setup_web_service_name_wrap").css("display","block"):$(".eb_setup_web_service_name_wrap").css("display","none")})),$(document).on("change",".eb_setup_wp_sites",(function(event){if(""!=$(".eb_setup_web_service_list").val()?($(".eb_setup_wp_details_btn").removeClass("disabled"),$(".eb_setup_wp_details_btn").removeAttr("disabled")):($(".eb_setup_wp_details_btn").attr("disabled","disabled"),$(".eb_setup_wp_details_btn").addClass("disabled")),""==$(".eb_setup_wp_sites").val())$(".eb_setup_wp_site_details_inp").addClass("eb_setup_wp_site_details_wrap");else{$(".eb_setup_wp_site_details_inp").removeClass("eb_setup_wp_site_details_wrap");var option=$(this).find(":selected");$(".eb_setup_site_name").val(option.data("name")),$(".eb_setup_site_url").val(option.data("url"))}})),$(document).on("click",".eb_setup_test_connection_btn",(function(event){var url=$(".eb_setup_site_url").val();$("body").css("cursor","wait"),$("#eb-lading-parent").show(),ajax.call([{methodname:"auth_edwiserbridge_setup_test_connection",args:{wp_url:url}}])[0].done((function(response){return $("#eb-lading-parent").hide(),$("body").css("cursor","default"),$(".eb_setup_test_conn_resp_msg").css("display","block"),1==response.status?($(".eb_setup_test_connection_continue_btn").css("display","inline-block"),$(".eb_setup_test_connection_btn").css("display","none"),$(".eb_setup_test_conn_resp_msg").addClass("eb_setup_settings_success_msg"),$(".eb_setup_test_conn_resp_msg").html('<i class="fa-solid fa-circle-check"></i> '+response.msg),$(".eb_setup_test_conn_resp_msg").removeClass("eb_setup_error_msg_box")):($(".eb_setup_test_conn_resp_msg").addClass("eb_setup_error_msg_box"),$(".eb_setup_test_conn_resp_msg").html('<i class="fa-solid fa-circle-check"></i> '+response.msg),$(".eb_setup_test_conn_resp_msg").removeClass("eb_setup_settings_success_msg")),response})).fail((function(response){return $("body").css("cursor","default"),$("#eb-lading-parent").hide(),0}))})),$(document).on("click","#eb_setup_sync_all",(function(event){this.checked?$(".eb_setup_sync_cb").prop("checked",!0):$(".eb_setup_sync_cb").prop("checked",!1)})),$(document).on("click",".eb_setup_sync_cb",(function(event){if(this.checked){var all_checked=1;$(".eb_setup_sync_cb").each((function(){this.checked||(all_checked=0)})),all_checked&&$("#eb_setup_sync_all").prop("checked",!0)}else $("#eb_setup_sync_all").prop("checked",!1)})),$(document).on("click",".eb_setup_copy",(function(event){event.preventDefault();var copyText=$(this).data("copy");navigator.clipboard.writeText(copyText).then((()=>{var copy_success='<p class="eb_setup_copy_success"><i class="fa fa-check" aria-hidden="true"></i> '+M.util.get_string("copied","auth_edwiserbridge")+"</p>";$(this).append(copy_success),setTimeout((()=>{$(".eb_setup_copy_success").fadeOut(300,(function(){$(this).remove()}))}),2e3)}))})),$(document).on("click",".eb_setup_download_creds",(function(event){var obj={url:$(".eb_setup_copy_url").html(),token:$(".eb_setup_copy_token").html(),lang_code:$(".eb_setup_copy_lang").html()};$("<a />",{download:"creds.json",href:"data:application/json,"+encodeURIComponent(JSON.stringify(obj))}).appendTo("body").click((function(){$(this).remove()}))[0].click()})),$(".eb-setup-close-icon").click((function(){$(".eb-setup-content").append('<div class="eb_setup_popup"> '+$(".eb_setup_popup_content_wrap").html()+" </div>")})),$(document).on("click",".eb_setup_do_not_close",(function(event){$(".eb_setup_popup").remove()})),$(document).on("change",".eb_setup_wp_sites",(function(event){var option=$(this).find(":selected");$(".eb_setup_site_name").val(option.data("name")),$(".eb_setup_site_url").val(option.data("url"))})),$(document).on("click",".eb_redirect_to_wp",(function(event){event.preventDefault();$(this);var data={current_step:$(this).data("step"),next_step:$(this).data("next-step"),is_next_sub_step:$(this).data("is-next-sub-step")};data=JSON.stringify(data),ajax.call([{methodname:"auth_edwiserbridge_setup_wizard_save_and_continue",args:{data:data}}])[0].done((function(response){return response})).fail((function(response){return 0})),$(".eb-setup-content").append('<div class="eb_setup_popup"> '+$(".eb_setup_wp_redirection_popup").html()+" </div>"),setTimeout((function(){$(".eb_setup_popup").remove(),$(".eb_redirect_to_wp_btn").trigger("click"),window.open($(".eb_redirect_to_wp").attr("href"),"_blank").focus()}),2e3)}))}))}}}));
⋮----
//# sourceMappingURL=settings.min.js.map

================
File: amd/build/settings.min.js.map
================
{"version":3,"file":"settings.min.js","sources":["../src/settings.js"],"sourcesContent":["/* eslint-disable no-unused-vars */\n// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n/**\n * Js file to handle settings.\n *\n * @package\n * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @author      Wisdmlabs\n * @module      auth_edwiserbridge/settings\n */\n\"use strict\";\ndefine(\"auth_edwiserbridge/eb_settings\", [\n    \"jquery\",\n    \"core/ajax\",\n    \"core/url\",\n    \"core/str\",\n], function($, ajax, url, str) {\n    /**\n     * Load settings.\n     */\n    function load_settings() {\n        var translation = str.get_strings([\n            { key: \"dialog_title\", component: \"auth_edwiserbridge\" },\n            { key: \"site_url\", component: \"auth_edwiserbridge\" },\n            { key: \"token\", component: \"auth_edwiserbridge\" },\n            { key: \"copy\", component: \"auth_edwiserbridge\" },\n            { key: \"copied\", component: \"auth_edwiserbridge\" },\n            { key: \"link\", component: \"auth_edwiserbridge\" },\n            { key: \"create\", component: \"auth_edwiserbridge\" },\n            { key: \"eb_empty_name_err\", component: \"auth_edwiserbridge\" },\n            { key: \"eb_empty_user_err\", component: \"auth_edwiserbridge\" },\n            { key: \"eb_service_select_err\", component: \"auth_edwiserbridge\" },\n            { key: \"click_to_copy\", component: \"auth_edwiserbridge\" },\n            { key: \"pop_up_info\", component: \"auth_edwiserbridge\" },\n            { key: \"eb_settings_msg\", component: \"auth_edwiserbridge\" },\n            { key: \"click_here\", component: \"auth_edwiserbridge\" },\n        ]);\n\n        $(document).ready(function () {\n\n            $(document).on('click', '.eb_test_connection_log_open', function (event) {\n                $('.eb_test_connection_log_open').addClass('eb_test_connection_log_close');\n                $('.eb_test_connection_log_close').removeClass('eb_test_connection_log_open');\n                $(\".eb_test_connection_log\").slideDown();\n            });\n\n            $(document).on('click', '.eb_test_connection_log_close', function (event) {\n                $('.eb_test_connection_log_close').addClass('eb_test_connection_log_open');\n                $('.eb_test_connection_log_open').removeClass('eb_test_connection_log_close');\n                $(\".eb_test_connection_log\").slideUp();\n            });\n\n            /**\n             * Check if all the services are enabled.\n             * @param {string} service_id\n             * @param {boolean} messge_ele\n            */\n            function checkMissingServices(service_id, messge_ele = false) {\n                var promises = ajax.call([{\n                    methodname: \"auth_edwiserbridge_get_service_info\",\n                    args: { service_id: service_id },\n                }, ]);\n\n                promises[0]\n                    .done(function(response) {\n                        var message = \"\";\n                        $(\"body\").css(\"cursor\", \"default\");\n                        if (!response.status) {\n                            $(\".eb_summary_tab\").removeClass(\"summary_tab_sucess\");\n                            $(\".eb_summary_tab\").addClass(\"summary_tab_error\");\n                            if (!messge_ele) {\n                                $(\"#eb_common_err\").text(response.msg);\n                                $(\"#eb_common_err\").css(\"display\", \"block\");\n                            } else if (messge_ele) {\n                                var link =\n                                    window.location.origin +\n                                    window.location.pathname +\n                                    \"?tab=service\";\n                                var fix_link =\n                                    M.util.get_string(\n                                        \"more_details\",\n                                        \"auth_edwiserbridge\"\n                                    )\n                                    + \" <a href='\" +\n                                    link +\n                                    \"'  target='_blank'>\" + M.util.get_string(\"here\", \"auth_edwiserbridge\") + \"</a>.\";\n                                message =\n                                    \"<span class='summ_error'>\" +\n                                    response.msg +\n                                    fix_link +\n                                    \"</span>\";\n                                $(messge_ele).empty().append(message);\n                            }\n                        } else {\n                            if ($(\"#web_service_status span\").hasClass(\"summ_error\")) {\n                                $(\".eb_summary_tab\").removeClass(\"summary_tab_sucess\");\n                                $(\".eb_summary_tab\").addClass(\"summary_tab_error\");\n                            } else {\n                                $(\".eb_summary_tab\").addClass(\"summary_tab_sucess\");\n                                $(\".eb_summary_tab\").removeClass(\"summary_tab_error\");\n                            }\n                            if (messge_ele) {\n                                message =\n                                    '<span style=\"color: #7ad03a;\">' +\n                                        '<span class=\"summ_success\" style=\"font-weight:bolder;color:#7ad03a;font-size:22px;\">' +\n                                            '&#10003;' +\n                                        '</span>' +\n                                    '</span>';\n                                $(messge_ele).empty().append(message);\n                            }\n                        }\n                        return response;\n                    })\n                    .fail(function(response) {\n                        $(\"body\").css(\"cursor\", \"default\");\n                        return 0;\n                    });\n            }\n\n            /**\n             * Check the connection status with WordPress site\n             * @param {boolean|Element} messge_ele - Optional element to display messages\n             */\n            function checkConnectionstatus(messge_ele = false) {\n                var wp_url = $(\"#eb_wp_url\").text();\n                var wp_token = $(\"#eb_wp_token\").text();\n                var promises = ajax.call([\n                    { methodname: 'auth_edwiserbridge_test_connection', args: { wp_url: wp_url, wp_token: wp_token } }\n                ]);\n\n                promises[0]\n                    .done(function(response) {\n                        var message = \"\";\n                        $(\"body\").css(\"cursor\", \"default\");\n                        if (response.status == \"0\") {\n                            $(\".eb_summary_tab\").removeClass(\"summary_tab_sucess\");\n                            $(\".eb_summary_tab\").addClass(\"summary_tab_error\");\n                            if (!messge_ele) {\n                                $(\"#eb_common_err\").text(response.msg);\n                                $(\"#eb_common_err\").css(\"display\", \"block\");\n                            } else if (messge_ele) {\n                                var link = window.location.origin + window.location.pathname + \"?tab=connection\";\n                                var fix_link = \" Check more detials <a href='\" + link + \"'  target='_blank'>here</a>.\";\n                                message = \"<span class='summ_error'>\" + response.msg + fix_link + \"</span>\";\n                                $(messge_ele).empty().append(message);\n                            }\n                        } else {\n                            if ($(\"#test_connection_status span\").hasClass(\"summ_error\")) {\n                                $(\".eb_summary_tab\").removeClass(\"summary_tab_sucess\");\n                                $(\".eb_summary_tab\").addClass(\"summary_tab_error\");\n                            } else {\n                                $(\".eb_summary_tab\").addClass(\"summary_tab_sucess\");\n                                $(\".eb_summary_tab\").removeClass(\"summary_tab_error\");\n                            }\n                            if (messge_ele) {\n                                message = '<span style=\"color: #7ad03a;\">' +\n                                    '<span class=\"summ_success\" style=\"font-weight: bolder; color: #7ad03a; font-size: 22px;\">' +\n                                    '&#10003; ' + response.msg +\n                                    '</span></span>';\n                                $(messge_ele).empty().append(message);\n                            }\n                        }\n                        return response;\n                    })\n                    .fail(function(response) {\n                        $(\"body\").css(\"cursor\", \"default\");\n                        return 0;\n                    });\n            }\n\n            /**\n             * Check if the user is on edwiser bridge settings page.\n             */\n            if (window.location.href.indexOf(\"edwiserbridge.php\") > 1) {\n                let searchParams = new URLSearchParams(window.location.search);\n                if (searchParams.has(\"tab\") && \"service\" === searchParams.get(\"tab\")) {\n                    var service_id = $(\"#id_eb_sevice_list\").val();\n                    if (\"\" != service_id && \"create\" != service_id) {\n                        checkMissingServices(service_id);\n                    }\n                } else if (searchParams.has(\"tab\") && \"summary\" === searchParams.get(\"tab\")) {\n                    var service_id = $(\"#web_service_status\").data(\"serviceid\");\n                    checkMissingServices(service_id, \"#web_service_status\");\n                    checkConnectionstatus(\"#test_connection_status\");\n                }\n            }\n\n            /*\n             * Functionality to show only tokens which are asscoiated with the service.\n             */\n            $(\"#id_eb_sevice_list\").change(function() {\n                var service_id = $(this).val();\n                $(\"#eb_common_success\").css(\"display\", \"none\");\n                $(\"#eb_common_err\").css(\"display\", \"none\");\n\n                $(\"#id_eb_token option:selected\").removeAttr(\"selected\");\n\n                $('#id_eb_token option[value=\"\"]').attr(\"selected\", true);\n\n                handlefieldsdisplay(\n                    \"create\",\n                    service_id,\n                    \".eb_service_field\",\n                    \"#id_eb_mform_create_service\"\n                );\n\n                if ($(this).val() != \"\") {\n                    $(\"#id_eb_token\").children(\"option\").hide();\n                    $(\"#id_eb_token\")\n                        .children(\"option[data-id^=\" + $(this).val() + \"]\")\n                        .show();\n\n                    if ($(this).val() != \"create\") {\n                        $(\"body\").css(\"cursor\", \"progress\");\n                        checkMissingServices(service_id);\n                    }\n                }\n            });\n\n            /*****************    Change Form Action URL   *******************/\n\n            $(\"#service_submit_continue\").click(function() {\n                $(this)\n                    .closest(\"form\")\n                    .attr(\n                        \"action\",\n                        M.cfg.wwwroot +\n                        \"/auth/edwiserbridge/edwiserbridge.php?tab=connection\"\n                    );\n            });\n\n            $(\"#conne_submit_continue\").click(function() {\n                $(this)\n                    .closest(\"form\")\n                    .attr(\n                        \"action\",\n                        M.cfg.wwwroot +\n                        \"/auth/edwiserbridge/edwiserbridge.php?tab=synchronization\"\n                    );\n            });\n\n            $(\"#sync_submit_continue\").click(function() {\n                $(this)\n                    .closest(\"form\")\n                    .attr(\n                        \"action\",\n                        M.cfg.wwwroot + \"/auth/edwiserbridge/edwiserbridge.php?tab=sso\"\n                    );\n            });\n            $(\"#sso_submit_continue\").click(function() {\n                $(this)\n                    .closest(\"form\")\n                    .attr(\n                        \"action\",\n                        M.cfg.wwwroot + \"/auth/edwiserbridge/edwiserbridge.php?tab=summary\"\n                    );\n            });\n\n            $(\"#settings_submit_continue\").click(function() {\n                $(this)\n                    .closest(\"form\")\n                    .attr(\n                        \"action\",\n                        M.cfg.wwwroot + \"/auth/edwiserbridge/edwiserbridge.php?tab=service\"\n                    );\n            });\n\n            /*********** END *********/\n            // Add Settings field.\n            if (!$(\".eb_settings_btn_cont\").length) {\n                $(\"#admin-eb_setup_wizard_field\").before(\n                    '<div class=\"eb_settings_btn_cont\" style=\"padding: 30px;\"> ' +\n                    M.util.get_string(\"eb_settings_msg\", \"auth_edwiserbridge\") +\n                    ' <a target=\"_blank\" style=\"border-radius:4px;margin-left:5px;padding:7px 18px;\" ' +\n                        'class=\"eb_settings_btn btn btn-primary\" href=\"' +\n                    M.cfg.wwwroot +\n                    '/auth/edwiserbridge/setup_wizard.php\"> ' +\n                    M.util.get_string(\"click_here\", \"auth_edwiserbridge\") +\n                    \" </a></div>\"\n                );\n            }\n            $(\"#admin-eb_setup_wizard_field\").css(\"display\", \"none\");\n\n            //Adds the link and create button on the set-up wizard\n            if ($(\"#admin-ebnewserviceuserselect\").length) {\n                if (!$(\"#eb_create_service\").length) {\n                    $(\"#admin-ebnewserviceuserselect\").after(\n                        '<div class=\"row eb_create_service_wrap\">' +\n                        '  <div class=\"offset-sm-3 col-sm-3\">' +\n                        '    <button type=\"submit\" id=\"eb_create_service\" class=\"btn\">' +\n                        M.util.get_string(\"link\", \"auth_edwiserbridge\") +\n                        \"</button>\" +\n                        \"  </div>\" +\n                        \"</div>\"\n                    );\n                }\n            }\n\n            //This adds the error succes messages divs on the set-up wizard.\n            if ($(\".eb_create_service_wrap\").length) {\n                $(\".eb_create_service_wrap\").before(\n                    '<div class=\"row eb_common_err_wrap\">' +\n                    '  <div class=\"offset-sm-3 col-sm-3\">' +\n                    '    <span id=\"eb_common_err\" class=\"btn\"></span>' +\n                    '    <span id=\"eb_common_success\" class=\"btn\"></span>' +\n                    \"  </div>\" +\n                    \"</div>\"\n                );\n            }\n\n            $(\"#id_eb_mform_create_service\").click(function(event) {\n                event.preventDefault();\n                var error = 0;\n                var web_service_name = $(\"#id_eb_service_inp\").val();\n                var user_id = $(\"#id_eb_auth_users_list\").val();\n                var service_id = $(\"#id_eb_sevice_list\").val();\n                var token = $(\"#id_eb_token\").val();\n\n                $(\".eb_settings_err\").remove();\n                $(\"#eb_common_success\").css(\"display\", \"none\");\n                $(\"#eb_common_err\").css(\"display\", \"none\");\n\n                if (user_id == \"\") {\n                    $(\"#eb_common_err\").text(\n                        M.util.get_string(\"eb_empty_user_err\", \"auth_edwiserbridge\")\n                    );\n                    $(\"#eb_common_err\").css(\"display\", \"block\");\n                    error = 1;\n                }\n\n                //If the select box has a value to create the web service the create web service else\n                if (service_id == \"create\") {\n                    if (web_service_name == \"\") {\n                        $(\"#eb_common_err\").css(\"display\", \"block\");\n                        $(\"#eb_common_err\").text(\n                            M.util.get_string(\"eb_empty_name_err\", \"auth_edwiserbridge\")\n                        );\n                        error = 1;\n                    }\n\n                    if (error) {\n                        return;\n                    }\n\n                    create_web_service(\n                        web_service_name,\n                        user_id,\n                        \"#id_eb_sevice_list\",\n                        \"#eb_common_err\",\n                        1\n                    );\n                } else {\n                    if ($(\"#id_eb_token\").val() == \"\") {\n                        $(\"#eb_common_err\").css(\"display\", \"block\");\n                        $(\"#eb_common_err\").text(\n                            M.util.get_string(\"token_empty\", \"auth_edwiserbridge\")\n                        );\n                        error = 1;\n                        return 0;\n                    }\n\n                    if (error) {\n                        return;\n                    }\n\n                    //If select has selected existing web service\n                    if (service_id != \"\") {\n                        link_web_service(\n                            service_id,\n                            token,\n                            \"#eb_common_err\",\n                            \"#eb_common_success\"\n                        );\n                    } else {\n                        //If the select box has been selected with the placeholder\n                        $(\"#eb_common_err\").text(\n                            M.util.get_string(\"eb_service_select_err\", \"auth_edwiserbridge\")\n                        );\n                    }\n                }\n            }); // event end\n\n            /************************ Web service creation click handlers *******************************/\n\n            /* -------------------------------------------\n             *  Copy to clipboard functionality handler\n             *---------------------------------------*/\n\n            /**\n             * This shows the copy test on the side\n             */\n            $(document).on(\"mouseenter\", \".eb_copy_text_wrap\", function() {\n                // hover starts code here\n                var parent = $(this).find(\".eb_copy_btn\");\n                parent.css(\"visibility\", \"visible\");\n            });\n\n            $(document).on(\"mouseleave\", \".eb_copy_text_wrap\", function() {\n                // hover ends code here\n                var parent = $(this).find(\".eb_copy_btn\");\n                parent.css(\"visibility\", \"hidden\");\n            });\n\n            /**\n             * Copy to clipboard functionality.\n             */\n            $(document).on(\"click\", \".eb_copy_text_wrap\", function(event) {\n                event.preventDefault();\n\n                var copyText = $(this).find(\".eb_copy_text\").html().trim();\n                navigator.clipboard.writeText(copyText).then(() => {\n                    toaster(M.util.get_string('copied', 'auth_edwiserbridge'), 400);\n                });\n            });\n\n            $(document).on(\"click\", \".eb_primary_copy_btn\", function(event) {\n                event.preventDefault();\n\n                var parent = $(this).parent().parent();\n\n                parent = parent.find(\".eb_copy\");\n\n                if (parent.attr(\"id\") == \"id_eb_token\") {\n                    var copyText = parent.val().trim();\n                } else {\n                    var copyText = parent.text().trim();\n                }\n\n                navigator.clipboard.writeText(copyText)\n                .then(() => {\n                    toaster(M.util.get_string('copied', 'auth_edwiserbridge'), 200);\n                });\n            });\n\n            /*************   Copy to clipboard functionality handler  **************/\n\n            /*----------------------------------------------------\n             * Below are alll js functions\n             *---------------------------------------------------*/\n\n            /**\n             * Toatser adde to show the successful copy message.\n             * @param {string} title\n             * @param {int} time\n             */\n            function toaster(title, time = 2000) {\n                const id = \"auth_edwiserbridge_copy\";\n                const toast = $(\n                    '<div id=\"' +\n                    id +\n                    '\">' +\n                    M.util.get_string(\"copied\", \"auth_edwiserbridge\") +\n                    \"<div>\"\n                ).get(0);\n                document.querySelector(\"body\").appendChild(toast);\n                toast.classList.add(\"show\");\n                setTimeout(function() {\n                    toast.classList.add(\"fade\");\n                    setTimeout(function() {\n                        toast.classList.remove(\"fade\");\n                        setTimeout(function() {\n                            toast.remove();\n                        }, time);\n                    }, time);\n                });\n            }\n\n            /**\n             * This function adds newly created web service in the drop down\n             * @param {string} element\n             * @param {string} name\n             * @param {string} id\n             */\n            function add_new_service_in_select(element, name, id) {\n                $(element + \"option:selected\").removeAttr(\"selected\");\n                $(element).append(\n                    '<option value=\"' + id + '\" selected> ' + name + \" </option>\"\n                );\n            }\n\n            /**\n             * This function adds newly created web service in the drop down\n             * @param {string} element\n             * @param {string} token\n             * @param {string} id\n             */\n            function add_new_token_in_select(element, token, id) {\n                $(element + \"option:selected\").removeAttr(\"selected\");\n                $(element).append(\n                    '<option data-id=\"' +\n                    id +\n                    '\" value=\"' +\n                    token +\n                    '\" selected> ' +\n                    token +\n                    \" </option>\"\n                );\n            }\n\n            /**\n             * This function handles the display of the service creation form depending on the drop down value.\n             * @param {string} condition\n             * @param {string} condition_var\n             * @param {string} element\n             * @param {string} btn\n             */\n            function handlefieldsdisplay(\n                condition,\n                condition_var,\n                element,\n                btn = \"\"\n            ) {\n                if (condition == condition_var) {\n                    $(btn).text(M.util.get_string(\"create\", \"auth_edwiserbridge\"));\n                    $(element).css(\"display\", \"flex\");\n                } else {\n                    $(btn).text(M.util.get_string(\"link\", \"auth_edwiserbridge\"));\n                    $(element).css(\"display\", \"none\");\n                }\n            }\n\n            /**\n             * This functions link the existing wervices\n             * @param {string} service_id\n             * @param {string} token\n             * @param {string} common_errr_fld\n             * @param {string} common_success_fld\n             */\n            function link_web_service(\n                service_id,\n                token,\n                common_errr_fld,\n                common_success_fld\n            ) {\n                $(\"body\").css(\"cursor\", \"progress\");\n                $(\"#eb_common_err\").css(\"display\", \"none\");\n\n                var promises = ajax.call([{\n                    methodname: \"auth_edwiserbridge_link_service\",\n                    args: { service_id: service_id, token: token },\n                }, ]);\n\n                promises[0]\n                    .done(function(response) {\n                        $(\"body\").css(\"cursor\", \"default\");\n                        if (response.status) {\n                            $(common_success_fld).text(response.msg);\n                            $(common_success_fld).css(\"display\", \"block\");\n                        } else {\n                            $(common_errr_fld).text(response.msg);\n                            $(common_success_fld).css(\"display\", \"block\");\n                        }\n\n                        return response;\n                    })\n                    .fail(function(response) {\n                        $(\"body\").css(\"cursor\", \"default\");\n                        return 0;\n                    }); //promise end\n            }\n\n            $(document).on(\"click\", \".eb_service_pop_up_close\", function() {\n                $(\".eb_service_pop_up\").hide();\n            });\n\n            /**\n             * This functions regiters new web service.\n             * @param {string} web_service_name\n             * @param {string} user_id\n             * @param {string} service_select_fld\n             * @param {string} common_errr_fld\n             * @param {boolean} is_mform\n             */\n            function create_web_service(\n                web_service_name,\n                user_id,\n                service_select_fld,\n                common_errr_fld,\n                is_mform\n            ) {\n                $(\"body\").css(\"cursor\", \"progress\");\n                $(\"#eb_common_err\").css(\"display\", \"none\");\n\n                $(\"#id_eb_token option:selected\").removeAttr(\"selected\");\n\n                $('#id_eb_token option[value=\"\"]').attr(\"selected\", true);\n\n                var promises = ajax.call([{\n                    methodname: \"auth_edwiserbridge_create_service\",\n                    args: { web_service_name: web_service_name, user_id: user_id },\n                }, ]);\n\n                var validation_error = 0;\n\n                if (!validation_error) {\n                    promises[0]\n                        .done(function(response) {\n                            $(\"body\").css(\"cursor\", \"default\");\n                            if (response.status) {\n                                //Dialog box content.\n                                var eb_dialog_content =\n                                    \"<div> \" +\n                                    M.util.get_string(\"pop_up_info\", \"auth_edwiserbridge\") +\n                                    \" </div>\" +\n                                    '<table class=\"eb_toke_detail_tbl\">' +\n                                    \"  <tr>\" +\n                                    '     <th width=\"17%\">' +\n                                    M.util.get_string(\"site_url\", \"auth_edwiserbridge\") +\n                                    \"</th>\" +\n                                    '     <td> : <span class=\"eb_copy_text\" title=\"' +\n                                    M.util.get_string(\"click_to_copy\", \"auth_edwiserbridge\") +\n                                    '\">' +\n                                    response.site_url +\n                                    \"</span>\" +\n                                    '        <span class=\"eb_copy_btn\">' +\n                                    M.util.get_string(\"copy\", \"auth_edwiserbridge\") +\n                                    \"</span></td>\" +\n                                    \"  </tr>\" +\n                                    \"  <tr>\" +\n                                    '     <th width=\"17%\">' +\n                                    M.util.get_string(\"token\", \"auth_edwiserbridge\") +\n                                    \"</th>\" +\n                                    '     <td> : <span class=\"eb_copy_text\" title=\"' +\n                                    M.util.get_string(\"click_to_copy\", \"auth_edwiserbridge\") +\n                                    '\">' +\n                                    response.token +\n                                    \"</span>\" +\n                                    '        <span class=\"eb_copy_btn\">' +\n                                    M.util.get_string(\"copy\", \"auth_edwiserbridge\") +\n                                    \"</span></td>\" +\n                                    \"  </tr>\" +\n                                    \"</table>\";\n\n                                $(\"body\").append(\n                                    '<div class=\"eb_service_pop_up_cont\">' +\n                                    '<div class=\"eb_service_pop_up\">' +\n                                    '<span class=\"helper\"></span>' +\n                                    \"<div>\" +\n                                    '<div class=\"eb_service_pop_up_close\">&times;</div>' +\n                                    \"<div>\" +\n                                    '<div class=\"eb_service_pop_up_title\"></div>' +\n                                    '<div class=\"eb_service_pop_up_content\"></div>' +\n                                    \"</div>\" +\n                                    \"</div>\" +\n                                    \"</div>\" +\n                                    \"</div>\"\n                                );\n\n                                $(\".eb_service_pop_up_content\").html(eb_dialog_content);\n                                $(\".eb_service_pop_up\").show();\n\n                                add_new_service_in_select(\n                                    service_select_fld,\n                                    web_service_name,\n                                    response.service_id\n                                );\n                                add_new_token_in_select(\n                                    \"#id_eb_token\",\n                                    response.token,\n                                    response.service_id\n                                );\n                            } else {\n                                $(\"#eb_common_err\").css(\"display\", \"block\");\n                                $(common_errr_fld).text(response.msg);\n                            }\n\n                            return response;\n                        })\n                        .fail(function(response) {\n                            $(\"body\").css(\"cursor\", \"default\");\n                            return 0;\n                        }); //promise end\n                }\n            }\n\n            /************************  Functions END  ****************************/\n\n\n\n\n\n            /******************    SETUP wizard   *****************/\n\n            var loader = '<div id=\"eb-lading-parent\" class=\"eb-lading-parent-wrap\">' +\n                '<div class=\"eb-loader-progsessing-anim\"></div>' +\n            '</div>';\n            $(\"body\").append(loader);\n\n\n            /**\n             * Change URL.\n             * @param {string} step\n             */\n            function change_url( step ) {\n                var url = new URL(document.location);\n                url.searchParams.set('current_step', step);\n                window.history.replaceState( null, null, url );\n            }\n\n            /**\n             * Handle step progress.\n             * @param {string} current_step\n             * @param {string} next_step\n             * @param {string} is_next_sub_step\n             * @param {string} parent_step\n             */\n            function handle_step_progress( current_step, next_step, is_next_sub_step, parent_step ) {\n                /**\n                 * 1. Mark current step as active and\n                 * 2. Mark previous step as completed.\n                 */\n                // Add completed class to the sidebar steps\n                var temp1 = $('.eb-setup-step-' + current_step).addClass('eb-setup-step-completed-wrap');\n                if( $('.eb-setup-step-' + current_step).hasClass('eb-setup-step-active-wrap') ) {\n                    $('.eb-setup-step-' + current_step).removeClass('eb-setup-step-active-wrap');\n                }\n\n                // Chnage step names class\n                var step_title = $('.eb-setup-step-' + current_step).children('.eb-setup-steps-title');\n                step_title.addClass('eb-setup-step-completed');\n                if(step_title.hasClass('eb-setup-step-active')){\n                    step_title.removeClass('eb-setup-step-active');\n                }\n\n                // Change icons class\n                var icon = $('.eb-setup-step-' + current_step).children('.eb_setup_sidebar_progress_icons');\n                icon.addClass('fa-circle-check');\n\n                if( icon.hasClass('fa-circle-chevron-right') ) {\n                    icon.removeClass('fa-circle-chevron-right');\n                }\n\n\n                var temp2 = $('.eb-setup-step-' + next_step).addClass('eb-setup-step-active-wrap');\n                var step_title1 = $('.eb-setup-step-' + next_step).children('.eb-setup-steps-title');\n                step_title1.addClass('eb-setup-step-active');\n\n                var icon = $('.eb-setup-step-' + next_step).children('.eb_setup_sidebar_progress_icons');\n                icon.addClass('fa-solid fa-circle-chevron-right');\n\n                if(icon.hasClass('eb-setup-step-circle')){\n                    icon.removeClass('eb-setup-step-circle');\n                }\n\n            }\n\n            // ajax xall to save data and get new tab at the same time.\n\n            // Clicking save continue\n            //\n            $(document).on('click', '.eb_setup_save_and_continue', function (event) {\n                // Create loader.\n                var current = $(this);\n                var current_step = $(this).data('step');\n                var next_step = $(this).data('next-step');\n                var is_next_sub_step = $(this).data('is-next-sub-step');\n\n\n\n                // get current step.\n                // get next step.\n                // get data which will be saved.\n                // Creating swicth case.\n                var data = { current_step : current_step, next_step : next_step, is_next_sub_step : is_next_sub_step };\n\n                switch ( current_step ) {\n                    case 'installtion_guide':\n                        $(\"#eb-lading-parent\").show();\n\n                        // Get required data and create array\n                        data = { current_step : current_step, next_step : next_step, is_next_sub_step : is_next_sub_step };\n\n                        break;\n\n                    case 'mdl_plugin_config':\n                        $(\"#eb-lading-parent\").show();\n\n                        data = { current_step : current_step, next_step : next_step, is_next_sub_step : is_next_sub_step };\n\n                        break;\n\n                    case 'web_service':\n                        var service_name = $('.eb_setup_web_service_list').val();\n\n                        // Course sync process.\n                        // Call course sync callback and after completing the process, call this callback.\n                        if( service_name == 'create' && '' == $('#eb_setup_web_service_name').val() ){\n                            event.preventDefault();\n                            $('#eb_setup_web_service_name').css('border-color', 'red');\n                            return;\n\n                        } else {\n                            $(\"#eb-lading-parent\").show();\n\n                            var existing_service = 1;\n\n                            if ( service_name == 'create' && service_name != '' ) {\n                                service_name = $('.eb_setup_web_service_name').val();\n                                existing_service = 0;\n                            }\n\n                            data = {\n                                current_step : current_step,\n                                next_step : next_step,\n                                is_next_sub_step : is_next_sub_step,\n                                service_name : service_name,\n                                existing_service : existing_service\n                            };\n                        }\n                        break;\n\n\n                    case 'wordpress_site_details':\n\n                        if( '' != site_name && ( '' == $('#eb_setup_site_name').val() || '' == $('#eb_setup_site_url').val() ) ){\n                            event.preventDefault();\n\n                            if ( '' == $('#eb_setup_site_name').val() ) {\n                                $('#eb_setup_site_name').css('border-color', 'red');\n                            } else {\n                                $('#eb_setup_site_name').css('border-color', '#E5E5E5');\n                            }\n\n                            if ( '' == $('#eb_setup_site_url').val() ) {\n                                $('#eb_setup_site_url').css('border-color', 'red');\n                            } else {\n                                $('#eb_setup_site_url').css('border-color', '#E5E5E5');\n                            }\n\n                            return;\n                        } else {\n                            $(\"#eb-lading-parent\").show();\n\n                            // Course sync process.\n                            // Call course sync callback and after completing the process, call this callback.\n\n                            var site_name = $('.eb_setup_wp_sites').val();\n                            var url       = '';\n\n                            if ( '' != site_name ) {\n                                site_name = $('.eb_setup_site_name').val();\n                                url       = $('.eb_setup_site_url').val();\n                            }\n\n                            data = {\n                                current_step : current_step,\n                                next_step : next_step,\n                                is_next_sub_step : is_next_sub_step,\n                                site_name : site_name,\n                                url : url\n                            };\n                        }\n\n                        break;\n\n\n                    case 'user_and_course_sync':\n                        $(\"#eb-lading-parent\").show();\n\n                        var user_enrollment   = $('#eb_setup_sync_user_enrollment').prop('checked') ? 1 : 0;\n                        var user_unenrollment = $('#eb_setup_sync_user_unenrollment').prop('checked') ? 1 : 0;\n                        var user_creation     = $('#eb_setup_sync_user_creation').prop('checked') ? 1 : 0;\n                        var user_deletion     = $('#eb_setup_sync_user_deletion').prop('checked') ? 1 : 0;\n                        var user_update       = $('#eb_setup_sync_user_update').prop('checked') ? 1 : 0;\n                        var course_creation   = $('#eb_setup_sync_course_creation').prop('checked') ? 1 : 0;\n                        var course_deletion   = $('#eb_setup_sync_course_deletion').prop('checked') ? 1 : 0;\n\n\n\n                        // If user checkbox is clicked start user sync otherwise just procedd to next screen.\n                        data = {\n                            current_step : current_step,\n                            next_step : next_step,\n                            is_next_sub_step : is_next_sub_step,\n                            user_enrollment: user_enrollment,\n                            user_unenrollment: user_unenrollment,\n                            user_creation: user_creation,\n                            user_deletion: user_deletion,\n                            user_update: user_update,\n                            course_creation: course_creation,\n                            course_deletion: course_deletion\n                        };\n\n                        break;\n\n\n                    default:\n                        $(\"#eb-lading-parent\").show();\n\n                        break;\n                }\n                data = JSON.stringify(data);\n\n\n                var promises = ajax.call([{\n                    methodname: \"auth_edwiserbridge_setup_wizard_save_and_continue\",\n                    args: { data : data },\n                }, ]);\n\n                promises[0].done(function(response) {\n                    $(\"#eb-lading-parent\").hide();\n\n                    change_url( next_step );\n\n\n                    // Dummy value.\n                    var parent_step = 1;\n\n                    handle_step_progress( current_step, next_step, is_next_sub_step, parent_step );\n\n                    $('.eb-setup-header-title').html(response.title);\n                    $('.eb-setup-content').html(response.html_data);\n\n\n                    if ( 'complete_details' == next_step ) {\n                        $('.eb-setup-content').append(\n                            '<div class=\"eb_setup_popup\"> ' +\n                            $('.eb_setup_wp_completion_success_popup').html() +\n                            ' </div>'\n                        );\n\n\n                        setTimeout(function(){\n                            $('.eb_setup_popup').remove();\n                        }, 2000);\n                    }\n\n\n                    return response;\n                }).fail(function(response) {\n                    $(\"#eb-lading-parent\").hide();\n                    $(\"body\").css(\"cursor\", \"default\");\n                    return 0;\n                }); //promise end\n\n\n            });\n\n\n\n            // Adding for refresh page condition\n            if ( $(\".eb_setup_wp_completion_success_popup\").length) {\n                $('.eb-setup-content').append(\n                    '<div class=\"eb_setup_popup\"> ' +\n                    $('.eb_setup_wp_completion_success_popup').html() +\n                    ' </div>');\n\n                setTimeout(function(){\n                    $('.eb_setup_popup').remove();\n                }, 2000);\n            }\n\n\n\n\n\n            /*\n            * Ajax call to enable settings.\n            */\n            $(document).on('click', '.eb_enable_plugin_settings', function (event) {\n                // start loader\n                $(\"#eb-lading-parent\").show();\n\n                var promises = ajax.call([{\n                    methodname: 'auth_edwiserbridge_enable_plugin_settings',\n                    args: {},\n                }, ]);\n\n                promises[0].done(function(response) {\n                    $(\"body\").css(\"cursor\", \"default\");\n                    $(\"#eb-lading-parent\").hide();\n\n                    // stop loader.\n                    // change icon colors\n                    $('.eb_enable_rest_protocol').css( 'color', '#1AB900' );\n                    $('.eb_enable_web_service').css( 'color', '#1AB900' );\n                    $('.eb_disable_pwd_policy').css( 'color', '#1AB900' );\n                    $('.eb_allow_extended_char').css( 'color', '#1AB900' );\n\n                    // show success message.\n                    $('.eb_setup_settings_success_msg').css( 'display', 'block' );\n\n\n                    // Hide current button and show save and continue button\n                    $('.eb_enable_plugin_settings').css( 'display', 'none' );\n                    $('.eb_enable_plugin_settings_label').css( 'display', 'none' );\n                    $('.eb_setup_save_and_continue').css( 'display', 'initial' );\n\n                    return response;\n                }).fail(function(response) {\n                    $(\"#eb-lading-parent\").hide();\n\n                    $(\"body\").css(\"cursor\", \"default\");\n                    return 0;\n                }); //promise end\n\n\n            });\n\n\n\n            var acc = document.getElementsByClassName(\"accordion\");\n            var i;\n\n            for (i = 0; i < acc.length; i++) {\n              acc[i].addEventListener(\"click\", function() {\n                /* Toggle between adding and removing the \"active\" class,\n                to highlight the button that controls the panel */\n                this.classList.toggle(\"active\");\n\n                /* Toggle between hiding and showing the active panel */\n                var panel = this.nextElementSibling;\n                if (panel.style.display === \"block\") {\n                  panel.style.display = \"none\";\n                } else {\n                  panel.style.display = \"block\";\n                }\n              });\n            }\n\n\n\n            // Handle Setup web service dropdown.\n            // $(\".eb_setup_web_service_list\").change(function() {\n            $(document).on('change', '.eb_setup_web_service_list', function (event) {\n\n                if('' != $(\".eb_setup_web_service_list\").val()){\n                    $('.eb_setup_web_service_btn').removeClass('disabled');\n                    $('.eb_setup_web_service_btn').removeAttr(\"disabled\");\n                } else {\n                    $('.eb_setup_web_service_btn').attr(\"disabled\", \"disabled\");\n                    $('.eb_setup_web_service_btn').addClass('disabled');\n                }\n\n\n                if('create' == $(\".eb_setup_web_service_list\").val()){\n                    $('.eb_setup_web_service_name_wrap').css('display', 'block');\n                } else {\n                    $('.eb_setup_web_service_name_wrap').css('display', 'none');\n                }\n            });\n\n\n            // Handle Wp site drop down\n            // $(\".eb_setup_wp_sites\").change(function() {\n            $(document).on('change', '.eb_setup_wp_sites', function (event) {\n\n                if('' != $(\".eb_setup_web_service_list\").val()){\n                    $('.eb_setup_wp_details_btn').removeClass('disabled');\n                    $('.eb_setup_wp_details_btn').removeAttr(\"disabled\");\n                } else {\n                    $('.eb_setup_wp_details_btn').attr(\"disabled\", \"disabled\");\n                    $('.eb_setup_wp_details_btn').addClass('disabled');\n                }\n\n                if('' == $(\".eb_setup_wp_sites\").val()){\n                    $('.eb_setup_wp_site_details_inp').addClass('eb_setup_wp_site_details_wrap');\n                } else {\n                    $('.eb_setup_wp_site_details_inp').removeClass('eb_setup_wp_site_details_wrap');\n\n                    var option = $(this).find(\":selected\");\n\n                    $('.eb_setup_site_name').val(option.data('name'));\n                    $('.eb_setup_site_url').val(option.data('url'));\n                }\n            });\n\n\n\n\n            $(document).on('click', '.eb_setup_test_connection_btn', function (event) {\n\n                var url = $('.eb_setup_site_url').val();\n                $(\"body\").css(\"cursor\", \"wait\");\n\n                $(\"#eb-lading-parent\").show();\n\n\n                var promises = ajax.call([{\n                    methodname: 'auth_edwiserbridge_setup_test_connection',\n                    args: { wp_url: url },\n                }, ]);\n\n                promises[0].done(function(response) {\n                    $(\"#eb-lading-parent\").hide();\n                    $(\"body\").css(\"cursor\", \"default\");\n\n\n                    $('.eb_setup_test_conn_resp_msg').css('display', 'block');\n\n                    // Parse response.\n                    if(response.status == 1){\n                        $('.eb_setup_test_connection_continue_btn').css('display', 'inline-block');\n                        $('.eb_setup_test_connection_btn').css('display', 'none');\n\n                        $('.eb_setup_test_conn_resp_msg').addClass('eb_setup_settings_success_msg');\n                        $('.eb_setup_test_conn_resp_msg').html('<i class=\"fa-solid fa-circle-check\"></i> ' + response.msg);\n                        $('.eb_setup_test_conn_resp_msg').removeClass('eb_setup_error_msg_box');\n                    }else{\n                        $('.eb_setup_test_conn_resp_msg').addClass('eb_setup_error_msg_box');\n                        $('.eb_setup_test_conn_resp_msg').html('<i class=\"fa-solid fa-circle-check\"></i> ' + response.msg);\n                        $('.eb_setup_test_conn_resp_msg').removeClass('eb_setup_settings_success_msg');\n                    }\n\n                    return response;\n                }).fail(function(response) {\n                    $(\"body\").css(\"cursor\", \"default\");\n                    $(\"#eb-lading-parent\").hide();\n\n                    return 0;\n                });\n\n\n            });\n\n\n           $(document).on('click', '#eb_setup_sync_all', function (event) {\n                if(this.checked){\n                    $('.eb_setup_sync_cb').prop('checked', true);\n                } else{\n                    $('.eb_setup_sync_cb').prop('checked', false);\n                }\n            });\n\n            $(document).on('click', '.eb_setup_sync_cb', function (event) {\n                if(this.checked){\n                    var all_checked = 1;\n                    $(\".eb_setup_sync_cb\").each(function() {\n\n                        if( ! this.checked ){\n                            all_checked = 0;\n                        }\n\n                    });\n\n                    if ( all_checked ) {\n                        $('#eb_setup_sync_all').prop('checked', true);\n                    }\n\n                } else{\n                    $('#eb_setup_sync_all').prop('checked', false);\n                }\n            });\n\n            /**\n             * Copy to clipboard functionality.\n             */\n            $(document).on(\"click\", \".eb_setup_copy\", function(event) {\n                event.preventDefault();\n\n                var copyText = $(this).data('copy');\n\n                navigator.clipboard.writeText(copyText)\n                .then(() => {\n                    var copy_success = '<p class=\"eb_setup_copy_success\"><i class=\"fa fa-check\" aria-hidden=\"true\"></i> ' +\n                     M.util.get_string(\"copied\", \"auth_edwiserbridge\") + '</p>';\n\n                    $(this).append(copy_success);\n\n                    // Remove success message after 2 seconds\n                    setTimeout(() => {\n                        $(\".eb_setup_copy_success\").fadeOut(300, function() {\n                            $(this).remove();\n                        });\n                    }, 2000);\n                });\n            });\n\n\n\n            // Code to create json file and download it.\n            $(document).on(\"click\", \".eb_setup_download_creds\", function(event) {\n\n                var obj = {\n                    url: $('.eb_setup_copy_url').html(),\n                    token: $('.eb_setup_copy_token').html(),\n                    lang_code: $('.eb_setup_copy_lang').html(),\n                };\n\n\n                $(\"<a />\", {\n                    \"download\": \"creds.json\",\n                    \"href\" : \"data:application/json,\" + encodeURIComponent(JSON.stringify( obj ) )\n                }).appendTo(\"body\").click(function() {\n                    $(this).remove();\n                })[0].click();\n            });\n\n        /**\n         * Close setup.\n         */\n        $('.eb-setup-close-icon').click(function(){\n            // Create loader.\n            $('.eb-setup-content').append('<div class=\"eb_setup_popup\"> ' + $('.eb_setup_popup_content_wrap').html() + ' </div>');\n\n        });\n\n\n        $(document).on('click', '.eb_setup_do_not_close', function (event) {\n            $('.eb_setup_popup').remove();\n        });\n\n\n        $(document).on('change', '.eb_setup_wp_sites', function (event) {\n            var option = $(this).find(\":selected\");\n\n            $('.eb_setup_site_name').val(option.data('name'));\n            $('.eb_setup_site_url').val(option.data('url'));\n\n        });\n\n\n\n\n\n        $(document).on('click', '.eb_redirect_to_wp', function (event) {\n\n            event.preventDefault();\n\n\n            // Sending one js request to unset the progress.\n            var current = $(this);\n            var current_step = $(this).data('step');\n            var next_step = $(this).data('next-step');\n            var is_next_sub_step = $(this).data('is-next-sub-step');\n\n\n            var data = { current_step : current_step, next_step : next_step, is_next_sub_step : is_next_sub_step };\n\n            data = JSON.stringify(data);\n\n\n            var promises = ajax.call([{\n                methodname: \"auth_edwiserbridge_setup_wizard_save_and_continue\",\n                args: { data : data },\n            }, ]);\n\n            promises[0].done(function(response) {\n\n                return response;\n            }).fail(function(response) {\n                return 0;\n            }); //promise end\n\n\n\n\n\n\n\n\n\n\n\n\n            // Create loader.\n            $('.eb-setup-content').append('<div class=\"eb_setup_popup\"> ' + $('.eb_setup_wp_redirection_popup').html() + ' </div>');\n\n            setTimeout( function(){\n                $('.eb_setup_popup').remove();\n                // window.location.replace($(this).attr('href'));\n                $('.eb_redirect_to_wp_btn').trigger('click');\n\n                var redirect = window.open($('.eb_redirect_to_wp').attr('href'), \"_blank\");\n                redirect.focus();\n            }, 2000 );\n\n        });\n\n\n\n        /***************************/\n\n\n        });\n    }\n    return { init: load_settings };\n});\n"],"names":["define","$","ajax","url","str","init","get_strings","key","component","document","ready","checkMissingServices","service_id","messge_ele","promises","call","methodname","args","done","response","message","css","status","hasClass","removeClass","addClass","empty","append","link","window","location","origin","pathname","fix_link","M","util","get_string","msg","text","fail","on","event","slideDown","slideUp","href","indexOf","searchParams","URLSearchParams","search","has","get","val","data","wp_url","wp_token","checkConnectionstatus","toaster","title","time","id","toast","querySelector","appendChild","classList","add","setTimeout","remove","change","this","removeAttr","attr","condition","condition_var","element","btn","handlefieldsdisplay","children","hide","show","click","closest","cfg","wwwroot","length","before","after","preventDefault","error","web_service_name","user_id","token","service_select_fld","common_errr_fld","is_mform","eb_dialog_content","site_url","html","name","add_new_token_in_select","create_web_service","common_success_fld","link_web_service","find","copyText","trim","navigator","clipboard","writeText","then","parent","current_step","next_step","is_next_sub_step","service_name","existing_service","site_name","user_enrollment","prop","user_unenrollment","user_creation","user_deletion","user_update","course_creation","course_deletion","JSON","stringify","step","URL","set","history","replaceState","change_url","parent_step","icon","step_title","handle_step_progress","html_data","i","acc","getElementsByClassName","addEventListener","toggle","panel","nextElementSibling","style","display","option","checked","all_checked","each","copy_success","fadeOut","obj","lang_code","encodeURIComponent","appendTo","trigger","open","focus"],"mappings":";;;;;;;;;AAyBAA,qCAAyC,CACrC,SACA,YACA,WACA,aACD,SAASC,EAAGC,KAAMC,IAAKC,WA4uCf,CAAEC,gBAvuCaD,IAAIE,YAAY,CAC9B,CAAEC,IAAK,eAAgBC,UAAW,sBAClC,CAAED,IAAK,WAAYC,UAAW,sBAC9B,CAAED,IAAK,QAASC,UAAW,sBAC3B,CAAED,IAAK,OAAQC,UAAW,sBAC1B,CAAED,IAAK,SAAUC,UAAW,sBAC5B,CAAED,IAAK,OAAQC,UAAW,sBAC1B,CAAED,IAAK,SAAUC,UAAW,sBAC5B,CAAED,IAAK,oBAAqBC,UAAW,sBACvC,CAAED,IAAK,oBAAqBC,UAAW,sBACvC,CAAED,IAAK,wBAAyBC,UAAW,sBAC3C,CAAED,IAAK,gBAAiBC,UAAW,sBACnC,CAAED,IAAK,cAAeC,UAAW,sBACjC,CAAED,IAAK,kBAAmBC,UAAW,sBACrC,CAAED,IAAK,aAAcC,UAAW,wBAGpCP,EAAEQ,UAAUC,OAAM,oBAmBLC,qBAAqBC,gBAAYC,uEAClCC,SAAWZ,KAAKa,KAAK,CAAC,CACtBC,WAAY,sCACZC,KAAM,CAAEL,WAAYA,eAGxBE,SAAS,GACJI,MAAK,SAASC,cACPC,QAAU,MACdnB,EAAE,QAAQoB,IAAI,SAAU,WACnBF,SAASG,OA2BNrB,EAAE,4BAA4BsB,SAAS,eACvCtB,EAAE,mBAAmBuB,YAAY,sBACjCvB,EAAE,mBAAmBwB,SAAS,uBAE9BxB,EAAE,mBAAmBwB,SAAS,sBAC9BxB,EAAE,mBAAmBuB,YAAY,sBAEjCX,aACAO,QACI,2IAKJnB,EAAEY,YAAYa,QAAQC,OAAOP,kBAxCjCnB,EAAE,mBAAmBuB,YAAY,sBACjCvB,EAAE,mBAAmBwB,SAAS,qBACzBZ,YAGE,GAAIA,WAAY,KACfe,KACAC,OAAOC,SAASC,OAChBF,OAAOC,SAASE,SAChB,eACAC,SACAC,EAAEC,KAAKC,WACH,eACA,sBAEF,aACFR,KACA,sBAAwBM,EAAEC,KAAKC,WAAW,OAAQ,sBAAwB,QAC9EhB,QACI,4BACAD,SAASkB,IACTJ,SACA,UACJhC,EAAEY,YAAYa,QAAQC,OAAOP,eApB7BnB,EAAE,kBAAkBqC,KAAKnB,SAASkB,KAClCpC,EAAE,kBAAkBoB,IAAI,UAAW,gBAuCpCF,YAEVoB,MAAK,SAASpB,iBACXlB,EAAE,QAAQoB,IAAI,SAAU,WACjB,QA3EnBpB,EAAEQ,UAAU+B,GAAG,QAAS,gCAAgC,SAAUC,OAC9DxC,EAAE,gCAAgCwB,SAAS,gCAC3CxB,EAAE,iCAAiCuB,YAAY,+BAC/CvB,EAAE,2BAA2ByC,eAGjCzC,EAAEQ,UAAU+B,GAAG,QAAS,iCAAiC,SAAUC,OAC/DxC,EAAE,iCAAiCwB,SAAS,+BAC5CxB,EAAE,gCAAgCuB,YAAY,gCAC9CvB,EAAE,2BAA2B0C,aA4H7Bd,OAAOC,SAASc,KAAKC,QAAQ,qBAAuB,EAAG,KACnDC,aAAe,IAAIC,gBAAgBlB,OAAOC,SAASkB,WACnDF,aAAaG,IAAI,QAAU,YAAcH,aAAaI,IAAI,OAEtD,KADAtC,WAAaX,EAAE,sBAAsBkD,QACjB,UAAYvC,YAChCD,qBAAqBC,iBAEtB,GAAIkC,aAAaG,IAAI,QAAU,YAAcH,aAAaI,IAAI,OAAQ,KACrEtC,WACJD,qBADIC,WAAaX,EAAE,uBAAuBmD,KAAK,aACd,sCA3DVvC,uEACvBwC,OAASpD,EAAE,cAAcqC,OACzBgB,SAAWrD,EAAE,gBAAgBqC,OAClBpC,KAAKa,KAAK,CACrB,CAAEC,WAAY,qCAAsCC,KAAM,CAAEoC,OAAQA,OAAQC,SAAUA,aAGjF,GACJpC,MAAK,SAASC,cACPC,QAAU,MACdnB,EAAE,QAAQoB,IAAI,SAAU,WACD,KAAnBF,SAASG,UACTrB,EAAE,mBAAmBuB,YAAY,sBACjCvB,EAAE,mBAAmBwB,SAAS,qBACzBZ,YAGE,GAAIA,WAAY,KAEfoB,SAAW,iCADJJ,OAAOC,SAASC,OAASF,OAAOC,SAASE,UACrC,8CACfZ,QAAU,4BAA8BD,SAASkB,IAAMJ,SAAW,UAClEhC,EAAEY,YAAYa,QAAQC,OAAOP,eAN7BnB,EAAE,kBAAkBqC,KAAKnB,SAASkB,KAClCpC,EAAE,kBAAkBoB,IAAI,UAAW,cAQnCpB,EAAE,gCAAgCsB,SAAS,eAC3CtB,EAAE,mBAAmBuB,YAAY,sBACjCvB,EAAE,mBAAmBwB,SAAS,uBAE9BxB,EAAE,mBAAmBwB,SAAS,sBAC9BxB,EAAE,mBAAmBuB,YAAY,sBAEjCX,aACAO,QAAU,mIAEQD,SAASkB,IACvB,iBACJpC,EAAEY,YAAYa,QAAQC,OAAOP,iBAG9BD,YAEVoB,MAAK,SAASpB,iBACXlB,EAAE,QAAQoB,IAAI,SAAU,WACjB,KAiBXkC,CAAsB,qCAsQrBC,QAAQC,WAAOC,4DAAO,UACrBC,GAAK,0BACLC,MAAQ3D,EACV,YACA0D,GACA,KACAzB,EAAEC,KAAKC,WAAW,SAAU,sBAC5B,SACFc,IAAI,GACNzC,SAASoD,cAAc,QAAQC,YAAYF,OAC3CA,MAAMG,UAAUC,IAAI,QACpBC,YAAW,WACPL,MAAMG,UAAUC,IAAI,QACpBC,YAAW,WACPL,MAAMG,UAAUG,OAAO,QACvBD,YAAW,WACPL,MAAMM,WACPR,QACJA,SAjRXzD,EAAE,sBAAsBkE,QAAO,eACvBvD,WAAaX,EAAEmE,MAAMjB,MACzBlD,EAAE,sBAAsBoB,IAAI,UAAW,QACvCpB,EAAE,kBAAkBoB,IAAI,UAAW,QAEnCpB,EAAE,gCAAgCoE,WAAW,YAE7CpE,EAAE,iCAAiCqE,KAAK,YAAY,YAsTpDC,UACAC,cACAC,aACAC,2DAAM,GAEFH,WAAaC,eACbvE,EAAEyE,KAAKpC,KAAKJ,EAAEC,KAAKC,WAAW,SAAU,uBACxCnC,EAAEwE,SAASpD,IAAI,UAAW,UAE1BpB,EAAEyE,KAAKpC,KAAKJ,EAAEC,KAAKC,WAAW,OAAQ,uBACtCnC,EAAEwE,SAASpD,IAAI,UAAW,SA9T9BsD,CACI,SACA/D,WACA,oBACA,+BAGiB,IAAjBX,EAAEmE,MAAMjB,QACRlD,EAAE,gBAAgB2E,SAAS,UAAUC,OACrC5E,EAAE,gBACG2E,SAAS,mBAAqB3E,EAAEmE,MAAMjB,MAAQ,KAC9C2B,OAEgB,UAAjB7E,EAAEmE,MAAMjB,QACRlD,EAAE,QAAQoB,IAAI,SAAU,YACxBV,qBAAqBC,iBAOjCX,EAAE,4BAA4B8E,OAAM,WAChC9E,EAAEmE,MACGY,QAAQ,QACRV,KACG,SACApC,EAAE+C,IAAIC,QACN,2DAIZjF,EAAE,0BAA0B8E,OAAM,WAC9B9E,EAAEmE,MACGY,QAAQ,QACRV,KACG,SACApC,EAAE+C,IAAIC,QACN,gEAIZjF,EAAE,yBAAyB8E,OAAM,WAC7B9E,EAAEmE,MACGY,QAAQ,QACRV,KACG,SACApC,EAAE+C,IAAIC,QAAU,oDAG5BjF,EAAE,wBAAwB8E,OAAM,WAC5B9E,EAAEmE,MACGY,QAAQ,QACRV,KACG,SACApC,EAAE+C,IAAIC,QAAU,wDAI5BjF,EAAE,6BAA6B8E,OAAM,WACjC9E,EAAEmE,MACGY,QAAQ,QACRV,KACG,SACApC,EAAE+C,IAAIC,QAAU,wDAMvBjF,EAAE,yBAAyBkF,QAC5BlF,EAAE,gCAAgCmF,OAC9B,6DACAlD,EAAEC,KAAKC,WAAW,kBAAmB,sBADrC,iIAIAF,EAAE+C,IAAIC,QACN,0CACAhD,EAAEC,KAAKC,WAAW,aAAc,sBAChC,eAGRnC,EAAE,gCAAgCoB,IAAI,UAAW,QAG7CpB,EAAE,iCAAiCkF,SAC9BlF,EAAE,sBAAsBkF,QACzBlF,EAAE,iCAAiCoF,MAC/B,4IAGAnD,EAAEC,KAAKC,WAAW,OAAQ,sBAH1B,4BAYRnC,EAAE,2BAA2BkF,QAC7BlF,EAAE,2BAA2BmF,OACzB,8LASRnF,EAAE,+BAA+B8E,OAAM,SAAStC,OAC5CA,MAAM6C,qBACFC,MAAQ,EACRC,iBAAmBvF,EAAE,sBAAsBkD,MAC3CsC,QAAUxF,EAAE,0BAA0BkD,MACtCvC,WAAaX,EAAE,sBAAsBkD,MACrCuC,MAAQzF,EAAE,gBAAgBkD,SAE9BlD,EAAE,oBAAoBiE,SACtBjE,EAAE,sBAAsBoB,IAAI,UAAW,QACvCpB,EAAE,kBAAkBoB,IAAI,UAAW,QAEpB,IAAXoE,UACAxF,EAAE,kBAAkBqC,KAChBJ,EAAEC,KAAKC,WAAW,oBAAqB,uBAE3CnC,EAAE,kBAAkBoB,IAAI,UAAW,SACnCkE,MAAQ,GAIM,UAAd3E,WAAwB,IACA,IAApB4E,mBACAvF,EAAE,kBAAkBoB,IAAI,UAAW,SACnCpB,EAAE,kBAAkBqC,KAChBJ,EAAEC,KAAKC,WAAW,oBAAqB,uBAE3CmD,MAAQ,GAGRA,uBA0ORC,iBACAC,QACAE,mBACAC,gBACAC,UAEA5F,EAAE,QAAQoB,IAAI,SAAU,YACxBpB,EAAE,kBAAkBoB,IAAI,UAAW,QAEnCpB,EAAE,gCAAgCoE,WAAW,YAE7CpE,EAAE,iCAAiCqE,KAAK,YAAY,OAEhDxD,SAAWZ,KAAKa,KAAK,CAAC,CACtBC,WAAY,oCACZC,KAAM,CAAEuE,iBAAkBA,iBAAkBC,QAASA,YAMrD3E,SAAS,GACJI,MAAK,SAASC,aACXlB,EAAE,QAAQoB,IAAI,SAAU,WACpBF,SAASG,OAAQ,KAEbwE,kBACA,SACA5D,EAAEC,KAAKC,WAAW,cAAe,sBADjC,uEAMAF,EAAEC,KAAKC,WAAW,WAAY,sBAN9B,sDASAF,EAAEC,KAAKC,WAAW,gBAAiB,sBACnC,KACAjB,SAAS4E,SAXT,4CAcA7D,EAAEC,KAAKC,WAAW,OAAQ,sBAd1B,iDAmBAF,EAAEC,KAAKC,WAAW,QAAS,sBAnB3B,sDAsBAF,EAAEC,KAAKC,WAAW,gBAAiB,sBACnC,KACAjB,SAASuE,MAxBT,4CA2BAxD,EAAEC,KAAKC,WAAW,OAAQ,sBA3B1B,8BAgCJnC,EAAE,QAAQ0B,OACN,+QAcJ1B,EAAE,8BAA8B+F,KAAKF,mBACrC7F,EAAE,sBAAsB6E,OAhLTL,QAmLXkB,mBAnLoBM,KAoLpBT,iBApL0B7B,GAqL1BxC,SAASP,WApL7BX,EAAEwE,QAAU,mBAAmBJ,WAAW,YAC1CpE,EAAEwE,SAAS9C,OACP,kBAAoBgC,GAAK,eAAiBsC,KAAO,uBAUxBxB,QAASiB,MAAO/B,IAC7C1D,EAAEwE,QAAU,mBAAmBJ,WAAW,YAC1CpE,EAAEwE,SAAS9C,OACP,oBACAgC,GACA,YACA+B,MACA,eACAA,MACA,cAiKYQ,CACI,eACA/E,SAASuE,MACTvE,SAASP,iBAGbX,EAAE,kBAAkBoB,IAAI,UAAW,SACnCpB,EAAE2F,iBAAiBtD,KAAKnB,SAASkB,SA9LlBoC,QAASwB,KAAMtC,UAiM3BxC,YAEVoB,MAAK,SAASpB,iBACXlB,EAAE,QAAQoB,IAAI,SAAU,WACjB,KAtUf8E,CACIX,iBACAC,QACA,qBACA,sBAGD,IAC4B,IAA3BxF,EAAE,gBAAgBkD,aAClBlD,EAAE,kBAAkBoB,IAAI,UAAW,SACnCpB,EAAE,kBAAkBqC,KAChBJ,EAAEC,KAAKC,WAAW,cAAe,uBAErCmD,MAAQ,EACD,KAGPA,aAKc,IAAd3E,oBAmKRA,WACA8E,MACAE,gBACAQ,oBAEAnG,EAAE,QAAQoB,IAAI,SAAU,YACxBpB,EAAE,kBAAkBoB,IAAI,UAAW,QAEpBnB,KAAKa,KAAK,CAAC,CACtBC,WAAY,kCACZC,KAAM,CAAEL,WAAYA,WAAY8E,MAAOA,UAGlC,GACJxE,MAAK,SAASC,iBACXlB,EAAE,QAAQoB,IAAI,SAAU,WACpBF,SAASG,QACTrB,EAAEmG,oBAAoB9D,KAAKnB,SAASkB,KACpCpC,EAAEmG,oBAAoB/E,IAAI,UAAW,WAErCpB,EAAE2F,iBAAiBtD,KAAKnB,SAASkB,KACjCpC,EAAEmG,oBAAoB/E,IAAI,UAAW,UAGlCF,YAEVoB,MAAK,SAASpB,iBACXlB,EAAE,QAAQoB,IAAI,SAAU,WACjB,KA9LPgF,CACIzF,WACA8E,MACA,iBACA,sBAIJzF,EAAE,kBAAkBqC,KAChBJ,EAAEC,KAAKC,WAAW,wBAAyB,2BAe3DnC,EAAEQ,UAAU+B,GAAG,aAAc,sBAAsB,WAElCvC,EAAEmE,MAAMkC,KAAK,gBACnBjF,IAAI,aAAc,cAG7BpB,EAAEQ,UAAU+B,GAAG,aAAc,sBAAsB,WAElCvC,EAAEmE,MAAMkC,KAAK,gBACnBjF,IAAI,aAAc,aAM7BpB,EAAEQ,UAAU+B,GAAG,QAAS,sBAAsB,SAASC,OACnDA,MAAM6C,qBAEFiB,SAAWtG,EAAEmE,MAAMkC,KAAK,iBAAiBN,OAAOQ,OACpDC,UAAUC,UAAUC,UAAUJ,UAAUK,MAAK,KACzCpD,QAAQtB,EAAEC,KAAKC,WAAW,SAAU,sBAAuB,WAInEnC,EAAEQ,UAAU+B,GAAG,QAAS,wBAAwB,SAASC,OACrDA,MAAM6C,qBAEFuB,OAAS5G,EAAEmE,MAAMyC,SAASA,YAIL,gBAFzBA,OAASA,OAAOP,KAAK,aAEVhC,KAAK,UACRiC,SAAWM,OAAO1D,MAAMqD,YAExBD,SAAWM,OAAOvE,OAAOkE,OAGjCC,UAAUC,UAAUC,UAAUJ,UAC7BK,MAAK,KACFpD,QAAQtB,EAAEC,KAAKC,WAAW,SAAU,sBAAuB,WAmInEnC,EAAEQ,UAAU+B,GAAG,QAAS,4BAA4B,WAChDvC,EAAE,sBAAsB4E,UA4H5B5E,EAAE,QAAQ0B,OAHG,iHAmEb1B,EAAEQ,UAAU+B,GAAG,QAAS,+BAA+B,SAAUC,OAE/CxC,EAAEmE,UACZ0C,aAAe7G,EAAEmE,MAAMhB,KAAK,QAC5B2D,UAAY9G,EAAEmE,MAAMhB,KAAK,aACzB4D,iBAAmB/G,EAAEmE,MAAMhB,KAAK,oBAQhCA,KAAO,CAAE0D,aAAeA,aAAcC,UAAYA,UAAWC,iBAAmBA,yBAE3EF,kBACA,wBAQA,oBACD7G,EAAE,qBAAqB6E,OAEvB1B,KAAO,CAAE0D,aAAeA,aAAcC,UAAYA,UAAWC,iBAAmBA,4BAI/E,kBACGC,aAAehH,EAAE,8BAA8BkD,SAI/B,UAAhB8D,cAA4B,IAAMhH,EAAE,8BAA8BkD,aAClEV,MAAM6C,sBACNrF,EAAE,8BAA8BoB,IAAI,eAAgB,OAIpDpB,EAAE,qBAAqB6E,WAEnBoC,iBAAmB,EAEF,UAAhBD,cAA4C,IAAhBA,eAC7BA,aAAehH,EAAE,8BAA8BkD,MAC/C+D,iBAAmB,GAGvB9D,KAAO,CACH0D,aAAeA,aACfC,UAAYA,UACZC,iBAAmBA,iBACnBC,aAAeA,aACfC,iBAAmBA,4BAM1B,4BAEG,IAAMC,YAAe,IAAMlH,EAAE,uBAAuBkD,OAAS,IAAMlD,EAAE,sBAAsBkD,cAC3FV,MAAM6C,iBAED,IAAMrF,EAAE,uBAAuBkD,MAChClD,EAAE,uBAAuBoB,IAAI,eAAgB,OAE7CpB,EAAE,uBAAuBoB,IAAI,eAAgB,gBAG5C,IAAMpB,EAAE,sBAAsBkD,MAC/BlD,EAAE,sBAAsBoB,IAAI,eAAgB,OAE5CpB,EAAE,sBAAsBoB,IAAI,eAAgB,YAKhDpB,EAAE,qBAAqB6E,WAKnBqC,UAAYlH,EAAE,sBAAsBkD,MACpChD,IAAY,GAEX,IAAMgH,YACPA,UAAYlH,EAAE,uBAAuBkD,MACrChD,IAAYF,EAAE,sBAAsBkD,OAGxCC,KAAO,CACH0D,aAAeA,aACfC,UAAYA,UACZC,iBAAmBA,iBACnBG,UAAYA,UACZhH,IAAMA,eAOb,uBACDF,EAAE,qBAAqB6E,WAEnBsC,gBAAoBnH,EAAE,kCAAkCoH,KAAK,WAAa,EAAI,EAC9EC,kBAAoBrH,EAAE,oCAAoCoH,KAAK,WAAa,EAAI,EAChFE,cAAoBtH,EAAE,gCAAgCoH,KAAK,WAAa,EAAI,EAC5EG,cAAoBvH,EAAE,gCAAgCoH,KAAK,WAAa,EAAI,EAC5EI,YAAoBxH,EAAE,8BAA8BoH,KAAK,WAAa,EAAI,EAC1EK,gBAAoBzH,EAAE,kCAAkCoH,KAAK,WAAa,EAAI,EAC9EM,gBAAoB1H,EAAE,kCAAkCoH,KAAK,WAAa,EAAI,EAKlFjE,KAAO,CACH0D,aAAeA,aACfC,UAAYA,UACZC,iBAAmBA,iBACnBI,gBAAiBA,gBACjBE,kBAAmBA,kBACnBC,cAAeA,cACfC,cAAeA,cACfC,YAAaA,YACbC,gBAAiBA,gBACjBC,gBAAiBA,+BAOrB1H,EAAE,qBAAqB6E,OAI/B1B,KAAOwE,KAAKC,UAAUzE,MAGPlD,KAAKa,KAAK,CAAC,CACtBC,WAAY,oDACZC,KAAM,CAAEmC,KAAOA,SAGV,GAAGlC,MAAK,SAASC,UACtBlB,EAAE,qBAAqB4E,gBA/MViD,UACb3H,IAAM,IAAI4H,IAAItH,SAASqB,UAC3B3B,IAAI2C,aAAakF,IAAI,eAAgBF,MACrCjG,OAAOoG,QAAQC,aAAc,KAAM,KAAM/H,KA8MrCgI,CAAYpB,2BApMWD,aAAcC,UAAWC,iBAAkBoB,aAM1DnI,EAAE,kBAAoB6G,cAAcrF,SAAS,gCACrDxB,EAAE,kBAAoB6G,cAAcvF,SAAS,8BAC7CtB,EAAE,kBAAoB6G,cAActF,YAAY,iCAuBhD6G,KAnBAC,WAAarI,EAAE,kBAAoB6G,cAAclC,SAAS,yBAC9D0D,WAAW7G,SAAS,2BACjB6G,WAAW/G,SAAS,yBACnB+G,WAAW9G,YAAY,yBAIvB6G,KAAOpI,EAAE,kBAAoB6G,cAAclC,SAAS,qCACnDnD,SAAS,mBAEV4G,KAAK9G,SAAS,4BACd8G,KAAK7G,YAAY,2BAITvB,EAAE,kBAAoB8G,WAAWtF,SAAS,6BACpCxB,EAAE,kBAAoB8G,WAAWnC,SAAS,yBAChDnD,SAAS,yBAEjB4G,KAAOpI,EAAE,kBAAoB8G,WAAWnC,SAAS,qCAChDnD,SAAS,oCAEX4G,KAAK9G,SAAS,yBACb8G,KAAK7G,YAAY,wBAuKjB+G,CAAsBzB,aAAcC,WAEpC9G,EAAE,0BAA0B+F,KAAK7E,SAASsC,OAC1CxD,EAAE,qBAAqB+F,KAAK7E,SAASqH,WAGhC,oBAAsBzB,YACvB9G,EAAE,qBAAqB0B,OACnB,gCACA1B,EAAE,yCAAyC+F,OAC3C,WAIJ/B,YAAW,WACPhE,EAAE,mBAAmBiE,WACtB,MAIA/C,YACRoB,MAAK,SAASpB,iBACblB,EAAE,qBAAqB4E,OACvB5E,EAAE,QAAQoB,IAAI,SAAU,WACjB,QASVpB,EAAE,yCAAyCkF,SAC5ClF,EAAE,qBAAqB0B,OACnB,gCACA1B,EAAE,yCAAyC+F,OAC3C,WAEJ/B,YAAW,WACPhE,EAAE,mBAAmBiE,WACtB,MAUPjE,EAAEQ,UAAU+B,GAAG,QAAS,8BAA8B,SAAUC,OAE5DxC,EAAE,qBAAqB6E,OAER5E,KAAKa,KAAK,CAAC,CACtBC,WAAY,4CACZC,KAAM,MAGD,GAAGC,MAAK,SAASC,iBACtBlB,EAAE,QAAQoB,IAAI,SAAU,WACxBpB,EAAE,qBAAqB4E,OAIvB5E,EAAE,4BAA4BoB,IAAK,QAAS,WAC5CpB,EAAE,0BAA0BoB,IAAK,QAAS,WAC1CpB,EAAE,0BAA0BoB,IAAK,QAAS,WAC1CpB,EAAE,2BAA2BoB,IAAK,QAAS,WAG3CpB,EAAE,kCAAkCoB,IAAK,UAAW,SAIpDpB,EAAE,8BAA8BoB,IAAK,UAAW,QAChDpB,EAAE,oCAAoCoB,IAAK,UAAW,QACtDpB,EAAE,+BAA+BoB,IAAK,UAAW,WAE1CF,YACRoB,MAAK,SAASpB,iBACblB,EAAE,qBAAqB4E,OAEvB5E,EAAE,QAAQoB,IAAI,SAAU,WACjB,YASXoH,EADAC,IAAMjI,SAASkI,uBAAuB,iBAGrCF,EAAI,EAAGA,EAAIC,IAAIvD,OAAQsD,IAC1BC,IAAID,GAAGG,iBAAiB,SAAS,gBAG1B7E,UAAU8E,OAAO,cAGlBC,MAAQ1E,KAAK2E,mBACW,UAAxBD,MAAME,MAAMC,QACdH,MAAME,MAAMC,QAAU,OAEtBH,MAAME,MAAMC,QAAU,WAS5BhJ,EAAEQ,UAAU+B,GAAG,SAAU,8BAA8B,SAAUC,OAE1D,IAAMxC,EAAE,8BAA8BkD,OACrClD,EAAE,6BAA6BuB,YAAY,YAC3CvB,EAAE,6BAA6BoE,WAAW,cAE1CpE,EAAE,6BAA6BqE,KAAK,WAAY,YAChDrE,EAAE,6BAA6BwB,SAAS,aAIzC,UAAYxB,EAAE,8BAA8BkD,MAC3ClD,EAAE,mCAAmCoB,IAAI,UAAW,SAEpDpB,EAAE,mCAAmCoB,IAAI,UAAW,WAO5DpB,EAAEQ,UAAU+B,GAAG,SAAU,sBAAsB,SAAUC,UAElD,IAAMxC,EAAE,8BAA8BkD,OACrClD,EAAE,4BAA4BuB,YAAY,YAC1CvB,EAAE,4BAA4BoE,WAAW,cAEzCpE,EAAE,4BAA4BqE,KAAK,WAAY,YAC/CrE,EAAE,4BAA4BwB,SAAS,aAGxC,IAAMxB,EAAE,sBAAsBkD,MAC7BlD,EAAE,iCAAiCwB,SAAS,qCACzC,CACHxB,EAAE,iCAAiCuB,YAAY,qCAE3C0H,OAASjJ,EAAEmE,MAAMkC,KAAK,aAE1BrG,EAAE,uBAAuBkD,IAAI+F,OAAO9F,KAAK,SACzCnD,EAAE,sBAAsBkD,IAAI+F,OAAO9F,KAAK,YAOhDnD,EAAEQ,UAAU+B,GAAG,QAAS,iCAAiC,SAAUC,WAE3DtC,IAAMF,EAAE,sBAAsBkD,MAClClD,EAAE,QAAQoB,IAAI,SAAU,QAExBpB,EAAE,qBAAqB6E,OAGR5E,KAAKa,KAAK,CAAC,CACtBC,WAAY,2CACZC,KAAM,CAAEoC,OAAQlD,QAGX,GAAGe,MAAK,SAASC,iBACtBlB,EAAE,qBAAqB4E,OACvB5E,EAAE,QAAQoB,IAAI,SAAU,WAGxBpB,EAAE,gCAAgCoB,IAAI,UAAW,SAG3B,GAAnBF,SAASG,QACRrB,EAAE,0CAA0CoB,IAAI,UAAW,gBAC3DpB,EAAE,iCAAiCoB,IAAI,UAAW,QAElDpB,EAAE,gCAAgCwB,SAAS,iCAC3CxB,EAAE,gCAAgC+F,KAAK,4CAA8C7E,SAASkB,KAC9FpC,EAAE,gCAAgCuB,YAAY,4BAE9CvB,EAAE,gCAAgCwB,SAAS,0BAC3CxB,EAAE,gCAAgC+F,KAAK,4CAA8C7E,SAASkB,KAC9FpC,EAAE,gCAAgCuB,YAAY,kCAG3CL,YACRoB,MAAK,SAASpB,iBACblB,EAAE,QAAQoB,IAAI,SAAU,WACxBpB,EAAE,qBAAqB4E,OAEhB,QAOhB5E,EAAEQ,UAAU+B,GAAG,QAAS,sBAAsB,SAAUC,OAChD2B,KAAK+E,QACJlJ,EAAE,qBAAqBoH,KAAK,WAAW,GAEvCpH,EAAE,qBAAqBoH,KAAK,WAAW,MAI/CpH,EAAEQ,UAAU+B,GAAG,QAAS,qBAAqB,SAAUC,UAChD2B,KAAK+E,QAAQ,KACRC,YAAc,EAClBnJ,EAAE,qBAAqBoJ,MAAK,WAElBjF,KAAK+E,UACPC,YAAc,MAKjBA,aACDnJ,EAAE,sBAAsBoH,KAAK,WAAW,QAI5CpH,EAAE,sBAAsBoH,KAAK,WAAW,MAOhDpH,EAAEQ,UAAU+B,GAAG,QAAS,kBAAkB,SAASC,OAC/CA,MAAM6C,qBAEFiB,SAAWtG,EAAEmE,MAAMhB,KAAK,QAE5BqD,UAAUC,UAAUC,UAAUJ,UAC7BK,MAAK,SACE0C,aAAe,mFAClBpH,EAAEC,KAAKC,WAAW,SAAU,sBAAwB,OAErDnC,EAAEmE,MAAMzC,OAAO2H,cAGfrF,YAAW,KACPhE,EAAE,0BAA0BsJ,QAAQ,KAAK,WACrCtJ,EAAEmE,MAAMF,cAEb,WAOXjE,EAAEQ,UAAU+B,GAAG,QAAS,4BAA4B,SAASC,WAErD+G,IAAM,CACNrJ,IAAKF,EAAE,sBAAsB+F,OAC7BN,MAAOzF,EAAE,wBAAwB+F,OACjCyD,UAAWxJ,EAAE,uBAAuB+F,QAIxC/F,EAAE,QAAS,UACK,kBACH,yBAA2ByJ,mBAAmB9B,KAAKC,UAAW2B,QACxEG,SAAS,QAAQ5E,OAAM,WACtB9E,EAAEmE,MAAMF,YACT,GAAGa,WAMd9E,EAAE,wBAAwB8E,OAAM,WAE5B9E,EAAE,qBAAqB0B,OAAO,gCAAkC1B,EAAE,gCAAgC+F,OAAS,cAK/G/F,EAAEQ,UAAU+B,GAAG,QAAS,0BAA0B,SAAUC,OACxDxC,EAAE,mBAAmBiE,YAIzBjE,EAAEQ,UAAU+B,GAAG,SAAU,sBAAsB,SAAUC,WACjDyG,OAASjJ,EAAEmE,MAAMkC,KAAK,aAE1BrG,EAAE,uBAAuBkD,IAAI+F,OAAO9F,KAAK,SACzCnD,EAAE,sBAAsBkD,IAAI+F,OAAO9F,KAAK,WAQ5CnD,EAAEQ,UAAU+B,GAAG,QAAS,sBAAsB,SAAUC,OAEpDA,MAAM6C,iBAIQrF,EAAEmE,UAMZhB,KAAO,CAAE0D,aALM7G,EAAEmE,MAAMhB,KAAK,QAKU2D,UAJ1B9G,EAAEmE,MAAMhB,KAAK,aAIoC4D,iBAH1C/G,EAAEmE,MAAMhB,KAAK,qBAKpCA,KAAOwE,KAAKC,UAAUzE,MAGPlD,KAAKa,KAAK,CAAC,CACtBC,WAAY,oDACZC,KAAM,CAAEmC,KAAOA,SAGV,GAAGlC,MAAK,SAASC,iBAEfA,YACRoB,MAAK,SAASpB,iBACN,KAeXlB,EAAE,qBAAqB0B,OAAO,gCAAkC1B,EAAE,kCAAkC+F,OAAS,WAE7G/B,YAAY,WACRhE,EAAE,mBAAmBiE,SAErBjE,EAAE,0BAA0B2J,QAAQ,SAErB/H,OAAOgI,KAAK5J,EAAE,sBAAsBqE,KAAK,QAAS,UACxDwF,UACV"}

================
File: amd/build/sso_settings.min.js
================
/**
 * Js file to handle settings.
 *
 * @package
 * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @author      Wisdmlabs
 * @module      auth_edwiserbridge/sso_settings
 */
define("auth_edwiserbridge/sso_settings",["jquery","core/ajax","core/url","core/str"],(function($,ajax,url,str){return{init:function(){$(document).ready((function(){$("#id_secret_key_generate").on("click",(function(event){event.preventDefault();for(var text="",possible="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz",i=0;i<15;i++)text+=possible.charAt(Math.floor(Math.random()*possible.length));$("#id_sharedsecret").val(text)}))}))}}}));
⋮----
//# sourceMappingURL=sso_settings.min.js.map

================
File: amd/build/sso_settings.min.js.map
================
{"version":3,"file":"sso_settings.min.js","sources":["../src/sso_settings.js"],"sourcesContent":["/* eslint-disable no-unused-vars */\n// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n/**\n * Js file to handle settings.\n *\n * @package\n * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>\n * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @author      Wisdmlabs\n * @module      auth_edwiserbridge/sso_settings\n */\n\"use strict\";\ndefine(\"auth_edwiserbridge/eb_sso_settings\", [\n    \"jquery\",\n    \"core/ajax\",\n    \"core/url\",\n    \"core/str\",\n], function($, ajax, url, str) {\n    /**\n     * Load SSO settings.\n     */\n    function load_settings() {\n        $(document).ready(function () {\n            $('#id_secret_key_generate').on('click', function (event) {\n                event.preventDefault();\n                var text = \"\";\n                var possible = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz\";\n\n                for (var i = 0; i < 15; i++) {\n                    text += possible.charAt(Math.floor(Math.random() * possible.length));\n                }\n\n                $('#id_sharedsecret').val(text);\n            });\n        });\n    }\n    return { init: load_settings };\n});\n"],"names":["define","$","ajax","url","str","init","document","ready","on","event","preventDefault","text","possible","i","charAt","Math","floor","random","length","val"],"mappings":";;;;;;;;;AAyBAA,yCAA6C,CACzC,SACA,YACA,WACA,aACD,SAASC,EAAGC,KAAMC,IAAKC,WAmBf,CAAEC,gBAdLJ,EAAEK,UAAUC,OAAM,WACdN,EAAE,2BAA2BO,GAAG,SAAS,SAAUC,OAC/CA,MAAMC,yBACFC,KAAO,GACPC,SAAW,iEAENC,EAAI,EAAGA,EAAI,GAAIA,IACpBF,MAAQC,SAASE,OAAOC,KAAKC,MAAMD,KAAKE,SAAWL,SAASM,SAGhEjB,EAAE,oBAAoBkB,IAAIR"}

================
File: amd/src/edwiser_bridge.js
================
/* eslint-disable no-unused-vars */
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
/**
 * JS file to handle edwiser bridge.
 *
 * @package
 * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license     https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @author      Wisdmlabs
 * @module      auth_edwiserbridge/edwiser_bridge
 */
define(['jquery', 'core/ajax', 'core/url', 'core/str'], function($, ajax, url) {
⋮----
$(document).ready(function() {
⋮----
/**
                 * Functionality to avoid space in the site name.
                 */
$('input[name^="wp_name"]').on({
⋮----
this.value = this.value.replace(/\s/g, "");
⋮----
/**
                 * Functionality to test connection.
                 */
$("[id$=_eb_test_connection]").click(function(event) {
event.preventDefault();
$(document.body).css({ 'cursor': 'wait' });
var id = $(this).prop("id");
id = id.replace("eb_test_connection", '');
id = id.replace("id_eb_buttons", '');
var index = id.replace(/\_/g, '');
var url = $("#id_wp_url_" + index).val();
var token = $("#id_wp_token_" + index).val();
var parent = $(this).parent().parent();
parent = parent.parent();
⋮----
// Display none the error div.
parent.find("#eb_test_conne_response_old").css("display", "none");
⋮----
var promises = ajax.call([
⋮----
promises[0].done(function(response) {
parent.find("#eb_test_conne_response_old").html(response.msg);
parent.find("#eb_test_conne_response_old").css("display", "block");
⋮----
parent.find("#eb_test_conne_response_old").addClass("eb-success-msg");
parent.find("#eb_test_conne_response_old").removeClass("eb-error-msg");
⋮----
parent.find("#eb_test_conne_response_old").removeClass("eb-success-msg");
parent.find("#eb_test_conne_response_old").addClass("eb-error-msg");
⋮----
$(document.body).css({ 'cursor': 'default' });
}).fail(function(ex) {
// Do something with the exception.
⋮----
/**
                 * Functionality to remove site from the sites list.
                 */
$("[id$=_eb_remove_site]").click(function(event) {
⋮----
id = id.replace("eb_remove_site", '');
⋮----
$("#id_wp_url_" + index).val("");
$("#id_wp_token_" + index).val("");
$("#id_wp_name_" + index).val("");
⋮----
// Hiding elemnts.
onRemoveHideElemnts(index);
$("input[name='wp_remove[" + index + "]']").val("yes");
⋮----
/**
                 * Hide the elements removed from the remove button.
                 * @param {number} index - Index of the element.
                 */
function onRemoveHideElemnts(index) {
$("#id_wp_name_" + index).closest('fieldset').css("display", "none");
⋮----
// Hiding js elements which are already removed.
if ($("input[name='wp_remove[0]']").length) {
var repeatQty = $("input[name='eb_connection_setting_repeats']").val();
⋮----
if ("yes" == $("input[name='wp_remove[" + i + "]']").val()) {
onRemoveHideElemnts(i);
⋮----
/**
                 * Functionlaity to get site synch values on the site change.
                 */
$("#id_wp_site_list").on("change", function() {
⋮----
{ methodname: 'auth_edwiserbridge_get_site_data', args: { site_index: $(this).val() } }
⋮----
$('#id_course_enrollment').prop('checked', response.course_enrollment);
$('#id_course_un_enrollment').prop('checked', response.course_un_enrollment);
$('#id_user_creation').prop('checked', response.user_creation);
$('#id_user_deletion').prop('checked', response.user_deletion);
$('#id_course_creation').prop('checked', response.course_creation);
$('#id_course_deletion').prop('checked', response.course_deletion);
$('#id_user_updation').prop('checked', response.user_updation);
}).fail(function(ex) {});

================
File: amd/src/settings.js
================
/* eslint-disable no-unused-vars */
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
/**
 * Js file to handle settings.
 *
 * @package
 * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @author      Wisdmlabs
 * @module      auth_edwiserbridge/settings
 */
⋮----
define("auth_edwiserbridge/eb_settings", [
⋮----
/**
     * Load settings.
     */
function load_settings() {
var translation = str.get_strings([
⋮----
$(document).ready(function () {
⋮----
$(document).on('click', '.eb_test_connection_log_open', function (event) {
$('.eb_test_connection_log_open').addClass('eb_test_connection_log_close');
$('.eb_test_connection_log_close').removeClass('eb_test_connection_log_open');
$(".eb_test_connection_log").slideDown();
⋮----
$(document).on('click', '.eb_test_connection_log_close', function (event) {
$('.eb_test_connection_log_close').addClass('eb_test_connection_log_open');
$('.eb_test_connection_log_open').removeClass('eb_test_connection_log_close');
$(".eb_test_connection_log").slideUp();
⋮----
/**
             * Check if all the services are enabled.
             * @param {string} service_id
             * @param {boolean} messge_ele
            */
function checkMissingServices(service_id, messge_ele = false) {
var promises = ajax.call([{
⋮----
.done(function(response) {
⋮----
$("body").css("cursor", "default");
⋮----
$(".eb_summary_tab").removeClass("summary_tab_sucess");
$(".eb_summary_tab").addClass("summary_tab_error");
⋮----
$("#eb_common_err").text(response.msg);
$("#eb_common_err").css("display", "block");
⋮----
M.util.get_string(
⋮----
"'  target='_blank'>" + M.util.get_string("here", "auth_edwiserbridge") + "</a>.";
⋮----
$(messge_ele).empty().append(message);
⋮----
if ($("#web_service_status span").hasClass("summ_error")) {
⋮----
$(".eb_summary_tab").addClass("summary_tab_sucess");
$(".eb_summary_tab").removeClass("summary_tab_error");
⋮----
.fail(function(response) {
⋮----
/**
             * Check the connection status with WordPress site
             * @param {boolean|Element} messge_ele - Optional element to display messages
             */
function checkConnectionstatus(messge_ele = false) {
var wp_url = $("#eb_wp_url").text();
var wp_token = $("#eb_wp_token").text();
var promises = ajax.call([
⋮----
if ($("#test_connection_status span").hasClass("summ_error")) {
⋮----
/**
             * Check if the user is on edwiser bridge settings page.
             */
if (window.location.href.indexOf("edwiserbridge.php") > 1) {
let searchParams = new URLSearchParams(window.location.search);
if (searchParams.has("tab") && "service" === searchParams.get("tab")) {
var service_id = $("#id_eb_sevice_list").val();
⋮----
checkMissingServices(service_id);
⋮----
} else if (searchParams.has("tab") && "summary" === searchParams.get("tab")) {
var service_id = $("#web_service_status").data("serviceid");
checkMissingServices(service_id, "#web_service_status");
checkConnectionstatus("#test_connection_status");
⋮----
/*
             * Functionality to show only tokens which are asscoiated with the service.
             */
$("#id_eb_sevice_list").change(function() {
var service_id = $(this).val();
$("#eb_common_success").css("display", "none");
$("#eb_common_err").css("display", "none");
⋮----
$("#id_eb_token option:selected").removeAttr("selected");
⋮----
$('#id_eb_token option[value=""]').attr("selected", true);
⋮----
handlefieldsdisplay(
⋮----
if ($(this).val() != "") {
$("#id_eb_token").children("option").hide();
$("#id_eb_token")
.children("option[data-id^=" + $(this).val() + "]")
.show();
⋮----
if ($(this).val() != "create") {
$("body").css("cursor", "progress");
⋮----
/*****************    Change Form Action URL   *******************/
⋮----
$("#service_submit_continue").click(function() {
$(this)
.closest("form")
.attr(
⋮----
$("#conne_submit_continue").click(function() {
⋮----
$("#sync_submit_continue").click(function() {
⋮----
$("#sso_submit_continue").click(function() {
⋮----
$("#settings_submit_continue").click(function() {
⋮----
/*********** END *********/
// Add Settings field.
if (!$(".eb_settings_btn_cont").length) {
$("#admin-eb_setup_wizard_field").before(
⋮----
M.util.get_string("eb_settings_msg", "auth_edwiserbridge") +
⋮----
M.util.get_string("click_here", "auth_edwiserbridge") +
⋮----
$("#admin-eb_setup_wizard_field").css("display", "none");
⋮----
//Adds the link and create button on the set-up wizard
if ($("#admin-ebnewserviceuserselect").length) {
if (!$("#eb_create_service").length) {
$("#admin-ebnewserviceuserselect").after(
⋮----
M.util.get_string("link", "auth_edwiserbridge") +
⋮----
//This adds the error succes messages divs on the set-up wizard.
if ($(".eb_create_service_wrap").length) {
$(".eb_create_service_wrap").before(
⋮----
$("#id_eb_mform_create_service").click(function(event) {
event.preventDefault();
⋮----
var web_service_name = $("#id_eb_service_inp").val();
var user_id = $("#id_eb_auth_users_list").val();
⋮----
var token = $("#id_eb_token").val();
⋮----
$(".eb_settings_err").remove();
⋮----
$("#eb_common_err").text(
M.util.get_string("eb_empty_user_err", "auth_edwiserbridge")
⋮----
//If the select box has a value to create the web service the create web service else
⋮----
M.util.get_string("eb_empty_name_err", "auth_edwiserbridge")
⋮----
create_web_service(
⋮----
if ($("#id_eb_token").val() == "") {
⋮----
M.util.get_string("token_empty", "auth_edwiserbridge")
⋮----
//If select has selected existing web service
⋮----
link_web_service(
⋮----
//If the select box has been selected with the placeholder
⋮----
M.util.get_string("eb_service_select_err", "auth_edwiserbridge")
⋮----
}); // event end
⋮----
/************************ Web service creation click handlers *******************************/
⋮----
/* -------------------------------------------
             *  Copy to clipboard functionality handler
             *---------------------------------------*/
⋮----
/**
             * This shows the copy test on the side
             */
$(document).on("mouseenter", ".eb_copy_text_wrap", function() {
// hover starts code here
var parent = $(this).find(".eb_copy_btn");
parent.css("visibility", "visible");
⋮----
$(document).on("mouseleave", ".eb_copy_text_wrap", function() {
// hover ends code here
⋮----
parent.css("visibility", "hidden");
⋮----
/**
             * Copy to clipboard functionality.
             */
$(document).on("click", ".eb_copy_text_wrap", function(event) {
⋮----
var copyText = $(this).find(".eb_copy_text").html().trim();
navigator.clipboard.writeText(copyText).then(() => {
toaster(M.util.get_string('copied', 'auth_edwiserbridge'), 400);
⋮----
$(document).on("click", ".eb_primary_copy_btn", function(event) {
⋮----
var parent = $(this).parent().parent();
⋮----
parent = parent.find(".eb_copy");
⋮----
if (parent.attr("id") == "id_eb_token") {
var copyText = parent.val().trim();
⋮----
var copyText = parent.text().trim();
⋮----
navigator.clipboard.writeText(copyText)
.then(() => {
toaster(M.util.get_string('copied', 'auth_edwiserbridge'), 200);
⋮----
/*************   Copy to clipboard functionality handler  **************/
⋮----
/*----------------------------------------------------
             * Below are alll js functions
             *---------------------------------------------------*/
⋮----
/**
             * Toatser adde to show the successful copy message.
             * @param {string} title
             * @param {int} time
             */
function toaster(title, time = 2000) {
⋮----
const toast = $(
⋮----
M.util.get_string("copied", "auth_edwiserbridge") +
⋮----
).get(0);
document.querySelector("body").appendChild(toast);
toast.classList.add("show");
setTimeout(function() {
toast.classList.add("fade");
⋮----
toast.classList.remove("fade");
⋮----
toast.remove();
⋮----
/**
             * This function adds newly created web service in the drop down
             * @param {string} element
             * @param {string} name
             * @param {string} id
             */
function add_new_service_in_select(element, name, id) {
$(element + "option:selected").removeAttr("selected");
$(element).append(
⋮----
/**
             * This function adds newly created web service in the drop down
             * @param {string} element
             * @param {string} token
             * @param {string} id
             */
function add_new_token_in_select(element, token, id) {
⋮----
/**
             * This function handles the display of the service creation form depending on the drop down value.
             * @param {string} condition
             * @param {string} condition_var
             * @param {string} element
             * @param {string} btn
             */
function handlefieldsdisplay(
⋮----
$(btn).text(M.util.get_string("create", "auth_edwiserbridge"));
$(element).css("display", "flex");
⋮----
$(btn).text(M.util.get_string("link", "auth_edwiserbridge"));
$(element).css("display", "none");
⋮----
/**
             * This functions link the existing wervices
             * @param {string} service_id
             * @param {string} token
             * @param {string} common_errr_fld
             * @param {string} common_success_fld
             */
function link_web_service(
⋮----
$(common_success_fld).text(response.msg);
$(common_success_fld).css("display", "block");
⋮----
$(common_errr_fld).text(response.msg);
⋮----
}); //promise end
⋮----
$(document).on("click", ".eb_service_pop_up_close", function() {
$(".eb_service_pop_up").hide();
⋮----
/**
             * This functions regiters new web service.
             * @param {string} web_service_name
             * @param {string} user_id
             * @param {string} service_select_fld
             * @param {string} common_errr_fld
             * @param {boolean} is_mform
             */
function create_web_service(
⋮----
//Dialog box content.
⋮----
M.util.get_string("pop_up_info", "auth_edwiserbridge") +
⋮----
M.util.get_string("site_url", "auth_edwiserbridge") +
⋮----
M.util.get_string("click_to_copy", "auth_edwiserbridge") +
⋮----
M.util.get_string("copy", "auth_edwiserbridge") +
⋮----
M.util.get_string("token", "auth_edwiserbridge") +
⋮----
$("body").append(
⋮----
$(".eb_service_pop_up_content").html(eb_dialog_content);
$(".eb_service_pop_up").show();
⋮----
add_new_service_in_select(
⋮----
add_new_token_in_select(
⋮----
/************************  Functions END  ****************************/
⋮----
/******************    SETUP wizard   *****************/
⋮----
$("body").append(loader);
⋮----
/**
             * Change URL.
             * @param {string} step
             */
function change_url( step ) {
var url = new URL(document.location);
url.searchParams.set('current_step', step);
window.history.replaceState( null, null, url );
⋮----
/**
             * Handle step progress.
             * @param {string} current_step
             * @param {string} next_step
             * @param {string} is_next_sub_step
             * @param {string} parent_step
             */
function handle_step_progress( current_step, next_step, is_next_sub_step, parent_step ) {
/**
                 * 1. Mark current step as active and
                 * 2. Mark previous step as completed.
                 */
// Add completed class to the sidebar steps
var temp1 = $('.eb-setup-step-' + current_step).addClass('eb-setup-step-completed-wrap');
if( $('.eb-setup-step-' + current_step).hasClass('eb-setup-step-active-wrap') ) {
$('.eb-setup-step-' + current_step).removeClass('eb-setup-step-active-wrap');
⋮----
// Chnage step names class
var step_title = $('.eb-setup-step-' + current_step).children('.eb-setup-steps-title');
step_title.addClass('eb-setup-step-completed');
if(step_title.hasClass('eb-setup-step-active')){
step_title.removeClass('eb-setup-step-active');
⋮----
// Change icons class
var icon = $('.eb-setup-step-' + current_step).children('.eb_setup_sidebar_progress_icons');
icon.addClass('fa-circle-check');
⋮----
if( icon.hasClass('fa-circle-chevron-right') ) {
icon.removeClass('fa-circle-chevron-right');
⋮----
var temp2 = $('.eb-setup-step-' + next_step).addClass('eb-setup-step-active-wrap');
var step_title1 = $('.eb-setup-step-' + next_step).children('.eb-setup-steps-title');
step_title1.addClass('eb-setup-step-active');
⋮----
var icon = $('.eb-setup-step-' + next_step).children('.eb_setup_sidebar_progress_icons');
icon.addClass('fa-solid fa-circle-chevron-right');
⋮----
if(icon.hasClass('eb-setup-step-circle')){
icon.removeClass('eb-setup-step-circle');
⋮----
// ajax xall to save data and get new tab at the same time.
⋮----
// Clicking save continue
⋮----
$(document).on('click', '.eb_setup_save_and_continue', function (event) {
// Create loader.
var current = $(this);
var current_step = $(this).data('step');
var next_step = $(this).data('next-step');
var is_next_sub_step = $(this).data('is-next-sub-step');
⋮----
// get current step.
// get next step.
// get data which will be saved.
// Creating swicth case.
⋮----
$("#eb-lading-parent").show();
⋮----
// Get required data and create array
⋮----
var service_name = $('.eb_setup_web_service_list').val();
⋮----
// Course sync process.
// Call course sync callback and after completing the process, call this callback.
if( service_name == 'create' && '' == $('#eb_setup_web_service_name').val() ){
⋮----
$('#eb_setup_web_service_name').css('border-color', 'red');
⋮----
service_name = $('.eb_setup_web_service_name').val();
⋮----
if( '' != site_name && ( '' == $('#eb_setup_site_name').val() || '' == $('#eb_setup_site_url').val() ) ){
⋮----
if ( '' == $('#eb_setup_site_name').val() ) {
$('#eb_setup_site_name').css('border-color', 'red');
⋮----
$('#eb_setup_site_name').css('border-color', '#E5E5E5');
⋮----
if ( '' == $('#eb_setup_site_url').val() ) {
$('#eb_setup_site_url').css('border-color', 'red');
⋮----
$('#eb_setup_site_url').css('border-color', '#E5E5E5');
⋮----
var site_name = $('.eb_setup_wp_sites').val();
⋮----
site_name = $('.eb_setup_site_name').val();
url       = $('.eb_setup_site_url').val();
⋮----
var user_enrollment   = $('#eb_setup_sync_user_enrollment').prop('checked') ? 1 : 0;
var user_unenrollment = $('#eb_setup_sync_user_unenrollment').prop('checked') ? 1 : 0;
var user_creation     = $('#eb_setup_sync_user_creation').prop('checked') ? 1 : 0;
var user_deletion     = $('#eb_setup_sync_user_deletion').prop('checked') ? 1 : 0;
var user_update       = $('#eb_setup_sync_user_update').prop('checked') ? 1 : 0;
var course_creation   = $('#eb_setup_sync_course_creation').prop('checked') ? 1 : 0;
var course_deletion   = $('#eb_setup_sync_course_deletion').prop('checked') ? 1 : 0;
⋮----
// If user checkbox is clicked start user sync otherwise just procedd to next screen.
⋮----
data = JSON.stringify(data);
⋮----
promises[0].done(function(response) {
$("#eb-lading-parent").hide();
⋮----
change_url( next_step );
⋮----
// Dummy value.
⋮----
handle_step_progress( current_step, next_step, is_next_sub_step, parent_step );
⋮----
$('.eb-setup-header-title').html(response.title);
$('.eb-setup-content').html(response.html_data);
⋮----
$('.eb-setup-content').append(
⋮----
$('.eb_setup_wp_completion_success_popup').html() +
⋮----
setTimeout(function(){
$('.eb_setup_popup').remove();
⋮----
}).fail(function(response) {
⋮----
// Adding for refresh page condition
if ( $(".eb_setup_wp_completion_success_popup").length) {
⋮----
/*
            * Ajax call to enable settings.
            */
$(document).on('click', '.eb_enable_plugin_settings', function (event) {
// start loader
⋮----
// stop loader.
// change icon colors
$('.eb_enable_rest_protocol').css( 'color', '#1AB900' );
$('.eb_enable_web_service').css( 'color', '#1AB900' );
$('.eb_disable_pwd_policy').css( 'color', '#1AB900' );
$('.eb_allow_extended_char').css( 'color', '#1AB900' );
⋮----
// show success message.
$('.eb_setup_settings_success_msg').css( 'display', 'block' );
⋮----
// Hide current button and show save and continue button
$('.eb_enable_plugin_settings').css( 'display', 'none' );
$('.eb_enable_plugin_settings_label').css( 'display', 'none' );
$('.eb_setup_save_and_continue').css( 'display', 'initial' );
⋮----
var acc = document.getElementsByClassName("accordion");
⋮----
acc[i].addEventListener("click", function() {
/* Toggle between adding and removing the "active" class,
                to highlight the button that controls the panel */
this.classList.toggle("active");
⋮----
/* Toggle between hiding and showing the active panel */
⋮----
// Handle Setup web service dropdown.
// $(".eb_setup_web_service_list").change(function() {
$(document).on('change', '.eb_setup_web_service_list', function (event) {
⋮----
if('' != $(".eb_setup_web_service_list").val()){
$('.eb_setup_web_service_btn').removeClass('disabled');
$('.eb_setup_web_service_btn').removeAttr("disabled");
⋮----
$('.eb_setup_web_service_btn').attr("disabled", "disabled");
$('.eb_setup_web_service_btn').addClass('disabled');
⋮----
if('create' == $(".eb_setup_web_service_list").val()){
$('.eb_setup_web_service_name_wrap').css('display', 'block');
⋮----
$('.eb_setup_web_service_name_wrap').css('display', 'none');
⋮----
// Handle Wp site drop down
// $(".eb_setup_wp_sites").change(function() {
$(document).on('change', '.eb_setup_wp_sites', function (event) {
⋮----
$('.eb_setup_wp_details_btn').removeClass('disabled');
$('.eb_setup_wp_details_btn').removeAttr("disabled");
⋮----
$('.eb_setup_wp_details_btn').attr("disabled", "disabled");
$('.eb_setup_wp_details_btn').addClass('disabled');
⋮----
if('' == $(".eb_setup_wp_sites").val()){
$('.eb_setup_wp_site_details_inp').addClass('eb_setup_wp_site_details_wrap');
⋮----
$('.eb_setup_wp_site_details_inp').removeClass('eb_setup_wp_site_details_wrap');
⋮----
var option = $(this).find(":selected");
⋮----
$('.eb_setup_site_name').val(option.data('name'));
$('.eb_setup_site_url').val(option.data('url'));
⋮----
$(document).on('click', '.eb_setup_test_connection_btn', function (event) {
⋮----
var url = $('.eb_setup_site_url').val();
$("body").css("cursor", "wait");
⋮----
$('.eb_setup_test_conn_resp_msg').css('display', 'block');
⋮----
// Parse response.
⋮----
$('.eb_setup_test_connection_continue_btn').css('display', 'inline-block');
$('.eb_setup_test_connection_btn').css('display', 'none');
⋮----
$('.eb_setup_test_conn_resp_msg').addClass('eb_setup_settings_success_msg');
$('.eb_setup_test_conn_resp_msg').html('<i class="fa-solid fa-circle-check"></i> ' + response.msg);
$('.eb_setup_test_conn_resp_msg').removeClass('eb_setup_error_msg_box');
⋮----
$('.eb_setup_test_conn_resp_msg').addClass('eb_setup_error_msg_box');
⋮----
$('.eb_setup_test_conn_resp_msg').removeClass('eb_setup_settings_success_msg');
⋮----
$(document).on('click', '#eb_setup_sync_all', function (event) {
⋮----
$('.eb_setup_sync_cb').prop('checked', true);
⋮----
$('.eb_setup_sync_cb').prop('checked', false);
⋮----
$(document).on('click', '.eb_setup_sync_cb', function (event) {
⋮----
$(".eb_setup_sync_cb").each(function() {
⋮----
$('#eb_setup_sync_all').prop('checked', true);
⋮----
$('#eb_setup_sync_all').prop('checked', false);
⋮----
$(document).on("click", ".eb_setup_copy", function(event) {
⋮----
var copyText = $(this).data('copy');
⋮----
M.util.get_string("copied", "auth_edwiserbridge") + '</p>';
⋮----
$(this).append(copy_success);
⋮----
// Remove success message after 2 seconds
setTimeout(() => {
$(".eb_setup_copy_success").fadeOut(300, function() {
$(this).remove();
⋮----
// Code to create json file and download it.
$(document).on("click", ".eb_setup_download_creds", function(event) {
⋮----
url: $('.eb_setup_copy_url').html(),
token: $('.eb_setup_copy_token').html(),
lang_code: $('.eb_setup_copy_lang').html(),
⋮----
$("<a />", {
⋮----
"href" : "data:application/json," + encodeURIComponent(JSON.stringify( obj ) )
}).appendTo("body").click(function() {
⋮----
})[0].click();
⋮----
/**
         * Close setup.
         */
$('.eb-setup-close-icon').click(function(){
⋮----
$('.eb-setup-content').append('<div class="eb_setup_popup"> ' + $('.eb_setup_popup_content_wrap').html() + ' </div>');
⋮----
$(document).on('click', '.eb_setup_do_not_close', function (event) {
⋮----
$(document).on('click', '.eb_redirect_to_wp', function (event) {
⋮----
// Sending one js request to unset the progress.
⋮----
$('.eb-setup-content').append('<div class="eb_setup_popup"> ' + $('.eb_setup_wp_redirection_popup').html() + ' </div>');
⋮----
setTimeout( function(){
⋮----
// window.location.replace($(this).attr('href'));
$('.eb_redirect_to_wp_btn').trigger('click');
⋮----
var redirect = window.open($('.eb_redirect_to_wp').attr('href'), "_blank");
redirect.focus();
⋮----
/***************************/

================
File: amd/src/sso_settings.js
================
/* eslint-disable no-unused-vars */
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
/**
 * Js file to handle settings.
 *
 * @package
 * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @author      Wisdmlabs
 * @module      auth_edwiserbridge/sso_settings
 */
⋮----
define("auth_edwiserbridge/eb_sso_settings", [
⋮----
/**
     * Load SSO settings.
     */
function load_settings() {
$(document).ready(function () {
$('#id_secret_key_generate').on('click', function (event) {
event.preventDefault();
⋮----
text += possible.charAt(Math.floor(Math.random() * possible.length));
⋮----
$('#id_sharedsecret').val(text);

================
File: classes/external/api.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Extends the external API of the Edwiser Bridge plugin.
 * This file aggregates all the external functions.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_api;
⋮----
/**
 * Provides an external API for the Edwiser Bridge plugin.
 * This class aggregates all the external functions of the plugin.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class api extends external_api {
⋮----
// SSO functions.
⋮----
// Bulk purchase functions.

================
File: classes/external/create_service.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Create external service.
 * Functionality to create new external service.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_single_structure;
use core_external\external_value;
use auth_edwiserbridge;
use core\context\system as context_system;
use core_external\external_function_parameters;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_create_service
 */
trait create_service {
⋮----
/**
     * Functionality to create a new external service.
     *
     * @param string $webservicename The name of the web service to create.
     * @param int $userid The ID of the user to associate with the web service.
     * @return array An array containing the details of the created web service.
     */
public static function auth_edwiserbridge_create_service($webservicename, $userid) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$settingshandler = new auth_edwiserbridge\local\settings_handler();
$response = $settingshandler->eb_create_externle_service($webservicename, $userid);
⋮----
/**
     * Defines the parameters for the auth_edwiserbridge_create_service external function.
     *
     * This function returns an external_function_parameters object that defines the
     * parameters required for the auth_edwiserbridge_create_service function.
     *
     * @return external_function_parameters The parameters for the
     *         auth_edwiserbridge_create_service function.
     */
public static function auth_edwiserbridge_create_service_parameters() {
⋮----
/**
     * Defines the structure of the return value for the auth_edwiserbridge_create_service external function.
     *
     * This function returns an external_single_structure object that defines the
     * structure of the array that will be returned by the auth_edwiserbridge_create_service function.
     *
     * @return external_single_structure The structure of the return value for the
     *         auth_edwiserbridge_create_service function.
     */
public static function auth_edwiserbridge_create_service_returns() {

================
File: classes/external/delete_cohort.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Delete cohort.
 * Functionality to delete cohort.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use Exception;
use core\context\system as context_system;
use core\context\user as context_user;
use core\exception\moodle_exception as moodle_exception;
use core\context as context;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_delete_cohort
 */
trait delete_cohort {
/**
     * Returns the description of the method parameters for the auth_edwiserbridge_delete_cohort function.
     *
     * @return external_function_parameters The description of the method parameters.
     */
public static function auth_edwiserbridge_delete_cohort_parameters() {
⋮----
/**
     * Deletes cohorts and returns the status of the operation.
     *
     * @param array $cohort An array of cohort IDs to be deleted.
     * @return array An associative array containing the status of the operation. The "status" key will be:
     *               - 1 if all cohorts were successfully deleted.
     *               - 0 if there was any error during the deletion process.
     */
public static function auth_edwiserbridge_delete_cohort($cohort) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
// Parameter validation.
$params = self::validate_parameters(
self::auth_edwiserbridge_delete_cohort_parameters(),
⋮----
// Context validation.
$context = context_user::instance($USER->id);
self::validate_context($context);
⋮----
// Capability checking.
⋮----
$cohort = $DB->get_record('cohort', ['id' => $cohortdetails["cohortid"]], '*', MUST_EXIST);
⋮----
$context = context::instance_by_id($cohort->contextid, MUST_EXIST);
⋮----
/**
     * Returns the external structure for the connection status.
     *
     * @return external_single_structure External structure containing:
     *                                   - status (int): Operation status (1 for success, 0 for failure)
     *                                   - message (string): Status message
     */
public static function auth_edwiserbridge_delete_cohort_returns() {

================
File: classes/external/enable_plugin_settings.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Enable plugin settings.
 * Functionality to enable mandatory plugin settings.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_enable_plugin_settings
 */
trait enable_plugin_settings {
/**
     * Returns the parameter description of the auth_edwiserbridge_enable_plugin_settings() function.
     *
     * @return external_function_parameters The parameter description.
     */
public static function auth_edwiserbridge_enable_plugin_settings_parameters() {
⋮----
/**
     * Enables the mandatory plugin settings for the Edwiser Bridge authentication plugin.
     *
     * This function performs the following actions:
     * - Validates the system context
     * - Ensures the REST web service protocol is enabled
     * - Enables the web services feature
     * - Disables the password policy
     * - Allows extended user name characters
     * - Returns an array of the enabled settings
     *
     * @return array An array containing the enabled plugin settings
     */
public static function auth_edwiserbridge_enable_plugin_settings() {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
// Call the function to get the list of protocols
⋮----
/**
     * Returns the description of the result value for the auth_edwiserbridge_enable_plugin_settings() function.
     *
     * @return external_single_structure The description of the result value.
     */
public static function auth_edwiserbridge_enable_plugin_settings_returns() {

================
File: classes/external/get_course_enrollment_method.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Get course enrollment method.
 * Functionality to get course enrollment method.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_function_parameters;
use core\context\system as context_system;
use core\exception\moodle_exception as moodle_exception;
use Exception;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_get_course_enrollment_method
 */
trait get_course_enrollment_method {
/**
     * Returns the description of the parameters for the auth_edwiserbridge_get_course_enrollment_method() external function.
     *
     * @return external_function_parameters The description of the function parameters.
     */
public static function auth_edwiserbridge_get_course_enrollment_method_parameters() {
⋮----
/**
     * Get list of active course enrolment methods for current user.
     *
     * This function retrieves the list of active course enrolment methods for the current user. It first validates the system context and checks if the Moodle manual enrolment plugin is enabled. If the plugin is disabled, it throws a moodle_exception. Otherwise, it retrieves the list of active manual enrolment instances from the database and returns an array containing the course IDs and a flag indicating if manual enrolment is enabled for each course.
     *
     * @return array An array of course enrolment methods, where each element is an associative array with the following keys:
     *               - courseid (int): The ID of the course.
     *               - enabled (int): 1 if manual enrolment is enabled for the course, 0 otherwise.
     * @throws moodle_exception If the Moodle manual enrolment plugin is disabled.
     */
public static function auth_edwiserbridge_get_course_enrollment_method() {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
// Check if Moodle manual enrollment plugin is disabled.
⋮----
$result = $DB->get_records('enrol', ['status' => 0, 'enrol' => 'manual'], 'sortorder,id');
⋮----
/**
     * Returns the external structure for course enrollment methods.
     *
     * @return external_multiple_structure Array of external_single_structure, each containing:
     *                                      - courseid (int): ID of the course.
     *                                      - enabled (int): Returns 1 if manual enrolment is enabled, 0 if disabled.
     */
public static function auth_edwiserbridge_get_course_enrollment_method_returns() {

================
File: classes/external/get_course_progress.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Get course progress.
 * Functionality to get course progress data.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use completion_info;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_function_parameters;
use core\context\course as context_course;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_get_course_progress
 */
trait get_course_progress {
⋮----
/**
     * Functionality to get course progress data for the given user.
     *
     * @param string $userid the user id.
     * @return array an array of course progress data.
     */
public static function auth_edwiserbridge_get_course_progress($userid) {
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_get_course_progress_parameters(),
⋮----
$result = $DB->get_records_sql(
⋮----
// Validation for context is needed.
$coursecontext = context_course::instance($value->course);
self::validate_context($coursecontext);
⋮----
$iscomplete = $cinfo->is_course_complete( $params['user_id'] );
⋮----
/**
     * Defines the parameters for the auth_edwiserbridge_get_course_progress function.
     *
     * @return external_function_parameters The parameters for the function.
     */
public static function auth_edwiserbridge_get_course_progress_parameters() {
⋮----
/**
     * Returns the structure of the course progress data.
     *
     * This function defines the structure of the data that will be returned by the
     * auth_edwiserbridge_get_course_progress function. It specifies that the
     * returned data will be an array of objects, where each object has two
     * properties: 'course_id' (a text value) and 'completion' (an integer value).
     *
     * @return external_multiple_structure The structure of the course progress data.
     */
public static function auth_edwiserbridge_get_course_progress_returns() {

================
File: classes/external/get_courses.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Get courses list.
 * Functionality to get courses list(with limited data) from moodle.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
/**
 * Trait implementing the external function auth_edwiserbridge_get_courses
 */
trait get_courses {
⋮----
/**
     * Functionality to get courses in chunk.
     *
     * @param int $offset Offset for the course list.
     * @param int $limit Limit the number of courses to return.
     * @param string $searchstring Search string to filter the courses.
     * @param int $totalcourses Flag to indicate if the total course count should be returned.
     * @return array Array of courses.
     */
public static function auth_edwiserbridge_get_courses($offset, $limit, $searchstring, $totalcourses) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_get_courses_parameters(),
⋮----
$courses = $DB->get_records_sql($query, $paramsql, $offset, $limit);
⋮----
$coursecount = $DB->get_record_sql($count_query);
⋮----
/**
     * Defines the parameters for the auth_edwiserbridge_get_courses external function.
     *
     * This function returns an external_function_parameters object that defines the
     * expected parameters for the auth_edwiserbridge_get_courses function. The
     * parameters include:
     *
     * - offset: The offset for the course list.
     * - limit: The maximum number of courses to return.
     * - search_string: A search string to filter the courses.
     * - total_courses: A flag to indicate if the total course count should be returned.
     *
     * @return external_function_parameters The parameters for the
     *         auth_edwiserbridge_get_courses function.
     */
public static function auth_edwiserbridge_get_courses_parameters() {
⋮----
/**
     * Defines the return structure for the auth_edwiserbridge_get_courses external function.
     *
     * This function returns an external_function_parameters object that defines the
     * expected return structure for the auth_edwiserbridge_get_courses function. The
     * return structure includes:
     *
     * - total_courses: The total number of courses.
     * - courses: An array of course information, including the course ID, full name, and category ID.
     *
     * @return external_function_parameters The return structure for the
     *         auth_edwiserbridge_get_courses function.
     */
public static function auth_edwiserbridge_get_courses_returns() {

================
File: classes/external/get_edwiser_plugins_info.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Get Edwiser plugins info.
 * Functionality to get Edwiser plugins info installed on Moodle.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
// use core\plugin_manager as core_plugin_manager;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_course_progress_data
 */
trait get_edwiser_plugins_info {
/**
     * Retrieves information about Edwiser plugins installed on the Moodle site.
     *
     * This function checks the installed authentication plugins and the Edwiser Bridge Pro
     * license status to gather information about the Edwiser plugins. It returns an array
     * containing the plugin names and versions.
     *
     * @return array An array with information about the installed Edwiser plugins.
     */
public static function auth_edwiserbridge_get_edwiser_plugins_info() {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$pluginman   = \core_plugin_manager::instance();
⋮----
$authplugin = $pluginman->get_plugins_of_type('auth');
⋮----
// Check licensing.
$license = new \auth_edwiserbridge\local\eb_pro_license_controller();
if ($license->get_data_from_db() == 'available') {
⋮----
/**
     * Returns the parameters for the auth_edwiserbridge_get_edwiser_plugins_info function.
     *
     * This function does not take any parameters, as the function it documents
     * retrieves information about the installed Edwiser plugins without requiring
     * any input from the caller.
     *
     * @return external_function_parameters The parameters for the
     *         auth_edwiserbridge_get_edwiser_plugins_info function.
     */
public static function auth_edwiserbridge_get_edwiser_plugins_info_parameters() {
⋮----
/**
     * Returns the structure of the response for the auth_edwiserbridge_get_edwiser_plugins_info function.
     *
     * This function defines the structure of the response that will be returned by the
     * auth_edwiserbridge_get_edwiser_plugins_info function. It specifies that the response
     * will be a single structure containing a 'plugins' field, which is a multiple structure
     * containing individual plugin information with 'plugin_name' and 'version' fields.
     *
     * @return external_single_structure The structure of the response for the
     *         auth_edwiserbridge_get_edwiser_plugins_info function.
     */
public static function auth_edwiserbridge_get_edwiser_plugins_info_returns() {

================
File: classes/external/get_mandatory_settings.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Get mandatory settings.
 * Functionality to get mandatory settings.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_get_mandatory_settings
 */
trait get_mandatory_settings {
/**
     * Retrieves the mandatory settings for the Edwiser Bridge authentication plugin.
     *
     * This function fetches the necessary settings from the Moodle configuration and
     * returns them as an associative array. The settings include the REST protocol
     * status, web service status, password policy, extended character support, student
     * role ID, and the language code.
     *
     * @return array An associative array containing the mandatory settings.
     */
public static function auth_edwiserbridge_get_mandatory_settings() {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
⋮----
self::validate_context($systemcontext);
⋮----
// Get all settings and form array.
⋮----
// Get rest_protocol settings.
⋮----
// Get web_service settings.
⋮----
// Get password policy settings.
⋮----
// Get allow_extended_char settings.
⋮----
// Get Role ID of student role.
⋮----
// Get roles where the archetype is defined.
$studentroles = $DB->get_records('role', ['archetype' => 'student']);
⋮----
// Assuming the first role in the list is the one we want
⋮----
// Handle the case where no 'student' archetype role is found
⋮----
// Get lang_code settings.
⋮----
/**
     * Returns the parameters for the auth_edwiserbridge_get_mandatory_settings external function.
     *
     * This function does not take any parameters, as it is used to retrieve the mandatory settings
     * for the Edwiser Bridge authentication plugin.
     *
     * @return external_function_parameters The parameters for the external function.
     */
public static function auth_edwiserbridge_get_mandatory_settings_parameters() {
⋮----
/**
     * Returns the structure of the mandatory settings for the Edwiser Bridge authentication plugin.
     *
     * This function is used to define the structure of the settings that will be returned by the
     * auth_edwiserbridge_get_mandatory_settings external function. It includes settings such as
     * the REST protocol, web service, password policy, language code, and student role ID.
     *
     * @return external_single_structure The structure of the mandatory settings.
     */
public static function auth_edwiserbridge_get_mandatory_settings_returns() {

================
File: classes/external/get_service_info.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Get service info.
 * Functionality to get added webservice functions for a web service.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_get_service_info
 */
trait get_service_info {
⋮----
/**
     * Functionality to link existing services.
     *
     * @param int $serviceid Service ID.
     * @return array Response array with status and message.
     */
public static function auth_edwiserbridge_get_service_info($serviceid) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
/**
     * Defines the parameters for the auth_edwiserbridge_get_service_info external function.
     *
     * @return external_function_parameters The parameters for the external function.
     */
public static function auth_edwiserbridge_get_service_info_parameters() {
⋮----
/**
     * Returns the parameters that will be returned from the get_service_info function.
     *
     * @return external_single_structure The structure of the returned parameters.
     */
public static function auth_edwiserbridge_get_service_info_returns() {

================
File: classes/external/get_site_data.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Get site specific synch settings.
 * Functionality to get site specific synchrnoization settings.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_get_site_data
 */
trait get_site_data {
⋮----
/**
     * Retrieves site-specific synchronization settings.
     *
     * @param string $siteindex The index of the site to retrieve settings for.
     * @return array An array of site-specific synchronization settings.
     */
public static function auth_edwiserbridge_get_site_data($siteindex) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_get_site_data_parameters(),
⋮----
/**
     * Defines the parameters for the auth_edwiserbridge_get_site_data function.
     *
     * @return external_function_parameters The parameters for the auth_edwiserbridge_get_site_data function.
     */
public static function auth_edwiserbridge_get_site_data_parameters() {
⋮----
/**
     * Defines the return structure for the auth_edwiserbridge_get_site_data function.
     * This structure includes various synchronization settings for the site, such as
     * course enrollment, user creation, and course creation.
     *
     * @return external_single_structure The return structure for the auth_edwiserbridge_get_site_data function.
     */
public static function auth_edwiserbridge_get_site_data_returns() {

================
File: classes/external/get_users.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Get users list.
 * Functionality to get users list in chunks.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_get_users
 */
trait get_users {
⋮----
/**
     * Functionality to get users list in chunks.
     *
     * @param int $offset Offset for the user list.
     * @param int $limit Limit for the number of users to retrieve.
     * @param string $searchstring Search string to filter the users.
     * @param int $totalusers Flag to retrieve the total number of users.
     * @return array Array of users.
     */
public static function auth_edwiserbridge_get_users($offset, $limit, $searchstring, $totalusers) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_get_users_parameters(),
⋮----
$users = $DB->get_records_sql($query, $paramsql, $offset, $limit);
⋮----
$usercount = $DB->get_record_sql($count_query);
⋮----
/**
     * Defines the parameters for the auth_edwiserbridge_get_users external function.
     *
     * This function returns an external_function_parameters object that defines the
     * parameters for the auth_edwiserbridge_get_users function. The parameters
     * include:
     *
     * - offset: The offset for the user list.
     * - limit: The limit for the number of users to retrieve.
     * - search_string: The search string to filter the users.
     * - total_users: A flag to retrieve the total number of users.
     *
     * @return external_function_parameters The parameters for the
     *         auth_edwiserbridge_get_users function.
     */
public static function auth_edwiserbridge_get_users_parameters() {
⋮----
/**
     * Defines the return parameters for the auth_edwiserbridge_get_users function.
     *
     * This function returns an array with two keys:
     * - 'total_users': an integer representing the total number of users
     * - 'users': an array of user objects, each with the following properties:
     *   - 'id': the user's ID
     *   - 'username': the user's username
     *   - 'firstname': the user's first name
     *   - 'lastname': the user's last name
     *   - 'email': the user's email address
     * 
     * @return external_function_parameters The return structure for the auth_edwiserbridge_get_users function.
     */
public static function auth_edwiserbridge_get_users_returns() {

================
File: classes/external/link_service.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Link service.
 * Functionality to link existing services.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use auth_edwiserbridge;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_link_service
 */
trait link_service {
⋮----
/**
     * Functionality to link existing services.
     *
     * @param string $serviceid The ID of the service to link.
     * @param int $token The token associated with the service.
     * @return array An array containing the status and message of the linking operation.
     */
public static function auth_edwiserbridge_link_service($serviceid, $token) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$settingshandler = new auth_edwiserbridge\local\settings_handler();
$result           = $settingshandler->eb_link_exitsing_service($serviceid, $token);
⋮----
/**
     * Defines the parameters for the auth_edwiserbridge_link_service external function.
     *
     * @return external_function_parameters The parameters for the link service function.
     */
public static function auth_edwiserbridge_link_service_parameters() {
⋮----
/**
     * Defines the return structure for the auth_edwiserbridge_link_service external function.
     *
     * @return external_single_structure The return structure for the link service function.
     */
public static function auth_edwiserbridge_link_service_returns() {

================
File: classes/external/manage_cohort_enrollment.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Manage cohort enrollment.
 * Functionality to manage cohort enrollment in course.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
use core\context\user as context_user;
use core\exception\moodle_exception as moodle_exception;
use core\output\progress_trace\null_progress_trace as null_progress_trace;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_manage_cohort_enrollment
 */
trait manage_cohort_enrollment {
/**
     * Returns the description of the method parameters for the auth_edwiserbridge_manage_cohort_enrollment function.
     *
     * @return external_function_parameters The description of the method parameters.
     */
public static function auth_edwiserbridge_manage_cohort_enrollment_parameters() {
⋮----
/**
     * Manages cohort enrollment for courses.
     * 
     * @param array $cohort Details of the cohort and course for enrollment/un-enrollment.
     * @return int|string The instance ID if successful enrollment is added, or "disabled" if cohort enrollment is disabled.
     */
public static function auth_edwiserbridge_manage_cohort_enrollment($cohort) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
// Parameter validation.
$params = self::validate_parameters(
self::auth_edwiserbridge_manage_cohort_enrollment_parameters(),
⋮----
// Context validation.
$context = context_user::instance($USER->id);
self::validate_context($context);
⋮----
// Capability checking.
⋮----
$enrol->delete_instance($instance);
⋮----
// Not enabled.
⋮----
$course = $DB->get_record('course', ['id' => $courseid]);
⋮----
// Already enrolled.
⋮----
$instance['status'] = ENROL_INSTANCE_ENABLED; // Enable it.
$instance['customint1'] = $cohortid; // Used to store the cohort id.
$instance['roleid'] = 5; // Default role for cohort enrol which is usually student.
$instance['customint2'] = 0; // Optional group id.
$instanceid = $enrol->add_instance($course, $instance);
⋮----
// Sync the existing cohort members.
⋮----
$trace->finished();
⋮----
/**
     * Returns the description of the method result value.
     *
     * @return external_value The ID of the instance as an integer.
     */
public static function auth_edwiserbridge_manage_cohort_enrollment_returns() {

================
File: classes/external/manage_user_cohort_enrollment.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Manage user cohort enrollment.
 * Functionality to manage user enrollments in courses.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_manage_user_cohort_enrollment
 */
trait manage_user_cohort_enrollment {
/**
     * Returns the description of the parameters for the auth_edwiserbridge_manage_user_cohort_enrollment external function.
     *
     * This function defines the parameters that can be passed to the auth_edwiserbridge_manage_user_cohort_enrollment function,
     * including the cohort ID and an array of user data (firstname, lastname, password, username, email).
     *
     * @return external_function_parameters The description of the function parameters.
     */
public static function auth_edwiserbridge_manage_user_cohort_enrollment_parameters() {
⋮----
/**
     * Enrolls users in a specified cohort.
     *
     * This function checks if the cohort exists, and then processes the provided user data.
     * If the user does not exist, it creates a new user account. It then adds the user to the specified cohort.
     * The function returns an array containing information about the enrollment process, including any errors that occurred.
     *
     * @param int $cohortid The ID of the cohort to enroll users in.
     * @param array $users An array of user data, including firstname, lastname, password, username, and email.
     * @return array An array containing the following keys:
     *   - error: 0 if successful, 1 if an error occurred.
     *   - error_msg: A string describing the error, if any.
     *   - users: An array of user enrollment information, including user_id, username, password, email, enrolled, cohort_id, and creation_error.
     */
public static function auth_edwiserbridge_manage_user_cohort_enrollment($cohortid, $users) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
// Check if the user has the capability to assign users to a cohort.
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_manage_user_cohort_enrollment_parameters(),
⋮----
// Check if cohort exists.
if (!$DB->record_exists('cohort', ['id' => $params['cohort_id']])) {
⋮----
// Create user if the new user does not exist.
⋮----
$existinguser = $DB->get_record('user', ['email' => $user['email']], '*');
⋮----
// Check if email exists if yes then dont create new user.
⋮----
// Create new user.
// check if the user name is available for new user.
⋮----
while ($DB->record_exists('user', ['username' => $user['username']])) {
⋮----
// Unable to create user.
⋮----
// Add User to cohort.
if (!$DB->record_exists('cohort_members', ['cohortid' => $params['cohort_id'], 'userid' => $userid])) {
⋮----
/**
     * Returns the description of the method result value for the
     * auth_edwiserbridge_manage_user_cohort_enrollment function.
     *
     * @return external_function_parameters The description of the method result value.
     */
public static function auth_edwiserbridge_manage_user_cohort_enrollment_returns() {

================
File: classes/external/setup_test_connection.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Setup Wizard Test Connection.
 * Functionality to test connection in setup wizard.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_setup_test_connection
 */
trait setup_test_connection {
⋮----
/**
     * Request to test connection
     *
     * @param string $wpurl WordPress URL to test the connection against.
     * @return array An array containing the status and message of the connection test.
     */
public static function auth_edwiserbridge_setup_test_connection($wpurl) {
⋮----
include_once($CFG->libdir . '/filelib.php'); // Include Moodle's curl class.
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_setup_test_connection_parameters(),
⋮----
// Use Moodle's curl class.
$curl = new \curl();
⋮----
// Construct the User-Agent string.
⋮----
// Set custom headers.
$curl->setHeader('User-Agent: ' . $useragent);
⋮----
// Set additional options.
⋮----
'CURLOPT_SSL_VERIFYPEER' => false, // Skip SSL verification.
⋮----
// Execute a GET request.
$response = $curl->get($requesturl, [], $options);
⋮----
// Decode the response.
⋮----
// Check if the response is valid JSON.
⋮----
/**
     * Defines the parameters for the auth_edwiserbridge_setup_test_connection function.
     *
     * This function returns the parameters required for the auth_edwiserbridge_setup_test_connection
     * function, which is used to test the connection to the WordPress site.
     *
     * @return external_function_parameters The parameters for the auth_edwiserbridge_setup_test_connection function.
     */
public static function auth_edwiserbridge_setup_test_connection_parameters() {
⋮----
/**
     * Returns the parameters that will be returned from the test connection function.
     *
     * This function defines the structure of the return value for the
     * auth_edwiserbridge_setup_test_connection function, which is used to test the
     * connection to the WordPress site. The return value includes a status and a
     * message.
     *
     * @return external_single_structure The parameters that will be returned from the test connection function.
     */
public static function auth_edwiserbridge_setup_test_connection_returns() {

================
File: classes/external/setup_wizard_save_and_continue.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Setup Wizard Save and Continue.
 * Functionality to save and continue setup wizard steps data.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
namespace auth_edwiserbridge\external;
⋮----
use auth_edwiserbridge;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_setup_wizard_save_and_continue
 */
trait setup_wizard_save_and_continue {
⋮----
/**
     * Returns the parameter description for the auth_edwiserbridge_setup_wizard_save_and_continue external function.
     *
     * @return external_function_parameters The parameter description.
     */
public static function auth_edwiserbridge_setup_wizard_save_and_continue_parameters() {
⋮----
/**
     * Saves and continues the setup wizard steps data.
     *
     * @param string $data The data to be saved and continued.
     * @return void
     */
public static function auth_edwiserbridge_setup_wizard_save_and_continue($data) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$PAGE->set_context(context_system::instance());
⋮----
$setupwizardhandler = new auth_edwiserbridge\local\setup_wizard();
$steps = $setupwizardhandler->eb_setup_wizard_get_steps();
⋮----
// Check if there are any sub steps available.
⋮----
// Save progress data.
⋮----
// Create web service and update data in EB settings.
$settingshandler = new auth_edwiserbridge\local\settings_handler();
// Get main admin user.
⋮----
$response = $settingshandler->eb_create_externle_service( $data->service_name , $adminuser->id );
⋮----
// Set Service. edwiser_bridge_last_created_token.
⋮----
// Select token update web services and set token.
// If token is not created dreate token.
$token = $settingshandler->eb_create_token( $data->service_name, $adminuser->id );
⋮----
// Set last created token.
⋮----
// Get existing data.
⋮----
// Update Moodle Wordpress site details.
⋮----
// Get next step.
⋮----
/*
        * There are multiple steps inside 1 step which are listed below.
        * 1. Web sevice
        *    a. web service
        *    b. WP site details
        *
        * 2. user and course sync
        *    a. User and course sync
        *    b. success screens
        */
⋮----
$title          = $setupwizardhandler->eb_get_step_title($nextstep);
⋮----
/**
     * Returns the description of the result value for the auth_edwiserbridge_setup_wizard_save_and_continue() function.
     *
     * @return external_single_structure The structure describing the result value, which contains the HTML content for the next setup wizard step and the title of that step.
     */
public static function auth_edwiserbridge_setup_wizard_save_and_continue_returns() {

================
File: classes/external/test_connection.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Test connection.
 * Functionality to test wordpress and moodle connection.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_test_connection
 */
trait test_connection {
⋮----
/**
     * Request to test connection
     *
     * @param string $wpurl   wpurl.
     * @param string $wptoken wptoken.
     * @param string $testconnection Test connection type, defaults to "moodle".
     *
     * @return array
     */
public static function auth_edwiserbridge_test_connection($wpurl, $wptoken, $testconnection = "moodle") {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_test_connection_parameters(),
⋮----
// Get webservice id by token.
⋮----
$serviceid = $DB->get_field('external_tokens', 'externalserviceid', ['token' => $params["wp_token"]]);
⋮----
$response   = $apihandler->connect_to_wp_with_args($params["wp_url"], $requestdata);
⋮----
// Test connection error messages.
// 1. Wrong token don't show detailed message.
// 2. Redirection or other isues will show detailed error message.
⋮----
/**
     * Defines the parameters for the 'auth_edwiserbridge_test_connection' web service function.
     *
     * This function returns an external_function_parameters object that defines the parameters
     * for the 'auth_edwiserbridge_test_connection' web service function. The parameters include:
     *
     * - 'wp_url': The URL of the WordPress site to test the connection with.
     * - 'wp_token': The token used to authenticate the connection to the WordPress site.
     * - 'test_connection': The text to be used for the 'test_connection' parameter, with a default value of 'moodle'.
     *
     * @return external_function_parameters The parameters for the 'auth_edwiserbridge_test_connection' web service function.
     */
public static function auth_edwiserbridge_test_connection_parameters() {
⋮----
/**
     * Defines the return parameters for the 'auth_edwiserbridge_test_connection' web service function.
     *
     * This function returns an external_single_structure object that defines the parameters
     * that will be returned by the 'auth_edwiserbridge_test_connection' web service function.
     * The returned parameters include:
     *
     * - 'status': The status of the connection test, as a text value.
     * - 'msg': The message returned from the connection test, as a raw value.
     * - 'warnings': An optional array of warning messages, as text values.
     *
     * @return external_single_structure The return parameters for the 'auth_edwiserbridge_test_connection' web service function.
     */
public static function auth_edwiserbridge_test_connection_returns() {

================
File: classes/external/update_course_enrollment_method.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Update course enrollment method.
 * Functionality to update course enrollment method from WordPress.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\course as context_course;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_update_course_enrollment_method
 */
trait update_course_enrollment_method {
/**
     * Update the course enrollment method for the specified course ID.
     *
     * This function is used to update the enrollment method for a course, typically from an external system like WordPress.
     *
     * @param int $courseid The ID of the course to update the enrollment method for.
     * @return array An array containing the course ID and the status of the update operation.
     * @throws moodle_exception If there is an error validating the context or parameters.
     */
public static function auth_edwiserbridge_update_course_enrollment_method($courseid) {
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_update_course_enrollment_method_parameters(),
⋮----
// Include manual enrollment file.
⋮----
// Validation for context is needed.
$coursecontext = context_course::instance( $singlecourseid );
self::validate_context($coursecontext);
⋮----
// Add enrolment instance.
$enrolinstance = new \enrol_manual_plugin();
⋮----
$course = $DB->get_record('course', ['id' => $singlecourseid]);
$status = $enrolinstance->add_instance($course);
⋮----
// Get manual enrolment instance id.
// Other plugin instances are also available.
⋮----
$enrolinstance->update_status($instance[$instanceid], ENROL_INSTANCE_ENABLED);
⋮----
/**
     * Returns the parameters for the auth_edwiserbridge_update_course_enrollment_method() function.
     *
     * This function defines the parameters that can be passed to the
     * auth_edwiserbridge_update_course_enrollment_method() function, which is used to update the
     * course enrollment method.
     *
     * @return external_function_parameters The parameters for the function.
     */
public static function auth_edwiserbridge_update_course_enrollment_method_parameters() {
⋮----
/**
     * Returns the description of the result value for the auth_edwiserbridge_update_course_enrollment_method() function.
     *
     * The result is a multiple structure containing a single structure with the following fields:
     *
     * - courseid: The ID of the course.
     * - status: Returns 1 if manual enrolment is enabled, and 0 if disabled.
     * - message: An optional message, if applicable.
     *
     * @return external_multiple_structure The description of the result value.
     */
public static function auth_edwiserbridge_update_course_enrollment_method_returns() {

================
File: classes/external/validate_token.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Test connection.
 * Functionality to test wordpress and moodle connection.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_validate_token
 */
trait validate_token {
⋮----
public static function auth_edwiserbridge_validate_token($wpurl, $wptoken) {
// Validation for context is needed.
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_validate_token_parameters(),
⋮----
// get user id by token
⋮----
$userid = $DB->get_field('external_tokens', 'userid', array('token' => $params["wp_token"]));
// $roleid = $DB->get_records('role_assignments', ['userid' => $userid]);
⋮----
$manager_id = $DB->get_field('role', 'id', ['archetype' => 'manager']);
// $roleid = $DB->get_field('mdl_role', 'archetype', ['id' => $roleid]);
⋮----
public static function auth_edwiserbridge_validate_token_parameters() {
⋮----
public static function auth_edwiserbridge_validate_token_returns() {

================
File: classes/external/verify_sso_token.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Verify SSO token.
 * Functionality to verify SSO token.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\external;
⋮----
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core\context\system as context_system;
⋮----
/**
 * Trait implementing the external function auth_edwiserbridge_verify_sso_token
 */
trait verify_sso_token {
⋮----
/**
     * Returns the external function parameters for the auth_edwiserbridge_verify_sso_token function.
     *
     * @return external_function_parameters The function parameters.
     * @since SSO 1.2.1
     */
public static function auth_edwiserbridge_verify_sso_token_parameters() {
⋮----
/**
     * Verifies the provided SSO token.
     *
     * @param string $token The token to verify.
     * @return array An array containing the success status and a message.
     */
public static function auth_edwiserbridge_verify_sso_token($token) {
⋮----
// Validation for context is needed.
$systemcontext = context_system::instance();
⋮----
self::validate_context($systemcontext);
⋮----
$params = self::validate_parameters(
self::auth_edwiserbridge_verify_sso_token_parameters(),
⋮----
/**
     * Returns the external function return structure for the auth_edwiserbridge_verify_sso_token function.
     *
     * @return external_single_structure The function return structure.
     * @since SSO 1.2.1
     */
public static function auth_edwiserbridge_verify_sso_token_returns() {

================
File: classes/local/api_handler.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Edwiser Bridge - WordPress and Moodle integration.
 * This file is responsible for WordPress connection related functionality.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\local;
/**
 * Handles API requests and response from WordPress.
 */
class api_handler {
/**
     * Returns the singleton instance of the api_handler class.
     *
     * @return object self object.
     */
protected static $instance = null;
⋮----
public static function instance() {
⋮----
/**
     * Connects to WordPress with the provided request URL and data.
     *
     * @param string $requesturl The URL for the WordPress API request.
     * @param array $requestdata The data to be sent in the WordPress API request.
     * @return array An array containing the response data or an error message.
     */
public function connect_to_wp_with_args($requesturl, $requestdata) {
⋮----
include_once($CFG->libdir . '/filelib.php'); // Include Moodle's curl class.
⋮----
// Create an instance of Moodle's curl class.
$curl = new \curl();
⋮----
// Construct the User-Agent string.
⋮----
// Set headers.
$curl->setHeader('User-Agent: ' . $useragent);
⋮----
// Set additional options.
⋮----
'CURLOPT_SSL_VERIFYPEER' => true, // Enforce SSL verification.
⋮----
// Execute the POST request.
$response = $curl->post($requesturl, $requestdata, $options);
⋮----
// Get the HTTP status code.
⋮----
// Check for errors.
⋮----
// Check if response is html.

================
File: classes/local/eb_pro_license_controller.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * License controller.
 * Functionality to manage licensing of Edwiser Bridge PRO version.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\local;
⋮----
/**
  * License controller class.
  */
class eb_pro_license_controller {
/**
     * @var string Slug to be used in url and functions name
     */
private $pluginslug = '';
⋮----
/**
     * @var string stores the current plugin version
     */
private $pluginversion = '';
⋮----
/**
     * @var string store the plugin short name
     */
private $pluginshortname = '';
⋮----
/**
     * @var string Handles the plugin name
     */
private $pluginname = '';
⋮----
/**
     * @var string  Stores the URL of store. Retrieves updates from
     *              this store
     */
private $storeurl = '';
⋮----
/**
     * @var string  Name of the Author
     */
private $authorname = '';
⋮----
/**
     * @var string  Short name of the plugin
     */
public static $responsedata;
⋮----
/**
     * Developer Note: This variable is used everywhere to check license information and verify the data.
     * Change the Name of this variable in this file wherever it appears and also remove this comment
     * After you are done with adding Licensing
     * @var array Stores the data of the plugin
     */
public $edwiserbridgedata = [
'plugin_short_name' => 'Edwiser Bridge - Moodle', // Plugins short name appears on the License Menu Page.
'plugin_slug'       => 'moodle_edwiser_bridge', // Plugin Slug.
'plugin_version'    => '3.0.0', // Current Version of the plugin.
'plugin_name'       => 'Edwiser Bridge - Moodle', // Under this Name product should be created on WisdmLabs Site.
'store_url'         => 'https://edwiser.org/check-update', // Edwiser Store URL.
'author_name'       => 'WisdmLabs', // Author Name.
⋮----
/**
     * Initializes the plugin data on instance creation.
     * This method sets the values of various properties of the class
     * based on the data stored in the $edwiserbridgedata array.
     */
public function __construct() {
⋮----
/**
     * Updates the status of the license.
     *
     * @param object $licensedata License data
     * @return string License status
     */
public function update_status($licensedata) {
⋮----
$this->add_notice(get_string('license_expired', 'auth_edwiserbridge'));
⋮----
$this->add_notice(get_string('license_revoked', 'auth_edwiserbridge'));
⋮----
$this->add_notice(get_string('license_no_activation_left', 'auth_edwiserbridge'));
⋮----
$this->add_notice(get_string('license_invalid', 'auth_edwiserbridge'));
⋮----
$this->add_notice(get_string('license_failed', 'auth_edwiserbridge'));
⋮----
// Delete previous license status.
⋮----
// Update license status.
⋮----
/**
     * Checks if there is no license data or if the current response code is not in the valid response codes.
     *
     * @param string $licensedata          The license data.
     * @param int    $currentresponsecode  The current response code.
     * @param array  $validresponsecode    The array of valid response codes.
     * @return bool   True if there is no data or the response code is not valid, false otherwise.
     */
public function check_if_no_data($licensedata, $currentresponsecode, $validresponsecode) {
⋮----
// Delete previous record.
⋮----
// Insert new license trans.
⋮----
/**
     * Activates the license key for the plugin.
     *
     * @param string $licensekey The license key to activate.
     * @return void
     */
public function activate_license($licensekey) {
⋮----
// Delete previous license key.
⋮----
// Insert new license key.
⋮----
// Use Moodle's curl class.
⋮----
$curl = new \curl();
⋮----
// Set the request data.
⋮----
// Set user agent.
⋮----
$curl->setHeader('User-Agent: ' . $useragent);
⋮----
// Execute POST request.
⋮----
$resp = $curl->post($this->storeurl, $postdata, $options);
⋮----
$isdataavailable = $this->check_if_no_data($licensedata, $currentresponsecode, $validresponsecode);
⋮----
// Add renew link.
⋮----
$licensestatus = $this->update_status($licensedata);
$this->set_transient_on_activation($licensestatus);
⋮----
/**
     * Sets a transient on plugin activation for frequent license checks.
     *
     * @param string $licensestatus The current license status.
     */
public function set_transient_on_activation($licensestatus) {
⋮----
// Check license trans.
⋮----
// Delete previous license trans.
⋮----
/**
     * Deactivates the license key for the plugin.
     * This function retrieves the license key from the database, sends a deactivation request to the plugin store,
     * and updates the license status and transaction records in the database accordingly.
     */
public function deactivate_license() {
⋮----
// Prepare POST data.
⋮----
// Set options and execute the POST request.
⋮----
// Delete previous license status record.
⋮----
// Insert deactivated license status.
⋮----
// Delete previous license transaction record.
⋮----
// Insert new license transaction record.
⋮----
/**
     * Retrieves the license data from the database and updates the license status.
     *
     * This method checks for the existence of a license transient in the database. If the transient has expired, it fetches the license key from the database, sends a request to the store to check the license status, and updates the license status in the database accordingly.
     *
     * @return string The response status, either 'available', 'unavailable', or 'server_did_not_respond'.
     */
public function get_data_from_db() {
⋮----
// Delete previous license transient.
⋮----
// Set headers.
⋮----
// If server does not respond, read current license information.
⋮----
// Insert new license transient.
⋮----
// Insert new license status.
⋮----
$this->set_response_data($licensestatus, $this->pluginslug, true);
⋮----
$this->set_response_data($licensestatus, $this->pluginslug);
⋮----
/**
     * Sets the response data in static properties.
     *
     * @param string  $licensestatus License status
     * @param string  $pluginslug    Plugin slug
     * @param boolean $settransient  Whether to set a transient
     */
public function set_response_data($licensestatus, $pluginslug, $settransient = false) {
⋮----
/**
     * This function is used to get a list of sites where the license key is already activated.
     *
     * @return string A list of sites where the license key is activated, or an empty string if the number of activated sites is less than the maximum allowed.
     */
public function get_site_data() {
⋮----
$sites = unserialize($sites2);// For legacy data or data received from licensing server.
⋮----
// Add Json encoded data instead of serialized data.
⋮----
/**
     * Adds a notification message to the system.
     *
     * @param string $msg The message to be displayed.
     */
public function add_notice($msg) {
\core\notification::add($msg, \core\output\notification::NOTIFY_ERROR);

================
File: classes/local/migration_helper.php
================
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
⋮----
/**
 * Migration helper for Edwiser Bridge.
 *
 * @package    auth_edwiserbridge
 * @copyright  2024 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\local;
⋮----
/**
 * Class migration_helper handles data migration from serialized to JSON format
 */
class migration_helper {
⋮----
/**
     * Executes the migration of serialized data to JSON format
     *
     * @return bool True if migration successful, false otherwise
     */
public function execute_migration() {
⋮----
$result = $result && $this->migrate_connection_settings();
$result = $result && $this->migrate_sync_settings();
$result = $result && $this->migrate_global_settings();
⋮----
/**
     * Migrates connection settings from serialized to JSON format
     *
     * @return bool Success status
     */
protected function migrate_connection_settings() {
⋮----
list($success, $data) = $this->convert_serialized_to_json($CFG->eb_connection_settings);
⋮----
/**
     * Migrates sync settings from serialized to JSON format
     *
     * @return bool Success status
     */
protected function migrate_sync_settings() {
⋮----
list($success, $data) = $this->convert_serialized_to_json($CFG->eb_synch_settings);
⋮----
/**
     * Converts serialized data to JSON format
     *
     * @param string $data Serialized data to convert
     * @return array [success, data/error_message]
     */
protected function convert_serialized_to_json($data) {
⋮----
/**
     * Migrates global settings from the Moodle configuration to the plugin configuration.
     *
     * This function iterates through a list of global settings and moves them from the Moodle
     * configuration to the plugin configuration. This is likely part of a migration process
     * to move settings from the global Moodle configuration to the plugin-specific configuration.
     *
     * @return bool True if the migration was successful, false otherwise.
     */
protected function migrate_global_settings() {
⋮----
// 'eb_connection_settings',
// 'eb_synch_settings',

================
File: classes/local/settings_handler.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Settings handler.
 * Saves and handle all Moodle settings related functionalities.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\local;
⋮----
use Exception;
⋮----
/**
 * Saves and handle all Moodle settings related functionalities.
 *
 * @package     auth_edwiserbridge
 * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class settings_handler {
⋮----
/**
     * Creates an external service with the provided name and user ID.
     *
     * @param string $name   The name of the external service.
     * @param int $userid The user ID associated with the external service.
     * @return array An array containing the response status, message, token, site URL, and service ID.
     */
public function eb_create_externle_service($name, $userid) {
⋮----
// Response initializations.
⋮----
// User id validation.
⋮----
$shortname = $this->eb_generate_service_shortname();
⋮----
if ($this->eb_check_if_service_name_available($name)) {
⋮----
$webservicemanager = new \webservice();
⋮----
// Service creation default data.
⋮----
$service = $webservicemanager->add_external_service((object) $servicedata);
⋮----
$this->eb_add_auth_user($service, $userid);
$this->eb_add_default_web_service_functions($service);
$token = $this->eb_create_token($service, $userid);
⋮----
/**
     * Generates a unique shortname for an external service.
     *
     * This function generates a new shortname for an external service by appending a
     * sequential number to the base 'edwiser' shortname. It checks if the generated
     * shortname is already in use in the 'external_services' table, and continues
     * generating new shortnames until a unique one is found, or a maximum of 100
     * attempts is reached.
     *
     * @return string The new unique shortname, or 0 if a unique shortname could not
     *         be generated after 100 attempts.
     */
public function eb_generate_service_shortname() {
⋮----
} while ($webservicemanager->get_external_service_by_shortname($newshortname));
⋮----
/**
     * Checks if the provided service name is already registered.
     *
     * This function checks if the given service name is already registered in the
     * 'external_services' table. It returns 0 if the service name is already
     * registered, and 1 if the service name is available.
     *
     * @param string $servicename The service name to check.
     * @return int 0 if the service name is already registered, 1 if it is available.
     */
public function eb_check_if_service_name_available($servicename) {
⋮----
// No method to get service by name only by name. To be replaced in the future when method becomes available.
$service = $DB->get_record('external_services',
⋮----
/**
     * Adds an authorized user for the external service.
     *
     * This function adds a user as an authorized user for the specified external service.
     * It inserts a new record in the 'external_services_users' table with the provided
     * service ID and user ID.
     *
     * @param int $serviceid The ID of the external service.
     * @param int $userid The ID of the user to be added as an authorized user.
     */
public function eb_add_auth_user($serviceid, $userid) {
⋮----
$webservicemanager->add_ws_authorised_user((object) $userdata);
⋮----
/**
     * Adds the default web service functions registered with the Edwiser Bridge plugin.
     *
     * This function adds a set of default web service functions to the external service
     * identified by the provided $serviceid. The functions added are related to user
     * management, course management, and other Edwiser Bridge specific operations.
     *
     * @param int $serviceid The ID of the external service to add the functions to.
     */
public function eb_add_default_web_service_functions($serviceid) {
⋮----
if (!$webservicemanager->service_function_exists($functionname, $serviceid)) {
$webservicemanager->add_external_function_to_service($functionname, $serviceid);
⋮----
$this->eb_extensions_web_service_function($serviceid);
⋮----
/**
     * This function adds extensions web services which are registered with the edwiser-bridge only.
     *
     * @param int $serviceid The ID of the external service to add the extension functions to.
     */
public function eb_extensions_web_service_function($serviceid) {
⋮----
['auth_edwiserbridge_verify_sso_token'], // SSO functions
[ // Selective sync functions
⋮----
[ // Bulk purchase functions
⋮----
/**
     * Links an existing web service to the Edwiser Bridge plugin.
     *
     * This function adds all the missing functions to the web service, but does not add an auth user.
     *
     * @param int $serviceid The ID of the external service to link.
     * @param int $token     The token to use for the web service.
     * @return bool          Returns a success message.
     */
public function eb_link_exitsing_service($serviceid, $token) {
⋮----
if ($webservicemanager->get_external_service_by_id($serviceid)) {
$this->eb_add_default_web_service_functions($serviceid);
⋮----
/**
     * This function creates the token by calling Moodle's inbuilt function.
     *
     * @param int $serviceid The ID of the external service.
     * @param int $userid    The ID of the user.
     * @return string        The generated token.
     */
public function eb_create_token($serviceid, $userid) {
⋮----
$token = \external_generate_token($tokendata['tokentype'], $serviceid, $userid, 1);

================
File: classes/local/setup_wizard.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Setup Wizard.
 * Functionality to manage setup wizard.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\local;
/**
 * Handles API requests and response from WordPress.
 *
 * @package     auth_edwiserbridge
 * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class setup_wizard {
⋮----
/**
     * Get setup wizard steps.
     *
     * @return array $steps Setup wizard steps.
     */
public function eb_setup_wizard_get_steps() {
⋮----
// Loop through the steps.
// Ajax call for each of the steps and save.
// step change logic.
// load data on step change.
⋮----
/**
     * Generates the HTML content for the setup wizard steps.
     *
     * @param string $currentstep The current step in the setup wizard.
     * @return string The HTML content for the setup wizard steps.
     */
public function eb_setup_steps_html($currentstep = '') {
⋮----
$renderer = $PAGE->get_renderer('core');
⋮----
$steps = $this->eb_setup_wizard_get_steps();
⋮----
return $renderer->render_from_template('auth_edwiserbridge/setup_steps', $templatecontext);
⋮----
/**
     * Get the title of the specified setup wizard step.
     *
     * @param string $step The name of the setup wizard step.
     * @return string The title of the specified step, or an empty string if the step is not found.
     */
public function eb_get_step_title($step) {
⋮----
/**
     * Handles the submission or refresh of the setup wizard page.
     *
     * This function determines the current step of the setup wizard based on the
     * request parameters or the saved progress in the configuration.
     *
     * @return string The name of the current setup wizard step.
     */
public function eb_setup_handle_page_submission_or_refresh() {
⋮----
// Handle page refresh.
⋮----
$step = $this->get_next_step($eb_setup_progress);
⋮----
/**
     * Renders the setup wizard template.
     *
     * This function is responsible for rendering the setup wizard template, which
     * includes the sidebar and content sections. It determines the current step of
     * the setup wizard and calls the appropriate function to generate the content
     * for that step.
     *
     * @param string $step The name of the current setup wizard step, defaulting to
     *                     'installation_guide'.
     */
public function eb_setup_wizard_template($step = 'installation_guide') {
⋮----
// Get current step.
⋮----
$step = $this->eb_setup_handle_page_submission_or_refresh();
$title = $this->eb_get_step_title($step);
⋮----
$this->setup_wizard_header($title);
⋮----
// Sidebar HTML.
$sidebar = $this->eb_setup_steps_html($step);
⋮----
// Content HTML.
⋮----
// Mustache template context.
⋮----
// Render the setup_wizard_template.mustache template.
⋮----
echo $renderer->render_from_template('auth_edwiserbridge/setup_wizard_template', $templatecontext);
⋮----
// Footer part.
$this->setup_wizard_footer();
⋮----
/**
     * Renders the setup wizard header.
     *
     * This function is responsible for rendering the header section of the setup wizard
     * template. It takes an optional $title parameter to set the page title.
     *
     * @param string $title The title to display in the header.
     */
public function setup_wizard_header($title = '') {
⋮----
// Template context.
⋮----
// Render the template with the data.
echo $renderer->render_from_template('auth_edwiserbridge/setup_wizard_header', $data);
⋮----
/**
     * Renders the setup wizard footer.
     *
     * This function is responsible for rendering the footer section of the setup wizard
     * template. It sets up the template context with the necessary data and then
     * renders the 'auth_edwiserbridge/setup_wizard_footer' template.
     */
public function setup_wizard_footer() {
⋮----
'closesetup' => $this->eb_setup_close_setup(),
⋮----
echo $renderer->render_from_template('auth_edwiserbridge/setup_wizard_footer', $data);
⋮----
/**
     * Get the next step in the setup wizard.
     *
     * This function retrieves the next step in the setup wizard based on the current step.
     *
     * @param string $currentstep The current step in the setup wizard.
     * @return string The next step in the setup wizard.
     */
public function get_next_step($currentstep) {
⋮----
/**
     * Get the previous step in the setup wizard.
     *
     * This function retrieves the previous step in the setup wizard based on the current step.
     *
     * @param string $currentstep The current step in the setup wizard.
     * @return string The previous step in the setup wizard.
     */
public function get_prev_step($currentstep) {
⋮----
/**
     * Displays the installation guide for the Edwiser Bridge plugin.
     *
     * This function renders the installation guide template with the necessary data and
     * outputs the HTML content. If the $ajax parameter is set to 1, the function will
     * return the HTML content instead of directly echoing it.
     *
     * @param int $ajax Whether the call is an AJAX request (1) or not (0).
     * @return string The HTML content of the installation guide.
     */
public function eb_setup_installation_guide($ajax = 1) {
⋮----
'nextstep' => $this->get_next_step('installation_guide'),
⋮----
$output = $renderer->render_from_template('auth_edwiserbridge/installation_guide', $data);
⋮----
/**
     * Outputs the HTML content for the plugin configuration page. If the $ajax parameter is set to 1, the function will
     * return the HTML content instead of directly echoing it.
     *
     * @param int $ajax Whether the call is an AJAX request (1) or not (0).
     * @return string The HTML content of the plugin configuration page.
     */
public function eb_setup_plugin_configuration($ajax = 1) {
⋮----
$nextstep = $this->get_next_step($step);
⋮----
$output = $renderer->render_from_template('auth_edwiserbridge/plugin_configuration', $templatecontext);
⋮----
/**
     * Handles the web service setup for the Edwiser Bridge plugin.
     *
     * @param int $ajax Indicates whether the request is an AJAX call.
     * @return string $html HTML content for the web service setup.
     */
public function eb_setup_web_service($ajax = 1) {
⋮----
$output = $renderer->render_from_template('auth_edwiserbridge/web_service', $templatecontext);
⋮----
/**
     * Displays the WordPress site details step in the setup wizard.
     *
     * @param int $ajax Whether the function is called via AJAX (1) or not (0).
     * @return string $html HTML content for the WordPress site details step.
     */
public function eb_setup_wordpress_site_details($ajax = 1) {
⋮----
$prevstep = $this->get_prev_step($step);
⋮----
$output = $renderer->render_from_template('auth_edwiserbridge/wordpress_site_details', $templatecontext);
⋮----
/**
     * Checks the permalink structure of the WordPress site.
     *
     * @param int $ajax Indicates whether the call is an AJAX request (1) or not (0).
     * @return string $html HTML content to be displayed.
     */
public function eb_setup_check_permalink($ajax = 1) {
⋮----
$output = $renderer->render_from_template('auth_edwiserbridge/permalink', $templatecontext);
⋮----
/**
     * Test connection.
     *
     * @param int $ajax Ajax call.
     * @return string $html HTML content.
     */
public function eb_setup_test_connection($ajax = 1) {
⋮----
$output = $renderer->render_from_template('auth_edwiserbridge/test_connection', $templatecontext);
⋮----
/**
     * Handles the user and course synchronization settings in the setup wizard.
     *
     * @param int $ajax Whether the function is called via AJAX (1) or not (0).
     * @return string $html HTML content to be displayed in the setup wizard.
     */
public function eb_setup_user_and_course_sync($ajax = 1) {
⋮----
$output = $renderer->render_from_template('auth_edwiserbridge/user_and_course_sync', $templatecontext);
⋮----
/**
     * Handles the completion of the setup wizard for the Edwiser Bridge plugin.
     *
     * @param int $ajax Indicates whether the request is an AJAX call (1) or not (0).
     * @return string $html The HTML content to be displayed.
     */
public function eb_setup_complete_details($ajax = 1) {
⋮----
'ebsetupredirectionpopup' => $this->eb_setup_redirection_popup(),
'ebsetupcompletionpopup' => $this->eb_setup_completion_popup(),
⋮----
$output = $renderer->render_from_template('auth_edwiserbridge/setup_complete_details', $templatecontext);
⋮----
/**
     * Renders the HTML content for the setup close popup.
     *
     * @return string $html HTML content for the setup close popup.
     */
public function eb_setup_close_setup() {
⋮----
return $renderer->render_from_template('auth_edwiserbridge/setup_close', $templatecontext);
⋮----
/**
     * Renders the HTML content for the setup redirection popup.
     *
     * @return string $html HTML content for the setup redirection popup.
     */
public function eb_setup_redirection_popup() {
⋮----
return $renderer->render_from_template('auth_edwiserbridge/setup_redirection_popup', $templatecontext);
⋮----
/**
     * Renders the HTML content for the setup completion popup.
     *
     * @return string $html HTML content for the setup completion popup.
     */
public function eb_setup_completion_popup() {
⋮----
return $renderer->render_from_template('auth_edwiserbridge/setup_completion_popup', $templatecontext);

================
File: classes/local/update.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Plugin update class.
 * Functionality to manage plugin updates.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\local;
⋮----
// use core\plugin_manager as core_plugin_manager;
use core\exception\moodle_exception as moodle_exception;
use Michelf\MarkDown;
use core\component as core_component;
use ZipArchive;
use moodle_url;
use Exception;
use stdClass;
use curl;
use core\output\html_writer as html_writer;
⋮----
/**
 * Class update
 */
class update {
⋮----
/**
     * Edwiser plugins list
     * @var array
     */
public $plugins = [];
⋮----
/**
     * Error occured while fetching update details
     * @var array
     */
public $errors = [];
⋮----
/**
     * Refresh update cache
     * @var bool
     */
public $refresh = false;
⋮----
/**
     * Cache object
     * @var null
     */
public static $cache = null;
⋮----
public $page = null;
⋮----
/**
     * Cache file url
     *
     * @var string
     */
public static $cacheurl = null;
⋮----
/**
     * Thin wrapper for the core's download_file_content() function.
     *
     * @param string $url    URL to the file
     * @param string $tofile full path to where to store the downloaded file
     *
     * @return bool
     */
protected function download_file_content($url, $tofile) {
// Prepare the parameters for the download_file_content() function.
⋮----
/**
     * Download the ZIP file with the plugin package from the given location
     *
     * @param string $url    URL to the file
     * @param string $tofile full path to where to store the downloaded file
     *
     * @return bool false on error
     */
protected function download_plugin_zip_file($url, $tofile) {
include_once($CFG->libdir . '/filelib.php'); // Ensure Moodle's curl class is available.
⋮----
$response = $curl->get($checkurl);
⋮----
$status = $this->download_file_content($url, $tofile);
⋮----
/**
     * Obtain the plugin ZIP file from the given URL
     *
     * The caller is supposed to know both downloads URL and the MD5 hash of
     * the ZIP contents in advance, typically by using the API requests against
     * the plugins directory.
     *
     * @param object $pluginman plugin manager object
     * @param string $url       url of plugin file
     * @param string $name      name with component of plugin
     *
     * @return string|bool full path to the file, false on error
     */
public function get_remote_plugin_zip($pluginman, $url, $name) {
⋮----
// Sanitize and validate the URL.
⋮----
// The cache location for the file.
⋮----
// Download the file into a temporary location.
⋮----
$result = $this->download_plugin_zip_file($url, $tempfile);
⋮----
// If the file is empty, something went wrong.
⋮----
// Store the file in our cache.
⋮----
/**
     * Get plugin details from version.php file.
     *
     * @param string $path        Path of the plugin.
     * @param array  $zipcontents Contents of the zip file.
     *
     * @return stdClass|bool Plugin details, or false if unable to retrieve.
     */
public function get_plugin_details($path, $zipcontents) {
⋮----
/**
     * Unzips a plugin file and returns its contents.
     *
     * @param object $pluginman Plugin manager object.
     * @param string $zip       Path to the zip file.
     * @param string $temp      Path to the temporary directory.
     * @param string $root      Root directory path.
     * @return array            Contents of the zip file.
     */
public function unzip_plugin_file($pluginman, $zip, $temp, $root) {
$contents = $pluginman->unzip_plugin_file($zip, $temp, $root);
⋮----
/**
     * Verify zip file is valid
     *
     * @param object $pluginman core plugin manager
     * @param string $zip       zip file
     * @param string $temp      temporary directory path
     * @param string $name      name of zip file
     *
     * @return bool         True is zip file is valid
     */
public function verify_zip($pluginman, $zip, $temp, $name) {
⋮----
$zipcontents = $this->unzip_plugin_file($pluginman, $zip, $temp, $name);
⋮----
// Check all files from zip is ok and has zip inside zip.
⋮----
// If count is different means only one plugin file is there.
// Else zip contains multiple plugins.
⋮----
$plugin = $this->get_plugin_details($temp, $zipcontents);
⋮----
$zipcontents = $this->unzip_plugin_file($pluginman, $temp . '/' . $file, $path, $name1);
⋮----
$plugin = $this->get_plugin_details($path, $zipcontents);
⋮----
/**
     * Fetch plugin update data from the edwiser.org cache or directly from the server.
     *
     * @return array An associative array containing the plugin update data, with the plugin name as the key.
     */
public function fetch_plugins_update() {
⋮----
/**
     * Validates the given plugin zip file before installing it.
     *
     * @param core_plugin_manager      $pluginman core plugin manager object
     * @param \core\update\remote_info $plugin    plugin information
     * @param string                   $zipfile   zip file path
     * @param bool                     $silent    true if don't want to show debug error
     *
     * @return bool                 validation result
     */
private function validate_plugin_zip($pluginman, $plugin, $zipfile, $silent) {
⋮----
list($plugintype, $pluginname) = core_component::normalize_component($plugin->component);
⋮----
$zipcontents = $this->unzip_plugin_file($pluginman, $zipfile, $tmp, $pluginname);
⋮----
$validator = \core\update\validator::instance($tmp, $zipcontents);
$validator->assert_plugin_type($plugintype);
$validator->assert_moodle_version($CFG->version);
⋮----
// Check for missing dependencies during validation.
$result = $validator->execute();
⋮----
foreach ($validator->get_messages() as $message) {
⋮----
mtrace('  <strong>['.$validator->message_level_name($message->level).']</strong>', ' ');
⋮----
mtrace('  ['.$validator->message_level_name($message->level).']', ' ');
⋮----
mtrace($validator->message_code_name($message->msgcode), ' ');
⋮----
$info = $validator->message_code_info($message->msgcode, $message->addinfo);
⋮----
if ($icon = $validator->message_help_icon($message->msgcode)) {
⋮----
mtrace($OUTPUT->render($icon), ' ');
⋮----
/**
     * Perform the installation of plugins.
     *
     * If used for installation of remote plugins from the Edwiser Plugins
     * directory, the $plugins must be list of {@link \core\update\remote_info}
     * object that represent installable remote plugins. The caller can use
     * {@link self::filter_installable()} to prepare the list.
     *
     * If used for installation of plugins from locally available ZIP files,
     * the $plugins should be list of objects with properties ->component and
     * ->zipfilepath.
     *
     * The method uses {@link mtrace()} to produce direct output and can be
     * used in both web and cli interfaces.
     *
     * @param  \core\update\remote_info $plugin    list of plugins
     * @param  bool                     $confirmed should the files be really deployed into the dirroot?
     * @param  bool                     $silent    hide debugg errors is set true
     *
     * @return bool                                 true on success
     */
public function install_plugin(\core\update\remote_info $plugin, $confirmed, $silent) {
⋮----
$pluginman = \core_plugin_manager::instance();
⋮----
// Let admins know they can expect more verbose output.
⋮----
// Download all ZIP packages if we do not have them yet.
⋮----
$errormsg = html_writer::start_tag($tag);
⋮----
$errormsg .= html_writer::tag('li', $msg);
⋮----
$errormsg .= html_writer::end_tag($tag);
⋮----
$zip = $this->get_remote_plugin_zip(
⋮----
$zips = $this->verify_zip($pluginman, $zip, $temp, $plugin->component);
⋮----
$checks &= $this->validate_plugin_zip($pluginman, $plugindetails, $zipfile, $silent);
⋮----
// Extract all ZIP packs do the dirroot.
⋮----
$target = $pluginman->get_plugintype_root($plugintype);
$plugininfo = $pluginman->get_plugin_info($plugin->component);
⋮----
$pluginman->remove_plugin_folder($plugininfo);
⋮----
if (!$this->unzip_plugin_file($pluginman, $zipfile, $target, $pluginname)) {
⋮----
/**
     * Displays the continue and cancel buttons for the plugins management pages.
     *
     * @param null|moodle_url $continue URL for the continue button, should it be displayed
     * @param null|moodle_url $download URL for the download button, should it be displayed
     * @param null|moodle_url $cancel URL for the cancel link, defaults to the current page
     * @return string HTML containing the buttons
     */
public function plugins_management_confirm_buttons(
⋮----
$out = html_writer::start_div('plugins-management-confirm-buttons');
⋮----
$out .= $OUTPUT->single_button($continue, get_string('continue'), 'post', ['class' => 'continue']);
⋮----
$out .= $OUTPUT->single_button($download, get_string('download'), 'post', ['class' => 'download']);
⋮----
$out .= html_writer::div(html_writer::link($cancel, get_string('cancel')), 'cancel');
⋮----
/**
     * Handles the installation and validation of a remote plugin.
     *
     * This method is responsible for displaying the validation results and
     * providing the necessary buttons for the user to proceed with the
     * installation or cancel the process.
     *
     * @param \core\update\remote_info $installable The plugin information to be installed.
     * @param bool $confirmed Whether the installation has been confirmed by the user.
     * @param string $heading The heading to display on the validation screen.
     * @param null|moodle_url $continue The URL to proceed with the installation.
     * @param null|moodle_url $download The URL to download the plugin.
     * @param null|moodle_url $return The URL to go back to on cancellation.
     */
public function upgrade_install_plugin(
⋮----
// Installation confirmed at the validation results page.
if (!$this->install_plugin($installable, true, true)) {
⋮----
// Always redirect to admin/index.php to perform the database upgrade.
// Do not throw away the existing $PAGE->url parameters such as.
// confirmupgrade or confirmrelease if $PAGE->url is a superset of the.
// URL we must go to.
⋮----
if ($mustgoto->compare($PAGE->url, URL_MATCH_PARAMS)) {
⋮----
$output = $PAGE->get_renderer('core', 'admin');
echo $output->header();
⋮----
echo $output->heading($heading, 3);
⋮----
echo html_writer::start_tag('pre', ['class' => 'plugin-install-console']);
$validated = $this->install_plugin($installable, false, false);
echo html_writer::end_tag('pre');
⋮----
echo $this->plugins_management_confirm_buttons($continue, null, $return);
⋮----
echo html_writer::start_tag('a', ['class' => 'btn btn-secondary', 'href' => $download]);
⋮----
echo html_writer::end_tag('a');
echo $this->plugins_management_confirm_buttons(null, null, $return);
⋮----
echo $output->footer();
⋮----
/**
     * Downloads the plugin file for the requested plugin.
     *
     * @param object $plugin The plugin object to download.
     * @return bool False if unable to download the plugin file.
     */
public function download_plugin($plugin) {
⋮----
// Validate all downloaded packages.
⋮----
// Force download.
⋮----
/**
     * Get plugin update details for install update page.
     *
     * @param array $params Plugin details parameter
     * @return array Plugin update details
     */
public function get_plugin_update($params) {
⋮----
$plugins = $this->fetch_plugins_update();
⋮----
$this->download_plugin($plugin);

================
File: classes/privacy/provider.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Privacy implementation for auth_edwiserbridge.
 * Privacy Subsystem implementation for auth_edwiserbridge.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\privacy;
⋮----
use core_privacy\local\metadata\collection;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\approved_userlist;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\helper;
use core_privacy\local\request\transform;
use core_privacy\local\request\userlist;
use core_privacy\local\request\writer;
⋮----
/**
 * The edwiserbridge plugin stores a user preference data.
 *
 * @copyright  2018 Andrew Nicols <andrew@nicols.co.uk>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class provider implements
// This plugin has data.
\core_privacy\local\metadata\provider,
\core_privacy\local\request\core_userlist_provider,
\core_privacy\local\request\plugin\provider,
\core_privacy\local\metadata\null_provider {
⋮----
/**
     * Returns meta data about this system.
     *
     * @param  collection $collection The initialised item collection to add items to.
     * @return collection A listing of user data stored through this system.
     */
public static function get_metadata(collection $collection): collection {
$collection->add_external_location_link('wp_site', [
⋮----
/**
     * Get the list of contexts that contain user information for the specified user.
     *
     * @param int $userid The user to search.
     * @return contextlist The contextlist containing the list of contexts used in this plugin.
     */
public static function get_contexts_for_userid(int $userid): contextlist {
⋮----
/**
     * Get the list of users who have data within a context.
     *
     * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
     */
public static function get_users_in_context(userlist $userlist) {
⋮----
/**
     * Export all user data for the specified user, in the specified contexts.
     *
     * @param approved_contextlist $contextlist The approved contexts to export information for.
     */
public static function export_user_data(approved_contextlist $contextlist) {
⋮----
/**
     * Delete all data for all users in the specified context.
     *
     * @param context $context The specific context to delete data for.
     */
public static function delete_data_for_all_users_in_context(\context $context) {
⋮----
/**
     * Delete all user data for the specified user, in the specified contexts.
     *
     * @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
     */
public static function delete_data_for_user(approved_contextlist $contextlist) {
⋮----
/**
     * Delete multiple users within a single context.
     *
     * @param approved_userlist $userlist The approved context and user information to delete information for.
     */
public static function delete_data_for_users(approved_userlist $userlist) {
⋮----
/**
     * Get the privacy provider component name.
     *
     * @return string The component name.
     */
public static function get_reason(): string {

================
File: classes/settings/connection_form.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Connection settings.
 * Functionality to manage connection settings.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\settings;
use moodleform;
⋮----
/**
 * Defines the connection settings form for the Edwiser Bridge plugin.
 * This class extends the moodleform class and provides functionality to manage the connection settings.
 */
class connection_form extends moodleform {
⋮----
/**
     * Defines the connection settings form for the Edwiser Bridge plugin.
     * This method sets up the form elements, including text fields for site name, URL, and token,
     * as well as buttons for testing the connection and removing a site. It also handles
     * setting default values and validating the form data.
     */
public function definition() {
⋮----
$repeatarray[] = $mform->createElement('header', 'wp_header', get_string('wp_site_settings_title', 'auth_edwiserbridge')
⋮----
$repeatarray[] = $mform->createElement(
⋮----
$repeatarray[] = $mform->createElement('text', 'wp_url', get_string('wordpress_url', 'auth_edwiserbridge'), 'size="35"');
$repeatarray[] = $mform->createElement('text', 'wp_token', get_string('wp_token', 'auth_edwiserbridge'), 'size="35"');
$repeatarray[] = $mform->createElement('hidden', 'wp_remove', 'no');
⋮----
$buttonarray[] = $mform->createElement(
⋮----
$buttonarray[] = $mform->createElement('html', '<div id="eb_test_conne_response_old"> </div>');
$repeatarray[] = $mform->createElement("group", "eb_buttons", "", $buttonarray);
$repeatarray[] = $mform->createElement('html', '<div id="eb_test_conne_response"> </div>');
⋮----
/*
        * Data type of each field.
        */
⋮----
/*
        * Name of each field.
        */
⋮----
/*
        * Adding rule for each field.
        */
⋮----
$mform->setDefault("wp_name[" . $siteno . "]", $value["wp_name"]);
$mform->setDefault("wp_url[" . $siteno . "]", $value["wp_url"]);
$mform->setDefault("wp_token[" . $siteno . "]", $value["wp_token"]);
⋮----
$this->repeat_elements(
⋮----
// Closing header section.
$mform->closeHeaderBefore('eb_option_add_fields');
⋮----
$mform->addElement(
⋮----
// Fill form with the existing values.
⋮----
/**
     * Validates the form data and files submitted.
     *
     * @param array $data The form data.
     * @param array $files The uploaded files.
     * @return array An array of validation errors.
     */
public function validation($data, $files) {
$errors = parent::validation($data, $files);
⋮----
// Delete the current values from the copy of the data array.
⋮----
// Checking if the current name value exitsts in array.
⋮----
// Checking if the current URL value exitsts in array.
⋮----
// If the site settings is removed then remove the validation errors also.

================
File: classes/settings/navigation_form.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Navigation form.
 * Functionality to manage navigation form.
 *
 * @package    auth_edwiserbridge
 * @category   external
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge\settings;
use moodleform;
⋮----
/**
 * Defines the navigation form for the Edwiser Bridge plugin.
 * The navigation form includes tabs for different sections of the plugin settings.
 */
class navigation_form extends moodleform {
⋮----
/**
     * Defines the navigation form for the Edwiser Bridge plugin.
     * This method sets up the navigation tabs for the different sections of the plugin settings.
     */
public function definition() {
⋮----
$mform->addElement('html', '<div class="eb-tabs-cont">' . $this->print_tabs($tabs) . '</div>');
⋮----
/**
     * Prepares and prints the list of tab links.
     *
     * @param array $tabs An array of settings arrays, each containing a link, label, and CSS class for a tab.
     * @return void
     */
private function print_tabs($tabs) {

================
File: classes/settings/service_form.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Used to create web service.
 * Functionality to create web service.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
namespace auth_edwiserbridge\settings;
use moodleform;
⋮----
/**
 * Defines the web services form for the Edwiser Bridge plugin.
 * This class extends the moodleform class and provides the functionality to create and manage web services.
 */
class service_form extends moodleform {
⋮----
/**
     * Defines the web services form for the Edwiser Bridge plugin.
     * This method is responsible for creating and managing the web services form, including adding various form elements such as service list, service input, user list, site language, site URL, and token.
     */
public function definition() {
⋮----
// 1st Field Service list
$select = $mform->addElement(
⋮----
$mform->addHelpButton('eb_sevice_list', 'eb_mform_service_desc', 'auth_edwiserbridge');
$select->setMultiple(false);
⋮----
// 2nd Field Service input name
$mform->addElement(
⋮----
$mform->setType('eb_service_inp', PARAM_TEXT);
⋮----
// 3rd field Users List.
⋮----
$mform->addHelpButton('eb_mform_lang_wrap', 'eb_mform_lang_desc', 'auth_edwiserbridge');
⋮----
// 4th field Site Url
⋮----
$mform->addHelpButton('eb_mform_site_url_wrap', 'eb_mform_ur_desc', 'auth_edwiserbridge');
⋮----
// If service is empty then show just the blank text with dash.
⋮----
// If the token available then show the token.
⋮----
// 5th field Token
⋮----
$mform->addHelpButton('eb_mform_token_wrap', 'eb_mform_token_desc', 'auth_edwiserbridge');
⋮----
$mform->addElement('button', 'eb_mform_create_service', get_string("link", 'auth_edwiserbridge'));
⋮----
// Set default values.
⋮----
$mform->setDefault("eb_sevice_list", $service);

================
File: classes/settings/settings_form.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Settings form.
 * Functionality to manage and display settings form.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
namespace auth_edwiserbridge\settings;
use moodleform;
⋮----
/**
 * Defines the settings form for the Edwiser Bridge authentication plugin.
 *
 * This class extends the moodleform class and provides the definition of the
 * settings form for the Edwiser Bridge authentication plugin. The form includes
 * various checkboxes for configuring the plugin's settings, such as the REST
 * protocol, web service, password policy, extended username, and auto-update
 * check. The form also includes buttons for saving the settings.
 */
class settings_form extends moodleform {
⋮----
/**
     * Defines the form definition for the settings form of the Edwiser Bridge authentication plugin.
     *
     * This method sets up the various form elements, including checkboxes for configuring the
     * REST protocol, web service, password policy, extended username, and auto-update check.
     * It also adds the submit buttons for saving the settings.
     */
public function definition() {
⋮----
// 1st field.
$mform->addElement(
⋮----
// 2nd field.
⋮----
// 3rd field.
⋮----
// 4th field.
⋮----
// 5th field.
⋮----
// Fill form with the existing values.
⋮----
$mform->setDefault('rest_protocol', $defaultvalues['rest_protocol']);
$mform->setDefault('web_service', $defaultvalues['web_service']);
$mform->setDefault('pass_policy', $defaultvalues['pass_policy']);
$mform->setDefault('extended_username', $defaultvalues['extended_username']);
$mform->setDefault('enable_auto_update_check', $defaultvalues['enable_auto_update_check']);
⋮----
/**
     * Validates the form data submitted by the user.
     *
     * @param array $data  The submitted form data.
     * @param array $files The submitted files, if any.
     *
     * @return void
     */
public function validation($data, $files) {

================
File: classes/settings/sso_form.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Manage SSO settings.
 * Functionality to manage SSO settings.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
namespace auth_edwiserbridge\settings;
use moodleform;
use auth_edwiserbridge\local\eb_pro_license_controller;
⋮----
/**
 * Defines the SSO settings form for the Edwiser Bridge plugin.
 * This form allows the user to configure the SSO settings, including the shared secret key, WordPress site URL, logout redirect URL, and login button options.
 */
class sso_form extends moodleform {
⋮----
/**
     * Defines the form for configuring the SSO settings in the Edwiser Bridge plugin.
     * This method sets up the form fields and default values for the SSO settings, including the shared secret key, WordPress site URL, logout redirect URL, and login button options.
     */
public function definition() {
⋮----
if ($license->get_data_from_db() == 'available') {
$mform->addElement('html', '<div class="eb-auto-generate-key-container">');
$mform->addElement(
⋮----
$mform->addHelpButton(
⋮----
$mform->setType('sharedsecret', PARAM_TEXT);
⋮----
// Add auto generate key button next to secret key field.
⋮----
$mform->setType('wpsiteurl', PARAM_TEXT);
⋮----
$mform->setType('logoutredirecturl', PARAM_TEXT);
⋮----
$mform->setType('wploginbtntext', PARAM_TEXT);
⋮----
$mform->setDefault(
⋮----
$mform->setDefault("wploginenablebtn", $wplogin);

================
File: classes/settings/summary_form.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Summary form.
 * Functionality to Show plugin summary and license form.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
namespace auth_edwiserbridge\settings;
use moodleform;
use webservice;
use moodle_url;
use auth_edwiserbridge\local\eb_pro_license_controller;
// use core\plugin_manager as core_plugin_manager;
⋮----
/**
 * Defines the summary form for the Edwiser Bridge plugin.
 * This form is used to display the plugin summary and license information.
 */
class summary_form extends moodleform {
⋮----
/**
     * This method is responsible for defining the summary form for the Edwiser Bridge plugin. 
     * It sets up the form fields and handles the display of plugin summary and license information. 
     * The method retrieves various data points such as the plugin version, web service details, and license information, and populates the form accordingly. 
     * It also checks the web service user's capabilities and displays appropriate messages based on the findings.
     */
public function definition() {
⋮----
$pluginsvdata  = $this->get_plugin_version_data();
⋮----
// Handle license request.
$this->handle_license_action();
⋮----
// Check web service user have a capability to use the web service.
⋮----
$allowedusers = $webservicemanager->get_ws_authorised_users($service);
$usersmissingcaps = $webservicemanager->get_missing_capabilities_by_users($allowedusers, $service);
$webservicemanager->get_external_service_by_id($service);
⋮----
// Get the web service name.
$serviceobj = $webservicemanager->get_external_service_by_id($service);
⋮----
// If service is empty then show just the blank text with dash.
⋮----
// If the token available then show the token.
⋮----
'value'          => $this->get_plugin_fetch_link(),
⋮----
'value'          => $this->get_license_data(),
⋮----
$mform->addElement(
⋮----
/**
     * Get the URL for fetching plugin information.
     *
     * This function generates the URL for fetching the latest information about the Edwiser Bridge plugin,
     * including the current version and any available updates. The URL is constructed using the global
     * $CFG object, which contains the root URL of the Moodle installation.
     *
     * @return string The URL for fetching plugin information.
     */
private function get_plugin_fetch_link() {
⋮----
/**
     * Retrieves the version information for the Edwiser Bridge plugin.
     *
     * This function fetches the current version of the Edwiser Bridge plugin installed on the Moodle site,
     * as well as the latest available version from the remote server. It then constructs an array of version
     * information, including any available updates, and returns it.
     *
     * @return array An associative array containing the version information for the Edwiser Bridge plugin.
     */
private function get_plugin_version_data() {
⋮----
$pluginman   = \core_plugin_manager::instance();
⋮----
$authplugin                 = $pluginman->get_plugins_of_type('auth');
⋮----
$remotedata = $this->get_remote_plugins_data($fetchdata);
⋮----
/**
     * Returns the remote plugin data.
     *
     * @param bool $fetchdata Whether to fetch the data from the remote server.
     * @return object The remote plugin data.
     */
private function get_remote_plugins_data($fetchdata) {
⋮----
include_once($CFG->libdir . '/filelib.php'); // Ensure Moodle's curl class is available.
⋮----
// Use Moodle's curl class.
$curl = new \curl();
⋮----
// Construct a user agent string.
⋮----
// Set headers and options.
$curl->setHeader('User-Agent: ' . $useragent);
⋮----
// Execute GET request.
⋮----
$response = $curl->get($url, [], $options);
⋮----
// Check the response.
⋮----
/**
     * Retrieves the license data for the Edwiser Bridge plugin.
     *
     * This function fetches the license key and status from the Moodle database and
     * prepares the data for rendering a license form template.
     *
     * @return string The rendered license form template.
     */
private function get_license_data() {
⋮----
$renderer = $PAGE->get_renderer('core');
⋮----
// Get License Key.
⋮----
// Get License Status.
⋮----
// Prepare data for Mustache template.
⋮----
return $renderer->render_from_template('auth_edwiserbridge/license_form', $templatecontext);
⋮----
/**
     * Handles the license activation and deactivation actions.
     *
     * This function retrieves the license key and activation/deactivation parameters
     * from the request, and then uses the eb_pro_license_controller to perform the
     * corresponding license action.
     */
private function handle_license_action() {
⋮----
$licensecontroller->activate_license($licensekey);
⋮----
$licensecontroller->deactivate_license();

================
File: classes/settings/synchronization_form.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Synchronization settings form.
 * Functionality to manage synchronization settings.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
namespace auth_edwiserbridge\settings;
use moodleform;
⋮----
/**
 * Defines the synchronization settings form for the Edwiser Bridge plugin.
 * This form allows the user to configure various synchronization options
 * between Moodle and the connected WordPress site.
 */
class synchronization_form extends moodleform {
⋮----
/**
     * Defines the synchronization settings form for the Edwiser Bridge plugin.
     * This method sets up the form fields and default values for configuring
     * various synchronization options between Moodle and the connected WordPress site.
     */
public function definition() {
⋮----
$mform->addElement('select', 'wp_site_list', get_string('site-list', 'auth_edwiserbridge'), $sites);
⋮----
// 1st Field
// Course enrollment
$mform->addElement(
⋮----
// 2nd field
// Course unenrollment
⋮----
// 3rd field.
// Course Creation.
⋮----
// 4th field.
// Course deletion.
⋮----
// 5th field.
// user creation.
⋮----
// 6th field.
// User update
⋮----
// 7th field.
// User deletion
⋮----
// Fill form with the existing values.
⋮----
$mform->setDefault("course_enrollment", $defaultvalues["course_enrollment"]);
$mform->setDefault("course_un_enrollment", $defaultvalues["course_un_enrollment"]);
$mform->setDefault("user_creation", $defaultvalues["user_creation"]);
$mform->setDefault("user_deletion", $defaultvalues["user_deletion"]);
$mform->setDefault("course_creation", $defaultvalues["course_creation"]);
$mform->setDefault("course_deletion", $defaultvalues["course_deletion"]);
$mform->setDefault("user_updation", $defaultvalues["user_updation"]);

================
File: classes/observer.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Event observer.
 * Observer file used as the callback for all the events.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
namespace auth_edwiserbridge;
⋮----
/**
 * Handles callbacks for all in built Moodle events.
 *
 * This class provides methods to handle various Moodle events, such as user enrollment, user creation, user update, and course creation/deletion. It communicates with a WordPress site using the Edwiser Bridge plugin to synchronize user and course data between the two platforms.
 *
 * @package     auth_edwiserbridge
 * @copyright   2021 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class observer {
⋮----
/**
     * Functionality to handle user enrollment event.
     *
     * This method is called when a user is enrolled in a course. It collects the relevant user data and sends it to the connected WordPress site using the Edwiser Bridge plugin to synchronize the enrollment.
     *
     * @param core\event\user_enrolment_created $event The event object containing information about the user enrollment.
     */
public static function user_enrolment_created(\core\event\user_enrolment_created $event) {
⋮----
// Adding Token for verification in WP from Moodle.
⋮----
$apihandler->connect_to_wp_with_args($value["wp_url"], $requestdata);
⋮----
/**
     * Functionality to handle user un enrollment event.
     *
     * This method is called when a user is unenrolled from a course. It collects the relevant user data and sends it to the connected WordPress site using the Edwiser Bridge plugin to synchronize the unenrollment.
     *
     * @param core\event\user_enrolment_deleted $event The event object containing information about the user unenrollment.
     */
public static function user_enrolment_deleted(\core\event\user_enrolment_deleted $event) {
⋮----
// Checks if the request is from the wordpress site or from te Moodle site itself.
⋮----
/**
     * Functionality to handle user creation event.
     *
     * This method is called when a new user is created in the Moodle system. It collects the relevant user data and sends it to the connected WordPress site using the Edwiser Bridge plugin to synchronize the user creation.
     *
     * @param core\event\user_created $event The event object containing information about the newly created user.
     */
public static function user_created(\core\event\user_created $event) {
⋮----
// User password should be encrypted. Using Openssl for it.
// We will use token as the key as it is present on both sites.
// Open SSL encryption initialization.
⋮----
// If new password in not empty.
⋮----
'secret_key' => $value['wp_token'], // Adding Token for verification in WP from Moodle.
'custom_fields' => json_encode(profile_user_record($event->relateduserid, false)), // Custom fields data.
⋮----
/**
     * Functionality to handle user update event.
     *
     * @param core\event\user_updated $event event.
     */
public static function user_updated(\core\event\user_updated $event) {
⋮----
'secret_key'    => $value['wp_token'], // Adding Token for verification in WP from Moodle.
⋮----
/**
     * Functionality to handle user password update event.
     *
     * This method is called when a user's password is updated in the system.
     * It is responsible for updating the user's password in the connected WordPress sites.
     *
     * @param core\event\user_password_updated $event The event object containing information about the password update.
     */
public static function user_password_updated(\core\event\user_password_updated $event) {
⋮----
/**
     * Functionality to handle user deletion event.
     *
     * @param core\event\user_deleted $event event.
     */
public static function user_deleted(\core\event\user_deleted $event) {
⋮----
/**
     * Functionality to handle Course creation event.
     *
     * @param core\event\course_created $event The course creation event.
     */
public static function course_created(\core\event\course_created $event) {
// Get course info.
⋮----
'secret_key'  => $value['wp_token'], // Adding Token for verification in WP from Moodle.
⋮----
/**
     * Functionality to handle Course deletion event.
     *
     * @param core\event\course_deleted $event The course deletion event.
     */
public static function course_deleted(\core\event\course_deleted $event) {
⋮----
/**
     * Handles the dashboard viewed event.
     *
     * @param \core\event\dashboard_viewed $event The dashboard viewed event.
     */
public static function dashboard_viewed(\core\event\dashboard_viewed $event) {
⋮----
// Check if user is admin or not.

================
File: db/access.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Access control.
 * Moodle Edwiser Bridge plugin capabilities.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

================
File: db/events.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Event registration.
 * Functionality to manage event registration.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
// Page view event for update check.

================
File: db/install.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Installation script for Edwiser Bridge plugin.
 * Functionality to manage installation of the plugin.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
/**
 * Performs installation tasks for the Edwiser Bridge plugin.
 *
 * This function is called during the installation of the Edwiser Bridge plugin.
 * It checks for the Edwiser Bridge Pro dependency, enables the plugin in the
 * default authentication method, and checks and updates the webservice functions.
 */
function xmldb_auth_edwiserbridge_install() {
⋮----
// Enable plugin in the default authentication method.
⋮----
// Check and upgrade webservice functions.

================
File: db/services.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * External API functions.
 * Functionality to add external API functions.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
// Setup Wizard.

================
File: db/upgrade.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Upgrade script for Edwiser Bridge plugin.
 * Functionality to manage upgrade of the plugin.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
/**
 * Upgrades the Edwiser Bridge plugin.
 *
 * This function is responsible for managing the upgrade process of the Edwiser Bridge plugin.
 * It checks for the Edwiser Bridge Pro dependency, enables the plugin in the default authentication method,
 * and updates the webservice functions as needed.
 *
 * @return bool True to continue the upgrade process.
 */
function xmldb_auth_edwiserbridge_upgrade($oldversion) {
// Enable plugin in the default authentication method.
⋮----
// Check and upgrade webservice functions.
// Migrate serialized data to json format & global config to plugin level config.
$migrationhelper = new \auth_edwiserbridge\local\migration_helper();
$migrationhelper->execute_migration();
⋮----
return true; // Return true to continue, it is must.

================
File: lang/en/auth_edwiserbridge.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Language file for auth_edwiserbridge
 * English strings
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
/**************  by default strings used by the moodle  ****************/
⋮----
/**************  end of the strings used by default by the moodle  ****************/
⋮----
/*** TABS  ***/
⋮----
/*******/
⋮----
/******* navigation menu and settings page   ********/
⋮----
/*********************************/
⋮----
/*********** Settings page validation and Modal strings************/
⋮----
/**********************************/
⋮----
/******  Form validation.  ******/
⋮----
/************/
⋮----
/*****  web service  *******/
⋮----
/******/
⋮----
/****  error handling  ***/
⋮----
/**/
⋮----
/*****************  Set up Moodle Settings  *****************/
⋮----
/********  Summary page  ********/
⋮----
/**************/
⋮----
/*****************************  ADDED FOR SETTINGS PAGE   *****************************/
⋮----
/*********  Form error Handling.    *******/
⋮----
/*
 * GDPR compatibility strings.
 */
⋮----
// Plugin stats.
⋮----
/* ----------
Setup wizard strings.
--------------*/
⋮----
/*  Tooltip  */
⋮----
/*****  Pop up close button  *****/
⋮----
/* SSO Settings */
⋮----
/* Bulk Purchase */
⋮----
/********  External service related lang  ********/
⋮----
// Plugin update notification.

================
File: specs/1_Activity_Overview_Page_Integration.md
================
# 1. Activity Overview Page Integration

**Change Summary:**
The traditional `index.php` page in activity modules has been replaced with a new Activity Overview Page. This page displays a table with activity names, completion statuses, and grades.

**Required Developer Action:**
- Implement a class in `mod_PLUGINNAME/classes/courseformat/overview.php` using the namespace `mod_PLUGINNAME\courseformat\overview`.
- Extend the `core_courseformatctivityoverviewbase` class.
- Define the `overviewitem` class with properties:
  - `name` (string): The header label for the overview item.
  - `value` (mixed): The data value, used for filtering purposes.

**Compatibility Checkpoints:**
- Ensure the class extends `activityoverviewbase`.
- Verify the presence of the `overviewitem` class with the required properties.

================
File: specs/10 AI_Compatibility_Workflow.md
================
# AI Compatibility Workflow for Moodle 5.0

## Step 1: Detect Plugin/Theme Information
The AI agent begins by scanning the existing plugin or theme for:
- **Version information** to compare against Moodle 5.0.
- **Usage of deprecated methods** (e.g., YUI, deprecated functions).
- **Current rendering methods** (check for use of old or deprecated renderers, CSS, or JavaScript frameworks like Bootstrap 4).

## Step 2: Analyze Compatibility with Moodle 5.0 Updates
The AI checks the following areas for compatibility with Moodle 5.0:
1. **Course Overview Page Compatibility:**  
   If the plugin uses old methods like `index.php` or doesn't utilize the `activityoverviewbase` class, it should flag this for updates.
   
2. **Deprecation Check:**
   - **Human Date Renderers:** Identify if any deprecated date rendering methods are used and suggest replacing them with `humandate` and `humantimeperiod`.
   - **Course Format & YUI Check:** If the plugin uses YUI, it should notify the developer that it needs to transition to Mustache templates and output classes.
   
3. **Subplugin and Plugin Type Compatibility:**  
   Check if any subplugin types or main plugin types are deprecated. This would require updating plugin declarations and possibly migrating to the new processes provided in Moodle 5.0.
   
4. **Bootstrap Version Compatibility:**  
   Scan for Bootstrap 4 references in the plugin's CSS and suggest replacing them with Bootstrap 5 equivalents.
   
5. **PHPUnit Compatibility:**  
   Check if existing unit tests are compatible with PHPUnit 11 and suggest necessary updates.

## Step 3: Provide Fix Suggestions
For each compatibility issue detected, the AI agent suggests:
- **Code Fixes:** Example - replacing YUI with Mustache or updating Bootstrap classes.
- **Migration Strategies:** Suggest specific migration paths for deprecated types and subplugin updates.
- **Testing Updates:** Modify or create PHPUnit test cases to ensure compatibility with Moodle 5.0.

## Step 4: Feedback Loop
Once the agent suggests fixes:
- The developer reviews and adjusts based on the AI's feedback.
- The AI may assist in generating pull requests or patch files with suggested fixes.

## Step 5: User Interface Enhancements
In Cursor Editor, the following enhancements can be implemented:
- **Real-time Compatibility Checks:** As developers write or modify code, the AI flags compatibility issues on-the-fly.
- **Contextual Documentation Access:** Allow developers to view the `.md` files directly in the editor for reference while checking compatibility.

================
File: specs/2_Human_Date_Renderers.md
================
# 2. Human Date Renderers

**Change Summary:**
Moodle 5.0 introduces `humandate` and `humantimeperiod` classes for rendering dates and time periods in a human-readable format, replacing deprecated functions.

**Required Developer Action:**
- Utilize `humandate` for single timestamps and `humantimeperiod` for date/time ranges.
- Replace deprecated functions like `calendar_format_event_time` with the new classes.

**Compatibility Checkpoints:**
- Search for and replace deprecated date rendering functions.
- Implement the new classes as per the updated API.

================
File: specs/3_Course_Format_Migration.md
================
# 3. Course Format Migration

**Change Summary:**
Course formats relying on YUI libraries are deprecated. The new course editor uses output classes and Mustache templates.

**Required Developer Action:**
- Ensure course format plugins extend `core_courseformatase`.
- Implement renderers extending `core_courseformat\output\section_renderer`.
- Use Mustache templates for rendering UI elements.
- Replace YUI-based logic with the new course editor's reactive state and data attributes.

**Compatibility Checkpoints:**
- Verify the use of `core_courseformatase` and `section_renderer`.
- Ensure Mustache templates are used for rendering.
- Check for the removal of YUI dependencies.

================
File: specs/4_Plugin_Type_Deprecation.md
================
# 4. Plugin Type Deprecation

**Change Summary:**
A new process for deprecating plugin types has been introduced.

**Required Developer Action:**
- Mark plugin types as deprecated using the new deprecation process.
- Provide migration paths for deprecated plugin types.

**Compatibility Checkpoints:**
- Identify plugins using deprecated types.
- Implement migration strategies as per the new deprecation guidelines.

================
File: specs/5_Subplugin_Type_Deprecation.md
================
# 5. Subplugin Type Deprecation

**Change Summary:**
The process for deprecating subplugin types has been updated.

**Required Developer Action:**
- Update `subplugins.json` to reflect deprecated subplugin types.
- Ensure subplugins are compatible with the new deprecation process.

**Compatibility Checkpoints:**
- Review and update `subplugins.json` files.
- Test subplugins for compatibility with the new deprecation process.

================
File: specs/6_Bootstrap_5_Migration.md
================
# 6. Bootstrap 5 Migration

**Change Summary:**
Moodle 5.0 migrates to Bootstrap 5, introducing changes in styling and component behavior.

**Required Developer Action:**
- Replace Bootstrap 4 classes with their Bootstrap 5 equivalents.
- Utilize the BS5 "bridge" for gradual migration.
- Ensure compatibility with the new vanilla JavaScript components.

**Compatibility Checkpoints:**
- Audit themes and plugins for Bootstrap 4 dependencies.
- Update styling and components to align with Bootstrap 5 standards.

================
File: specs/7_PHPUnit_11_Upgrade.md
================
# 7. PHPUnit 11 Upgrade

**Change Summary:**
Moodle 5.0 upgrades to PHPUnit 11, requiring updates to test cases.

**Required Developer Action:**
- Update test cases to be compatible with PHPUnit 11.
- Address issues like empty data providers and deprecated annotations.

**Compatibility Checkpoints:**
- Run existing tests to identify failures.
- Modify tests to comply with PHPUnit 11 requirements.

================
File: specs/8 AI_Compatibility_Check_Implementation.md
================
# Implementing AI Compatibility Check for Moodle 5.0

## Organize and Upload Markdown Files
Ensure that each `.md` file, which represents a specific change or update for Moodle 5.0, is uploaded into the AI environment. These files will serve as the foundation for compatibility checks.

## AI Workflow Overview
1. **Plugin Detection:** The AI scans the plugin codebase to gather version information and identifies deprecated or unsupported features based on Moodle 5.0's new standards.
2. **Compatibility Analysis:** Using the provided `.md` documentation, the AI cross-checks the plugin’s features and code with Moodle 5.0 updates.
3. **Suggestion of Fixes:** After detecting compatibility issues, the AI suggests fixes by referencing specific code examples and migration strategies mentioned in the `.md` files.

## Example of AI Action Flow:
### Example 1: Compatibility Check for `index.php` Activity Page
- **Plugin Use Case:** The plugin uses the traditional `index.php` for activity page rendering.
- **AI Action:** Suggests replacing the `index.php` page with the new Activity Overview Page, using the `activityoverviewbase` class and corresponding template files.

### Example 2: Bootstrap 4 Update
- **Plugin Use Case:** The plugin uses Bootstrap 4 for UI components.
- **AI Action:** Flags the use of Bootstrap 4 and suggests migrating to Bootstrap 5, replacing classes as needed.

### Example 3: PHPUnit 11 Compatibility
- **Plugin Use Case:** The plugin’s test suite uses outdated PHPUnit versions.
- **AI Action:** Suggests updates to the test suite to comply with PHPUnit 11 standards.

## Integrating AI with Cursor Editor
- **Upload `.md` Files:** Add all the `.md` files containing detailed compatibility instructions into the system.
- **Real-Time Code Analysis:** As developers work, the AI continuously analyzes the codebase and checks for compatibility with Moodle 5.0.
- **Issue Reporting & Suggestions:** When the AI detects compatibility issues, it provides suggestions for fixing those issues directly in the editor.

## Conclusion
This approach enables the AI to assist developers in migrating and updating existing plugins or themes for Moodle 5.0 with minimal manual effort.

================
File: specs/9 AI_Compatibility_Enhancement_Strategy.md
================
# AI Compatibility Enhancement Strategy for Moodle 5.0

## Enhancing the AI's Analysis Abilities
To improve the AI's capability in detecting and fixing compatibility issues, the following strategies are recommended:

### 1. Detailed Codebase Scanning
The AI should be able to perform a comprehensive scan of plugin files:
- **File Structure Analysis:** Checking directory structures, class names, and method signatures.
- **Search for Deprecated Features:** Identifying obsolete methods and libraries used in the plugin.
- **Cross-reference with `.md` Files:** The AI should cross-reference the plugin’s code with the detailed updates provided in the `.md` documentation files.

### 2. Specific Fix Suggestions
The AI must not only detect the issues but also suggest specific code changes:
- **Code Snippets:** Provide code snippets for replacing deprecated methods, such as the transition from YUI to Mustache.
- **Template Recommendations:** Offer specific Mustache templates to replace old views or layouts.
- **JavaScript & CSS Updates:** Suggest Bootstrap 5 equivalents for UI components and provide sample changes for CSS.

### 3. Real-Time Code Modification
- **Real-Time Compatibility Checks:** The AI should highlight compatibility issues in real time as developers write or modify code.
- **One-Click Fixes:** Implement functionality where the AI can apply simple fixes automatically (e.g., replacing Bootstrap 4 classes with Bootstrap 5).

### 4. Testing and Validation
- **Automated Test Creation:** The AI should create or update test cases to ensure compliance with Moodle 5.0 standards.
- **Run PHPUnit Tests:** The AI should run existing tests and report any compatibility failures.

## Conclusion
By implementing these enhancements, the AI will significantly improve its ability to detect, suggest, and apply fixes for compatibility issues in existing Moodle plugins, making the migration to Moodle 5.0 smoother for developers.

================
File: specs/Roadmap.md
================
# Moodle 5.0 Plugin Compatibility Roadmap

This document provides an overview of the changes introduced in Moodle 5.0. It contains references to separate Markdown files detailing each change. The AI Agent should go through the following files one by one to review the required changes and ensure compatibility with existing plugins or themes.

## Instructions for the AI Agent:
- Review the following .md files in order.
- For each change or feature detailed, analyze the impact on existing plugins or themes.
- Provide suggestions for updates, fixes, or modifications needed to ensure compatibility with Moodle 5.0.

---

### 1. [Activity Overview Page Integration](./1_Activity_Overview_Page_Integration.md)
- Overview of updates related to the Activity Overview Page.
- Review how this change impacts the integration of activities and plugins on the overview page.

### 2. [Human Date Renderers](./2_Human_Date_Renderers.md)
- Information on updates to the `Human Date Renderers` in Moodle 5.0.
- Analyze how the changes affect date and time display logic in plugins, particularly for custom date formatting.

### 3. [Course Format Migration](./3_Course_Format_Migration.md)
- Changes in course format types and migration strategy.
- Guide the AI Agent to check for backward compatibility issues with course format plugins and handle migration properly.

### 4. [Plugin Type Deprecation](./4_Plugin_Type_Deprecation.md)
- Detailed explanation of deprecated plugin types in Moodle 5.0.
- Identify deprecated plugin types in existing plugins and provide recommendations for their replacement.

### 5. [Subplugin Type Deprecation](./5_Subplugin_Type_Deprecation.md)
- Changes regarding subplugin type deprecation.
- Focus on identifying deprecated subplugin types and outline necessary updates to existing subplugins.

### 6. [Bootstrap 5 Migration](./6_Bootstrap_5_Migration.md)
- Review of the migration process to Bootstrap 5 for Moodle 5.0.
- Assess the impact of this migration on front-end elements, theme compatibility, and styling of Moodle plugins.

### 7. [PHPUnit 11 Upgrade](./7_PHPUnit_11_Upgrade.md)
- Explanation of the upgrade to PHPUnit 11.
- Check how this affects testing frameworks and the compatibility of existing plugins with the new version of PHPUnit.

### 8. [AI Compatibility Workflow](./AI_Compatibility_Workflow.md)
- Overview of the workflow for ensuring AI compatibility in plugins.
- Review the steps needed for integrating AI-based solutions within Moodle plugins, particularly for compatibility with Moodle 5.0.

### 9. [AI Compatibility Check Implementation](./AI_Compatibility_Check_Implementation.md)
- Detailed guide on implementing AI compatibility checks.
- Review the methods and tools required to perform these checks and ensure compatibility with the latest Moodle release.

### 10. [AI Compatibility Enhancement Strategy](./AI_Compatibility_Enhancement_Strategy.md)
- Strategy for enhancing AI compatibility across Moodle plugins.
- Assess how to leverage AI improvements to ensure smoother functionality and performance in plugins under Moodle 5.0.

---

## Next Steps:
Once all files have been reviewed, the AI Agent should identify compatibility issues with existing plugins or themes and suggest necessary changes or actions to ensure full compatibility with Moodle 5.0.

================
File: styles/setup-wizard.css
================
/* Css to solve conflict in remui as this is page specific css applying 1 important  */
⋮----
#page{
⋮----
#page-wrapper{
/**/
⋮----
.eb-setup-sidebar{
⋮----
.eb_setup_popup a:hover{
⋮----
.eb_setup_check_permalink a:hover{
⋮----
.es-w-80{
⋮----
.es-p-t-b-30{
⋮----
.es-p-t-20{
⋮----
.es-p-b-10{
⋮----
.eb_setup_popup fieldset{
⋮----
.eb_setup_pupup_warning_icon{
⋮----
.eb_setup_wp_redirection_popup .eb_setup_popup_content{
⋮----
/* ---- Animated arrows ---- */
.animated {
⋮----
.animated__text .fa-solid.fa-angle-right{
⋮----
.animated__text {
⋮----
/* ----------------------------- */
⋮----
.eb_setup_product_sync_progress_images{
⋮----
.eb_setup_product_sync_progress_images > div{
⋮----
.eb_setup_product_sync_progress_images > div:first-child{
⋮----
.eb_setup_popup legend{
⋮----
.eb_setup_popup{
⋮----
.eb_setup_popup_content{
⋮----
.eb_setup_check_permalink a{
⋮----
.eb_setup_h3 .eb-tooltip{
⋮----
/* Tooltip */
.eb-tooltip {
⋮----
.eb-tooltiptext{
⋮----
.eb-tooltip .eb-tooltiptext {
⋮----
/* Position the tooltip */
⋮----
.eb-tooltip:hover .eb-tooltiptext {
⋮----
.eb-setup-content a{
⋮----
.eb-setup-content{
⋮----
.eb-setup-content.eb_setup_full_width{
/*****/
⋮----
/* ****  Checkbox styling.    **** */
⋮----
.esw-cb-container {
⋮----
/* Hide the browser's default checkbox */
.esw-cb-container input {
⋮----
/* Create a custom checkbox */
.esw-cb-checkmark {
⋮----
/* On mouse-over, add a grey background color */
.esw-cb-container:hover input ~ .esw-cb-checkmark {
⋮----
/* When the checkbox is checked, add a blue background */
.esw-cb-container input:checked ~ .esw-cb-checkmark {
⋮----
/* Create the checkmark/indicator (hidden when not checked) */
.esw-cb-checkmark:after {
⋮----
/* Show the checkmark when checked */
.esw-cb-container input:checked ~ .esw-cb-checkmark:after {
⋮----
/* Style the checkmark/indicator */
.esw-cb-container .esw-cb-checkmark:after {
⋮----
/* *****   END Checkbox styling  ***** */
⋮----
.eb-setup-header-logo{
⋮----
.es-info-icon{
⋮----
.eb-setup-header-logo-img-wrap{
⋮----
.eb-setup-header-logo-img-wrap img{
⋮----
.eb_setup_pupup_success_icon{
⋮----
.eb-completion-succ-h{
⋮----
.eb-setup-header-title-wrap{
⋮----
.eb-setup-header-title{
⋮----
/*color: white;*/
⋮----
/* identical to box height */
⋮----
.eb-setup-wizard-header{
⋮----
a.es_text_links{
⋮----
.eb-setup-wizard-footer{
⋮----
.eb-setup-footer-copyright{
⋮----
.eb-setup-footer-button{
⋮----
.eb-setup-wizard-footer .eb-setup-footer-button a{
⋮----
.eb-setup-footer-button a:hover{
⋮----
.eb_setup_free_initialize{
⋮----
.eb_setup_free_initialize > div{
⋮----
.eb_setup_free_initialize div p{
⋮----
.eb_setup_free_initialize_inp_wrap input{
⋮----
.eb_setup_free_initialize_inp_wrap label{
⋮----
/* identical to box height, or 162% */
⋮----
.eb_setup_free_initialize legend{
⋮----
/* identical to box height, or 157% */
⋮----
.eb_setup_free_initialize fieldset{
⋮----
.eb_setup_free_initialize fieldset p{
⋮----
.eb_setup_free_initialize div{
⋮----
.eb_setup_btn_wrap{
⋮----
.eb-setup-close-icon{
⋮----
.eb_setup_btn{
⋮----
.eb_setup_btn:hover{
⋮----
.eb_setup_h2{
⋮----
.eb_setup_h3{
⋮----
.eb_setup_h2 i{
⋮----
.eb_setup_h3 i{
⋮----
.eb_setup_sec_btn{
⋮----
.eb_setup_sec_btn:hover{
⋮----
.eb_setup_installation_guide .eb_setup_sec_btn{
⋮----
.eb_setup_installation_guide, .eb_setup_conn_url, .eb_setup_test_connection, .eb_setup_user_sync{
⋮----
.eb_setup_conn_url{
⋮----
.eb_setup_inp{
⋮----
.eb_setup_conn_url div{
⋮----
.eb_setup_course_sync div, .eb_setup_user_sync div{
⋮----
.eb_setup_license_inp_wrap{
⋮----
.eb_setup_license_inp_wrap div{
⋮----
.eb_setup_conn_url_inp_wrap, .eb_setup_user_and_course_sync {
⋮----
.eb_setup_user_and_course_sync{
⋮----
.eb_setup_inp_wrap{
⋮----
.eb_setup_conn_url_inp_wrap p{
⋮----
.eb_setup_conn_url_inp_wrap p .eb_setup_h2{
⋮----
.eb_setup_separator{
⋮----
.eb_setup_hr{
⋮----
.eb_setup_hr hr{
⋮----
.eb_setup_separator div span {
⋮----
/* identical to box height, or 130% */
⋮----
.eb_setup_course_sync_note, .eb_setup_user_sync_note{
⋮----
.eb_setup_course_sync_inp_wrap, .eb_setup_user_sync_inp_wrap{
⋮----
.eb_setup_course_sync_btn_wrap, .eb_setup_user_sync_btn_wrap{
⋮----
.eb_setup_course_sync fieldset, .eb_setup_user_sync fieldset{
⋮----
/* ---- accordion */
/* Style the buttons that are used to open and close the accordion panel */
.accordion {
⋮----
/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
.active {
⋮----
.accordion .fa-solid.fa-circle-question{
⋮----
.accordion i.fa-solid.fa-chevron-down,
⋮----
.accordion i.fa-solid.fa-chevron-up{
⋮----
.accordion.active i.fa-solid.fa-chevron-up {
⋮----
.accordion.active i.fa-solid.fa-chevron-down {
⋮----
.es-p-t-10{
⋮----
.accordion.active{
⋮----
/* Style the accordion panel. Note: hidden by default */
.panel {
⋮----
/* ----- */
⋮----
/*  */
⋮----
/* ------------- */
⋮----
.eb-loader-progsessing-anim {
⋮----
.eb-lading-parent-wrap {
⋮----
.eb-setup-steps li {
⋮----
.eb-setup-steps .eb-setup-step-circle {
⋮----
.eb-setup-step .eb-setup-step-circle  {
⋮----
.eb-setup-step-active .eb-setup-steps-title{
⋮----
.eb-setup-step-active {
⋮----
.eb-setup-step-circle-wrap{
⋮----
.eb_setup_web_service_name_wrap{
⋮----
.eb_setup_btn.disabled{
⋮----
.eb-setup-steps .eb-setup-steps-title {
⋮----
.eb-setup-steps .eb-setup-steps-title::before {
⋮----
.eb-setup-step .eb-setup-step-active {
⋮----
.eb-setup-step .eb-setup-step-completed{
⋮----
.eb_setup_sidebar_progress_icons{
⋮----
.eb_setup_site_name, .eb_setup_site_url{
⋮----
.eb-setup-step-completed-wrap .eb_setup_sidebar_progress_icons{
⋮----
.eb-setup-step-active-wrap .eb_setup_sidebar_progress_icons{
⋮----
.eb-setup-step-active-wrap{
⋮----
.eb-setup-steps .eb-setup-step-active-wrap .eb-setup-step-active{
⋮----
.eb-setup-steps .eb-setup-step-completed-wrap .eb-setup-step-completed{
⋮----
.eb-setup-steps strong {
⋮----
.eb-setup-steps {
⋮----
.eb-setup-step:last-child .eb-setup-steps-title::before {
⋮----
/* --------------- */
⋮----
.eb_plugin_configuration_checks{
⋮----
.eb_setup_web_service, .eb_plugin_configuration, .eb_plugin_configuration, .eb_setup_check_permalink, .eb_setup_complete_details{
⋮----
.eb_setup_complete_cards{
⋮----
.eb_setup_complete_card{
⋮----
.eb_setup_complete_cards .eb_setup_h2{
⋮----
.eb_setup_complete_card_wrap{
⋮----
.eb_setup_p_wrap{
⋮----
.eb_setup_settings_success_msg{
⋮----
.eb_setup_error_msg_box{
⋮----
/*****  Css to Hide elements temporarily   ****/
⋮----
.eb_plugin_configuration .eb_setup_save_and_continue, .eb_setup_wp_site_details_wrap, .eb_setup_test_connection_continue_btn{
⋮----
.eb_setup_complete_card .eb_setup_copy_icon{
⋮----
.eb_setup_copy{
⋮----
.eb_setup_copy_success{
⋮----
.eb_setup_complete_card > div{

================
File: styles/style.css
================
/*
* Enter template details
*/
⋮----
.eb_settings_btn {
⋮----
.eb_settings_btn_cont {
⋮----
.eb_admin_templ_dismiss_notice_message {
⋮----
.eb_service_field {
⋮----
.eb-tabs-cont {
⋮----
.eb-tabs {
⋮----
.eb-tabs:hover {
⋮----
.active-tab {
⋮----
.eb-error-msg {
⋮----
.eb_test_connection_log_open, .eb_test_connection_log_close{
⋮----
.eb_connection_short_msg{
⋮----
.eb_test_connection_log{
⋮----
.eb_connection_err_response{
⋮----
.eb_connection_err_response h4, .eb_connection_err_recommended_sec h4{
⋮----
.eb_connection_err_response div{
⋮----
.eb_connection_err_recommended_sec{
⋮----
.eb_connection_err_recommended_sec div{
⋮----
.eb_connection_err_recommended_sec ol li{
⋮----
.eb-success-msg {
⋮----
#id_eb_option_add_fields {
⋮----
.eb_setting_btn {
⋮----
.eb_connection_btns {
⋮----
#id_eb_mform_create_service {
⋮----
#eb_connection_form button {
⋮----
#admin-eb_setup_wizard_field {
⋮----
.eb_copy_txt_wrap {
⋮----
.eb_copy_div div:first-child {
⋮----
#id_eb_token {
⋮----
#fitem_id_eb_mform_token_wrap .form-control-static,
⋮----
.eb_primary_copy_btn {
⋮----
/***********  POP UP CSS   **************/
⋮----
/* Popup box BEGIN */
⋮----
.eb_service_pop_up {
⋮----
.eb_service_pop_up .helper {
.eb_service_pop_up > div {
⋮----
.eb_service_pop_up_close {
⋮----
.eb_service_pop_up_close:hover {
⋮----
/*********** END **************/
⋮----
/*********  Summary Page issue  *********/
⋮----
.summary_section_tbl {
⋮----
.summary_section_title {
⋮----
.summary_section {
⋮----
.sum_label {
⋮----
.sum_success {
⋮----
.summ_error {
⋮----
.eb_summary_tab {
⋮----
.summary_tab_sucess {
⋮----
.summary_tab_warning {
⋮----
.summary_tab_error {
⋮----
.summary_tab_sucess:hover {
⋮----
.summary_tab_warning:hover {
⋮----
.summary_tab_error:hover {
⋮----
.eb_pro_license_input{
.eb_pro_license_active{
.eb_pro_license_not_active{
.eb_pro_license_btn{
/*****************/

================
File: templates/create_token_field.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/create_token_field

    Create token field template.

    Context variables required for this template:
    * token_dropdown_lbl - Token dropdown label.
    * tokens - Token list.
    * copy_btn_text - Copy button text.

    Example context (JSON):
    {
        "token_dropdown_lbl": "Select Token",
        "tokens": [
            {
                id: 1,
                token: "token1",
                display: "",
                selected: "selected"
            }
        ],
        "copy_btn_text": "Copy"
    }

}}
<div class="eb_copy_txt_wrap">
    <div style="width:60%;">
        <select class="eb_copy custom-select" name="eb_token" id="id_eb_token">
            <option value="">{{token_dropdown_lbl}}</option>
            {{#tokens}}
            <option data-id="{{id}}" value="{{token}}" {{display}} {{selected}}>
                {{token}}
            </option>
            {{/tokens}}
        </select>
    </div>
    <div>
        <button class="btn btn-primary eb_primary_copy_btn">{{copy_btn_text}}</button>
    </div>
</div>

================
File: templates/installation_guide.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/installation_guide

    Setup wizard footer template

    Context variables required for this template:
    * installationnote1 - Installation note 1
    * modulenamefreewpplugin - Module name for free WP plugin
    * modulenamefreemdlplugin - Module name for free MDL plugin
    * installationnote2 - Installation note 2
    * continuebtn - Continue button text
    * step - Current step
    * nextstep - Next step
    * isnextsubstep - Is next step a sub step
    * installationfaq - Installation FAQ
    * faqdownloadplugin - Download plugin text
    * faqsteps - FAQ steps
    * faqstep1 - FAQ step 1
    * faqstep2 - FAQ step 2
    * faqstep3 - FAQ step 3
    * faqstep4 - FAQ step 4


    Example context (JSON):
    {
        "installationnote1": "value1",
        "modulenamefreewpplugin": "value2",
        "modulenamefreemdlplugin": "value3",
        "installationnote2": "value4",
        "continuebtn": "value5",
        "step": "value6",
        "nextstep": "value7",
        "isnextsubstep": "value8",
        "installationfaq": "value9",
        "faqdownloadplugin": "value10",
        "faqsteps": "value11",
        "faqstep1": "value12",
        "faqstep2": "value13",
        "faqstep3": "value14",
        "faqstep4": "value15"
    }

}}
<div class="eb_setup_installation_guide es-w-80">
    <div>
        <p class="eb_setup_p"> {{installationnote1}} </p>
        <div class="eb_setup_p_wrap">
            <p class="eb_setup_h2"> <i class="fa-solid fa-circle-chevron-right"></i> {{modulenamefreewpplugin}} </p>
            <p class="eb_setup_h2"> <i class="fa-solid fa-circle-chevron-right"></i> {{modulenamefreemdlplugin}} </p>
        </div>
        <span class="eb_setup_p"> {{installationnote2}} </span>
        <div class="eb_setup_btn_wrap">
            <button class="eb_setup_btn eb_setup_save_and_continue" data-step='{{step}}' data-next-step='{{nextstep}}' data-is-next-sub-step='{{isnextsubstep}}'>
                {{continuebtn}}
            </button>
        </div>
    </div>
    <div>
        <div class='es-p-t-10'>
            <div class='accordion'> <i class="fa-solid fa-circle-question"></i> {{installationfaq}} <i class="fa-solid fa-chevron-down"></i> <i class="fa-solid fa-chevron-up"></i> </div>
            <div class="panel">
                <div>
                    <a class="eb_setup_sec_btn" href='https://downloads.wordpress.org/plugin/edwiser-bridge.zip'> {{faqdownloadplugin}} </a>
                </div>
                <p>
                    <p class='es-p-t-10'> {{faqsteps}} </p>
                    <ol>
                        <li class='es-p-b-10'> {{faqstep1}} </li>
                        <li class='es-p-b-10'> {{faqstep2}} </li>
                        <li class='es-p-b-10'> {{faqstep3}} </li>
                        <li class='es-p-b-10'> {{faqstep4}} </li>
                    </ol>
                </p>
            </div>
        </div>
    </div>
</div>

================
File: templates/license_form.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/license_form

    Edwiser Bridge license form template

    Context variables required for this template:
    * isvalidlicense: Is valid license
    * licensekey: License key
    * deactivate: Deactivate
    * licensestatus: License status
    * ebactive: Active
    * activate: Activate

    Example context (JSON):
    {
        "isvalidlicense": "value1",
        "licensekey": "value2",
        "deactivate": "value3",
        "licensestatus": "value4",
        "ebactive": "value5",
        "activate": "value6"
}}
<form method="post">
    <input type="text" class="eb_pro_license_input" name="eb_license_key" placeholder="License key" value="{{ licensekey }}" />
    {{# isvalidlicense }}
        <span class="eb_pro_license_active">{{{ ebactive }}}</span>
        <input type="submit" name="eb_license_deactivate" class="eb_pro_license_btn" value="{{ deactivate }}" />
    {{/ isvalidlicense }}
    {{^ isvalidlicense }}
        <span class="eb_pro_license_not_active">{{ licensestatus }}</span>
        <input type="submit" name="eb_license_activate" class="eb_pro_license_btn" value="{{ activate }}" />
    {{/ isvalidlicense }}
</form>

================
File: templates/permalink.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/permalink

    Setup wizard permalink template

    Context variables required for this template:
    * setuppermalinknote1: Setup permalink note 1
    * setuppermalinknote2: Setup permalink note 2
    * setuppermalinknote3: Setup permalink note 3
    * espostname: Post name
    * setuppermalinkclick: Setup permalink click
    * url: Url
    * prevurl: Previous url
    * back: Back
    * step: Step
    * nextstep: Next step
    * isnextsubstep: Is next sub step
    * confirmed: Confirmed


    Example context (JSON):
    {
        "setuppermalinknote1": "value1",
        "setuppermalinknote2": "value2",
        "setuppermalinknote3": "value3",
        "espostname": "value4",
        "setuppermalinkclick": "value5",
        "url": "value6",
        "prevurl": "value7",
        "back": "value8",
        "step": "value9",
        "nextstep": "value10",
        "isnextsubstep": "value11",
        "confirmed": "value12"
    }
}}
<div class='eb_setup_check_permalink es-w-80'>
    <div>
        <div>
            <p class="">
                {{{setuppermalinknote1}}}<b>{{{espostname}}}</b>
            </p>
            <p class="">
                {{{setuppermalinkclick}}}
                <a class="es_text_links" target="_blank" href="{{url}}">{{url}}</a>
                {{{setuppermalinknote2}}}
            </p>
            <div class="">{{{setuppermalinknote3}}}</div>
        </div>
        <div>
            <div class="eb_setup_btn_wrap">
                <a class="eb_setup_sec_btn" href="{{prevurl}}">
                    {{{back}}}
                </a>
                <button
                    class="eb_setup_btn eb_setup_save_and_continue"
                    data-step='{{step}}'
                    data-next-step='{{nextstep}}'
                    data-is-next-sub-step='{{isnextsubstep}}'>
                    {{{confirmed}}}
                </button>
            </div>
        </div>
    </div>
</div>

================
File: templates/plugin_configuration.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/plugin_configuration

    Setup wizard plugin configuration template

    Context variables required for this template:
    * setupmdlpluginnote1 : Setup mdl plugin note 1
    * checks: Checks
    * setupmdlsettingssuccessmsg: Setup mdl settings success msg
    * display_note1: Display note
    * setupmdlpluginnote2: Setup mdl plugin note 2
    * step: Step
    * nextstep: Next step
    * isnextsubstep: Is next sub step
    * setupenablesettings: Setup enable settings
    * displaycontinue: Display continue
    * setupcontinuebtn: Setup continue btn

    Example context (JSON):
    {
        "setupmdlpluginnote1": "value1",
        "checks": "value2",
        "setupmdlsettingssuccessmsg": "value3",
        "display_note1": "value4",
        "setupmdlpluginnote2": "value5",
        "step": "value6",
        "nextstep": "value7",
        "isnextsubstep": "value8",
        "setupenablesettings": "value9",
        "displaycontinue": "value10",
        "setupcontinuebtn": "value11"
    }
}}
<div class="eb_plugin_configuration es-w-80">
    <div>
        <p>{{{setupmdlpluginnote1}}}</p>
        <div class="eb_plugin_configuration_checks">
            {{#checks}}
            <div class="eb_setup_h3 es-p-b-10">
                <i class="fa-solid fa-circle-check {{icon_class}}" style="{{style}}"></i>
                {{{check_text}}}
                <i class="fa-solid fa-info eb-tooltip es-info-icon">
                    <span class='eb-tooltiptext'>{{{tooltip_text}}}</span>
                </i>
            </div>
            {{/checks}}
            <div class="eb_setup_settings_success_msg">
                <i class="fa-solid fa-circle-check"></i>
                {{{setupmdlsettingssuccessmsg}}}
            </div>
        </div>
        <div style="{{displaynote}}">
            <span class="eb_enable_plugin_settings_label">{{{setupmdlpluginnote2}}}</span>
            <button
                class="eb_setup_btn eb_enable_plugin_settings"
                data-step='{{step}}'
                data-next-step='{{nextstep}}'
                data-is-next-sub-step='{{isnextsubstep}}'>
                {{{setupenablesettings}}}
            </button>
        </div>
        <div class="eb_setup_btn_wrap">
            <button
                class="eb_setup_btn eb_setup_save_and_continue"
                style="{{displaycontinue}}"
                data-step='{{step}}'
                data-next-step='{{nextstep}}'
                data-is-next-sub-step='{{isnextsubstep}}'>
                {{{setupcontinuebtn}}}
            </button>
        </div>
    </div>
</div>

================
File: templates/plugin_update_notification.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/plugin_update_notification

    Plugin update notification template

    Context variables required for this template:
    * pluginupdatenotificationtitle: Plugin update notification title
    * pluginupdatenotificationbody: Plugin update notification body
    * pluginupdatenotificationchangelog: Plugin update notification changelog
    * changelogurl: Changelog url
    * plugindownload: Plugin download
    * plugindownloadhelptext: Plugin download help text
    * downloadurl: Download url
    * pluginupdatenotificationchangelog: Plugin update notification changelog
    * plugindownload: Plugin download
    * updateurl: Update url
    * pluginupdatehelptext: Plugin update help text
    * pluginupdate: Plugin update
    * dismissurl: Dismiss url


    Example context (JSON):
    {
        "pluginupdatenotificationtitle": "value1",
        "pluginupdatenotificationbody": "value2",
        "pluginupdatenotificationchangelog": "value3",
        "changelogurl": "value4",
        "plugindownload": "value5",
        "plugindownloadhelptext": "value6",
        "downloadurl": "value7",
        "pluginupdate": "value8",
        "updateurl": "value9",
        "pluginupdatehelptext": "value10",
        "dismissurl": "value11"
        "dismissurl": "value12"
    }
}}
<div class="eb-plugin-update-notice">
    <p class="eb-plugin-update-notice-heading">
        {{ pluginupdatenotificationtitle }}
    </p>
    <p class="eb-plugin-update-notice-body">
        {{ pluginupdatenotificationbody }}
        <a class="eb-plugin-update-changelog" target="_blank" href="{{ changelogurl }}">
            {{ pluginupdatenotificationchangelog }}
        </a>
    </p>
    <p class="eb-plugin-update-action">
        <a href="{{ downloadurl }}" title="{{ plugindownloadhelptext }}">
            {{ plugindownload }}
        </a>
        <span> | </span>
        <a href="{{ updateurl }}" title="{{ pluginupdatehelptext }}">
            {{ pluginupdate }}
        </a>
    </p>
    <a class="eb-plugin-update-dismiss" href="{{ dismissurl }}">x</a>
</div>

================
File: templates/setup_close.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/setup_close

    Setup wizard header template

    Context variables required for this template:
    * closequest: Close quest
    * yes: Yes
    * no: No
    * note: Note
    * closenote: Close note
    * wwwroot: Wwwroot


    Example context (JSON):
    {
        "closequest": "value1",
        "yes": "value2",
        "no": "value3",
        "note": "value4",
        "closenote": "value5",
        "wwwroot": "value6",
    }
}}
<div class="eb_setup_popup_content_wrap" style="display: none;">
    <div class="eb_setup_popup_content">
        <div>
            <p><i class="fa-solid fa-triangle-exclamation eb_setup_pupup_warning_icon"></i></p>
            <p class="eb_setup_h2">{{{ closequest }}}</p>
            <div class="eb_setup_user_sync_btn_wrap">
                <a href="{{{ wwwroot }}}" class="eb_setup_sec_btn">{{{ yes }}}</a>
                <button class="eb_setup_sec_btn eb_setup_do_not_close">{{{ no }}}</button>
            </div>
        </div>
        <div>
            <fieldset>
                <legend>{{{ note }}}</legend>
                <div>{{{ closenote }}}</div>
            </fieldset>
        </div>
    </div>
</div>

================
File: templates/setup_complete_details.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/setup_complete_details

    Setup wizard complete details template

    Context variables required for this template:
    * whatnext: The heading text for the "What's Next?" section.
    * setupcompletionnote1: The note text for the "What's Next?" section.
    * setupcompletionnote2: The heading text for the setup completion cards section.
    * mdlurl: The heading text for the Moodle URL card.
    * url: The Moodle URL value.
    * wptoken: The heading text for the WordPress token card.
    * token: The WordPress token value.
    * ebmformlangdesc: The heading text for the language code card.
    * lang: The language code value.
    * or: The text to display between the setup completion cards and the download credentials button.
    * setupcompletionnote3: The heading text for the download credentials section.
    * mdledwiserbridgetxtdownload: The text for the download credentials button.
    * setupcompletionnote4: The note text for the final section.
    * back: The text for the "Back" button.
    * prevurl: The URL for the "Back" button.
    * continuewpwizardbtn: The text for the "Continue to WordPress Wizard" button.
    * wpurl: The URL for the "Continue to WordPress Wizard" button.
    * step: The current step in the setup wizard.
    * nextstep: The next step in the setup wizard.
    * isnextsubstep: A flag indicating whether the next step is a sub-step.
    * setupcontinuebtn: The text for the "Continue" button (hidden by default).
    * ebsetupredirectionpopup: The HTML content for the redirection popup.
    * ebsetupcompletionpopup: The HTML content for the completion popup.

    Example context (JSON):
    {
        "whatnext": "value1",
        "setupcompletionnote1": "value1",
        "setupcompletionnote2": "value1",
        "mdlurl": "value1",
        "url": "value1",
        "wptoken": "value1",
        "token": "value1",
        "ebmformlangdesc": "value1",
        "lang": "value1",
        "or": "value1",
        "setupcompletionnote3": "value1",
        "mdledwiserbridgetxtdownload": "value1",
        "setupcompletionnote4": "value1",
        "back": "value1",
        "prevurl": "value2",
        "continuewpwizardbtn": "value1",
        "wpurl": "value2",
        "step": "value1",
        "nextstep": "value1",
        "isnextsubstep": "value1",
        "setupcontinuebtn": "value1",
        "ebsetupredirectionpopup": "value1",
        "ebsetupcompletionpopup": "value1"
    }
}}
<div class="eb_setup_complete_details es-w-80">
    <div>
        <div>
            <span class='eb_setup_h2'>{{{whatnext}}}</span>
            <div>{{{setupcompletionnote1}}}</div>
        </div>
        <div class="eb_setup_complete_card_wrap">
            <div class="eb_setup_h2">
                <i class="fa-solid fa-circle-chevron-right"></i>
                {{{setupcompletionnote2}}}</div>
            <div class="eb_setup_complete_cards">
                <div class="eb_setup_complete_card eb_setup_copy" data-copy='{{url}}'>
                    <div>
                        <span class="eb_setup_h2">{{{mdlurl}}}</span>
                        <div class="eb_setup_copy_url">{{url}}</div>
                    </div>
                    <div class="eb_setup_copy_icon" data-copy='{{url}}'>
                        <i class="fa-solid fa-copy"></i>
                    </div>
                </div>
                <div class="eb_setup_complete_card eb_setup_copy" data-copy='{{token}}'>
                    <div>
                        <span class="eb_setup_h2">{{{wptoken}}}</span>
                        <div class="eb_setup_copy_token" style="word-break:break-all;">{{token}}</div>
                    </div>
                    <div class="eb_setup_copy_icon" data-copy='{{token}}'>
                        <i class="fa-solid fa-copy"></i>
                    </div>
                </div>
                <div class='eb_setup_complete_card eb_setup_copy' data-copy='{{lang}}'>
                    <div>
                        <span class='eb_setup_h2'>{{{ebmformlangdesc}}}</span>
                        <div class="eb_setup_copy_lang">{{lang}}</div>
                    </div>
                    <div class="eb_setup_copy_icon" data-copy='{{lang}}'>
                        <i class="fa-solid fa-copy"></i>
                    </div>
                </div>
            </div>
            <div class="eb_setup_separator">
                <div class="eb_setup_hr">
                    <hr>
                </div>
                <div>
                    <span>{{{or}}}</span>
                </div>
                <div class="eb_setup_hr">
                    <hr>
                </div>
            </div>
            <p class="eb_setup_h2">
                <i class="fa-solid fa-circle-chevron-right"></i>
                {{{setupcompletionnote3}}}</p>
            <button class="eb_setup_sec_btn eb_setup_download_creds">
                {{{mdledwiserbridgetxtdownload}}}</button>
        </div>
        <div>
            <p>{{{setupcompletionnote4}}}</p>
            <div class="eb_setup_btn_wrap">
                <a class="eb_setup_sec_btn" href="{{prevurl}}">
                    {{{back}}}
                </a>
                <a class='eb_setup_btn eb_redirect_to_wp' target='_blank' href="{{wpurl}}" data-step='{{step}}' data-next-step='{{nextstep}}' data-is-next-sub-step='{{isnextsubstep}}'>
                    {{{continuewpwizardbtn}}}
                </a>
                <a style='display: none;' class='eb_setup_btn eb_redirect_to_wp_btn' target='_blank' href="{{wpurl}}">
                    {{{setupcontinuebtn}}}
                </a>
            </div>
        </div>
    </div>
    <div>{{{ebsetupredirectionpopup}}}</div>
    <div>{{{ebsetupcompletionpopup}}}</div>
</div>

================
File: templates/setup_completion_popup.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/setup_completion_popup

    Setup wizard completion popup template

    Context variables required for this template:
    * setupcompletionnote5: Setup completion note 5

    Example context (JSON):
    {
        "setupcompletionnote5": "value1",
    }
}}
<div class='eb_setup_wp_completion_success_popup' style='display: none;'>
    <div class='eb_setup_popup_content'>
        <div>
            <p><i class="fa-solid fa-circle-check eb_setup_pupup_success_icon"></i></p>
            <p class="eb-completion-succ-h">{{ setupcompletionnote5 }}</p>
        </div>
    </div>
</div>

================
File: templates/setup_redirection_popup.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/setup_redirection_popup

    Setup wizard redirection popup template
}}
<div class='eb_setup_wp_redirection_popup' style='display: none;'>
    <div class='eb_setup_popup_content'>
        <div class='eb_setup_h2 es-p-t-20'>
            {{#str}} redirecting_to_wp_setup_wizard, auth_edwiserbridge {{/str}}
        </div>
        <div class='eb_setup_product_sync_progress_images'>
            <div class='eb_setup_users_sync_wp_img'>
                <img src="images/moodle-logo.png" />
            </div>
            <div class='eb_setup_product_sync_progress_arrows'>
                <div class="animated  animated--on-hover mt-2">
                    <span class="animated__text">
                        <i class="fa-solid fa-angle-right" style='color:#bedbe2;width:7px;'></i>
                        <i class="fa-solid fa-angle-right" style='color:#76bccc;width:7px;'></i>
                        <i class="fa-solid fa-angle-right" style='color:#5abec3;width:7px;'></i>
                        <i class="fa-solid fa-angle-right" style='color:#14979d;width:7px;'></i>
                        <i class="fa-solid fa-angle-right" style='color:#007075;width:7px;'></i>
                    </span>
                </div>
            </div>
            <div class='eb_setup_users_sync_mdl_img'>
                <img src="images/wp-logo.png" />
            </div>
        </div>
    </div>
</div>

================
File: templates/setup_steps.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/setup_steps

    Setup wizard header template

    Context variables required for this template:
    steps: An array of step objects, each containing the following properties:
    key: A unique identifier for the step.
    name: The display name of the step.
    htmlicon: The HTML code for the step icon.
    iscompleted: A boolean indicating whether the step has been completed.
    isactive: A boolean indicating whether the step is currently active.
    toplevel: A boolean indicating whether the step is a top-level step.
    
    Example context (JSON):
    {
        "steps": [
          {
            "key": "step1",
            "name": "Step 1",
            "htmlicon": "<i class='icon fa fa-check'></i>",
            "iscompleted": true,
            "isactive": false,
            "toplevel": true
          },
          {
            "key": "step2",
            "name": "Step 2",
            "htmlicon": "<i class='icon fa fa-times'></i>",
            "iscompleted": false,
            "isactive": true,
            "toplevel": true
          }
        ]
    }
}}
<ul class="eb-setup-steps">
    {{#steps}}
        {{#toplevel}}
            <li class="eb-setup-step eb-setup-step-{{key}} {{#iscompleted}}eb-setup-step-completed{{/iscompleted}}{{#isactive}}eb-setup-step-active{{/isactive}}-wrap">
                {{{htmlicon}}}
                <span class="eb-setup-steps-title {{#iscompleted}}eb-setup-step-completed{{/iscompleted}}" data-step="{{key}}">
                    {{name}}
                </span>
            </li>
        {{/toplevel}}
    {{/steps}}
</ul>

================
File: templates/setup_wizard_footer.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/setup_wizard_footer

    Setup wizard footer template

    Context variables required for this template:
    * footertext: footer text
    * contactustext: contact us text
    * closesetup: close setup text

    Example context (JSON):
    {
        "footertext": "value1",
        "contactustext": "value2",
        "closesetup": "value3"
    }

}}
<footer class='eb-setup-wizard-footer'>
    <div class='eb-setup-footer-copyright'>
        {{footertext}}
    </div>
    <div class='eb-setup-footer-button'>
        <a href='https://edwiser.org/contact-us/' target='_blank'>
            {{contactustext}}
        </a>
    </div>
    <div>{{{closesetup}}}</div>
</footer>
</body>
</html>

================
File: templates/setup_wizard_header.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/setup_wizard_header

    Setup wizard header template

    Context variables required for this template:
    * pagetitle: Page title
    * logosrc: Logo source
    * headertitle: Header title

    Example context (JSON):
    {
        "pagetitle": "value1",
        "logosrc": "value2",
        "headertitle": "value3"
    }
}}
<!DOCTYPE html>
<html>
<head>
    <title>{{pagetitle}}</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body class="wc-setup wp-core-ui ">
    <header class="eb-setup-wizard-header">
        <div class="eb-setup-header-logo">
            <div class="eb-setup-header-logo-img-wrap">
                <img src="{{logosrc}}" />
            </div>
        </div>
        <div class="eb-setup-header-title-wrap">
            <div class="eb-setup-header-title">{{headertitle}}</div>
            <div class='eb-setup-close-icon'> <i class="fa-solid fa-xmark"></i> </div>
        </div>
    </header>

================
File: templates/setup_wizard_template.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/setup_wizard_template

    Setup wizard header template

    Context variables required for this template:
    * sidebar: Sidebar
    * contentclass: Content class
    * content: Content

    Example context (JSON):
    {
        "sidebar": "value1",
        "contentclass": "value2",
        "content": "value3",
    }
}}
<div class='eb-setup-content-area'>
    <!-- Sidebar -->
    <div class='eb-setup-sidebar'>
        {{{sidebar}}}
    </div>
    <!-- Content -->
    <div class="eb-setup-content {{contentclass}}">
        {{{content}}}
    </div>
</div>

================
File: templates/test_connection.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/test_connection

    Test connection template

    Context variables required for this template:
    * wpsitedetailsnote: Note about WordPress site details
    * namelabel: Label for site name
    * wpsitenametip: Tooltip text for site name
    * name: Site name value
    * urllabel: Label for site URL
    * wpsiteurltip: Tooltip text for site URL
    * url: Site URL value
    * prevurl: Previous URL
    * back: Back button text
    * wptestconnbtn: Test connection button text
    * step: Current step
    * nextstep: Next step
    * isnextsubstep: Flag indicating if next step is a sub-step
    * setupcontinuebtn: Continue button text

    Example context (JSON):
    {
        "wpsitedetailsnote": "value1",
        "namelabel": "value2",
        "wpsitenametip": "value3",
        "name": "value4",
        "urllabel": "value5",
        "wpsiteurltip": "value6",
        "url": "value7",
        "prevurl": "value8",
        "back": "value9",
        "wptestconnbtn": "value10",
        "step": "value11",
        "nextstep": "value12",
        "isnextsubstep": "value13",
        "setupcontinuebtn": "value14"
    }
}}
<div class="eb_setup_wordpress_site_details es-w-80">
    <div>
        <div class="eb_setup_conn_url_inp_wrap">
            <span>{{{wpsitedetailsnote}}}</span>
            <p>
                <label class="eb_setup_h2">{{{namelabel}}}</label>
                <i class="fa-solid fa-info eb-tooltip es-info-icon">
                    <span class='eb-tooltiptext'>{{{wpsitenametip}}}</span>
                </i>
            </p>
            <input class="eb_setup_inp eb_setup_site_name" name="eb_setup_site_name" type="text" value="{{name}}" disabled>
        </div>
        <div class="eb_setup_conn_url_inp_wrap">
            <p>
                <label class="eb_setup_h2">{{{urllabel}}}</label>
                <i class="fa-solid fa-info eb-tooltip es-info-icon">
                    <span class='eb-tooltiptext'>{{{wpsiteurltip}}}</span>
                </i>
            </p>
            <input class="eb_setup_inp eb_setup_site_url" name="eb_setup_site_url" type="url" value="{{url}}" disabled>
            <div class="eb_setup_test_conn_resp_msg"></div>
        </div>
        <div class="eb_setup_btn_wrap">
            <a class="eb_setup_sec_btn" href="{{prevurl}}">
                {{{back}}}
            </a>
            <button class="eb_setup_btn eb_setup_test_connection_btn" data-step="{{step}}" data-next-step="{{nextstep}}" data-is-next-sub-step="{{isnextsubstep}}">
                {{{wptestconnbtn}}}
            </button>
            <button class="eb_setup_btn eb_setup_save_and_continue eb_setup_test_connection_continue_btn" data-step="{{step}}" data-next-step="{{nextstep}}" data-is-next-sub-step="{{isnextsubstep}}">
                {{{setupcontinuebtn}}}
            </button>
        </div>
    </div>
</div>

================
File: templates/user_and_course_sync.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/user_and_course_sync

    User and course sync template

    Context variables required for this template:
    * setupsyncnote1: Note for user and course sync
    * selectall: Text for "Select All" option
    * recommended: Text indicating "Recommended" option
    * allchecked: Boolean indicating if "Select All" option is checked
    * syncsettings: Array of sync settings
      - name: Name of the sync setting
      - label: Label for the sync setting
      - tip: Tooltip text for the sync setting
      - checked: Boolean indicating if the sync setting is checked
    * prevurl: URL for the previous step
    * nexturl: URL for the next step
    * back: Text for the "Back" button
    * skip: Text for the "Skip" button
    * setupcontinuebtn: Text for the "Continue" button
    * step: Current step number
    * nextstep: Next step number
    * isnextsubstep: Boolean indicating if the next step is a sub-step

    Example context (JSON):
    {
        "setupsyncnote1": "value1",
        "selectall": "value2",
        "recommended": "value3",
        "allchecked": true,
        "syncsettings": [
        {
            "name": "setting1",
            "label": "value4",
            "tip": "value5",
            "checked": true
        },
        {
            "name": "setting2",
            "label": "value6",
            "tip": "value7",
            "checked": false
        }
        ],
        "prevurl": "value8",
        "nexturl": "value9",
        "back": "value10",
        "skip": "value11",
        "setupcontinuebtn": "value12",
        "step": 1,
        "nextstep": 2,
        "isnextsubstep": false
    }
}}
<div class="eb_setup_user_and_course_sync es-p-t-b-30 es-w-80">
    <div>
        <div>
            <p>{{{setupsyncnote1}}}</p>
            <div class="eb_setup_inp_wrap">
                <label class='esw-cb-container'>
                    <input type='checkbox' name='eb_setup_sync_all' id='eb_setup_sync_all' {{#allchecked}}checked{{/allchecked}}>
                    <span class='esw-cb-checkmark'></span>
                    <span class="eb_setup_h2">{{{selectall}}} {{{recommended}}}</span>
                </label>
            </div>
            <hr>
            {{#syncsettings}}
            <div class="eb_setup_inp_wrap">
                <label class='esw-cb-container'>
                    <input type='checkbox' class="eb_setup_sync_cb" name='{{name}}' id='{{name}}' {{#checked}}checked{{/checked}}>
                    <span class='esw-cb-checkmark'></span>
                    <span class="eb_setup_h2">{{{label}}}</span>
                    <i class="fa-solid fa-info eb-tooltip es-info-icon">
                        <span class='eb-tooltiptext'>{{{tip}}}</span>
                    </i>
                </label>
            </div>
            {{/syncsettings}}
            <div class="eb_setup_btn_wrap">
                <a class="eb_setup_sec_btn" href="{{prevurl}}">
                    {{{back}}}
                </a>
                <a class="eb_setup_sec_btn" href="{{nexturl}}">
                    {{{skip}}}
                </a>
                <button class="eb_setup_btn eb_setup_save_and_continue" data-step="{{step}}" data-next-step="{{nextstep}}" data-is-next-sub-step="{{isnextsubstep}}">
                    {{{setupcontinuebtn}}}
                </button>
            </div>
        </div>
    </div>
</div>

================
File: templates/web_service.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/web_service

    Web service template

    Context variables required for this template:
    * setupwebservicenote1: Note for setting up web service
    * setupwebserviceh1: Heading 1 for setting up web service
    * setupwebserviceh2: Heading 2 for setting up web service
    * or: Text for "or" separator
    * sumwebservices: Label for existing web services dropdown
    * webservicetip: Tooltip text for web services dropdown
    * existingservices: Array of existing web services
        ** key: Key for the web service
        ** value: Value for the web service
        ** selected: Whether the option is selected or not
    * newserviceinplbl: Label for new web service input
    * namewebservicetip: Tooltip text for new web service input
    * setupcontinuebtn: Text for continue button
    * step: Current step number
    * nextstep: Next step number
    * isnextsubstep: Whether the next step is a sub-step or not
    * disable: Class to disable the continue button

    Example context (JSON):
    {
        "setupwebservicenote1": "value1",
        "setupwebserviceh1": "value2",
        "setupwebserviceh2": "value3",
        "or": "value4",
        "sumwebservices": "value5",
        "webservicetip": "value6",
        "existingservices": [
            {
                "key": "value7",
                "value": "value8",
                "selected": true
            },
            {
                "key": "value9",
                "value": "value10",
                "selected": false
            }
        ],
        "newserviceinplbl": "value11",
        "namewebservicetip": "value12",
        "setupcontinuebtn": "value13",
        "step": "value14",
        "nextstep": "value15",
        "isnextsubstep": true,
        "disable": "value16"
    }
}}
<div class="eb_setup_web_service es-w-80">
    <div>
        <p>{{{setupwebservicenote1}}}</p>
        <div class="eb_setup_p_wrap">
            <div class="eb_setup_h2">
                <i class="fa-solid fa-circle-chevron-right"></i>
                {{{setupwebserviceh1}}}
            </div>
            <div class="eb_setup_separator">
                <div class="eb_setup_hr"><hr></div>
                <div><span>{{{or}}}</span></div>
                <div class="eb_setup_hr"><hr></div>
            </div>
            <div class="eb_setup_h2">
                <i class="fa-solid fa-circle-chevron-right"></i>
                {{{setupwebserviceh2}}}
            </div>
        </div>
        <div>
            <div class="eb_setup_conn_url_inp_wrap">
                <p>
                    <label class="eb_setup_h2">{{{sumwebservices}}}</label>
                    <i class="fa-solid fa-info eb-tooltip es-info-icon">
                        <span class='eb-tooltiptext'>{{{webservicetip}}}</span>
                    </i>
                </p>
                <select name="eb_setup_web_service_list" class="eb_setup_inp eb_setup_web_service_list">
                    {{#existingservices}}
                    <option value="{{key}}" {{selected}}>{{value}}</option>
                    {{/existingservices}}
                </select>
            </div>
            <div class="eb_setup_conn_url_inp_wrap eb_setup_web_service_name_wrap">
                <p>
                    <label class="eb_setup_h2">{{{newserviceinplbl}}}</label>
                    <i class="fa-solid fa-info eb-tooltip es-info-icon">
                        <span class='eb-tooltiptext'>{{{namewebservicetip}}}</span>
                    </i>
                </p>
                <input class="eb_setup_inp eb_setup_web_service_name" id="eb_setup_web_service_name" name="eb_setup_web_service_name" type="text">
            </div>
            <div class="eb_setup_btn_wrap">
                <button class="eb_setup_btn eb_setup_web_service_btn eb_setup_save_and_continue {{disable}}"
                        data-step='{{step}}'
                        data-next-step='{{nextstep}}'
                        data-is-next-sub-step='{{isnextsubstep}}' {{disable}}>
                    {{{setupcontinuebtn}}}
                </button>
            </div>
        </div>
    </div>
</div>

================
File: templates/wordpress_site_details.mustache
================
{{!
    This file is part of Moodle - http://moodle.org/

    Moodle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Moodle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

    Edwiser Bridge
    @package auth_edwiserbridge
    @copyright (c) 2024 WisdmLabs (https://wisdmlabs.com/)
    @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
}}
{{!
    @template auth_edwiserbridge/wordpress_site_details

    WordPress site details template

    Context variables required for this template:
    * setupwpsitenote1: Note 1 for setting up WordPress site
    * setupwpsitedropdown: Label for WordPress site dropdown
    * wpsitetip: Tooltip text for WordPress site dropdown
    * select: Option text for select option
    * createwpsite: Option text for creating a new WordPress site
    * sites: Array of existing WordPress sites
        - key: Unique identifier for the site
        - name: Name of the site
        - url: URL of the site
        - selected: Whether the site is selected or not (true/false)
    * class: CSS class for WordPress site details input wrappers
    * setupwpsitenote2: Note 2 for setting up WordPress site
    * namelabel: Label for site name input
    * wpsitenametip: Tooltip text for site name input
    * selectedname: Pre-filled value for site name input
    * urllabel: Label for site URL input
    * wpsiteurltip: Tooltip text for site URL input
    * selectedurl: Pre-filled value for site URL input
    * prevurl: URL for the previous step
    * back: Text for the back button
    * setupcontinuebtn: Text for the continue button
    * step: Current step number
    * nextstep: Next step number
    * isnextsubstep: Whether the next step is a sub-step or not (true/false)
    * btnclass: CSS class for the continue button

    Example context (JSON):
    {
        "setupwpsitenote1": "value1",
        "setupwpsitedropdown": "value2",
        "wpsitetip": "value3",
        "select": "value4",
        "createwpsite": "value5",
        "sites": [
            {
                "key": "value6",
                "name": "value7",
                "url": "value8",
                "selected": "value9"
            }
        ],
        "class": "value10",
        "setupwpsitenote2": "value11",
        "namelabel": "value12",
        "wpsitenametip": "value13",
        "selectedname": "value14",
        "urllabel": "value15",
        "wpsiteurltip": "value16",
        "selectedurl": "value17",
        "prevurl": "value18",
        "back": "value19",
        "setupcontinuebtn": "value20",
        "step": "value21",
        "nextstep": "value22",
        "isnextsubstep": "value23",
        "btnclass": "value24"
    }
}}
<div class="eb_setup_wordpress_site_details es-w-80">
    <div>
        <div>
            <div class="eb_setup_conn_url_inp_wrap">
                <p>{{{setupwpsitenote1}}}</p>
                <p>
                    <label class="eb_setup_h2">{{{setupwpsitedropdown}}}</label>
                    <i class="fa-solid fa-info eb-tooltip es-info-icon">
                        <span class='eb-tooltiptext'>{{{wpsitetip}}}</span>
                    </i>
                </p>
                <select name="eb_setup_wp_sites" class="eb_setup_inp eb_setup_wp_sites">
                    <option value="">{{{select}}}</option>
                    <option value="create">{{{createwpsite}}}</option>
                    {{#sites}}
                    <option data-name="{{name}}" data-url="{{url}}" value="{{key}}" {{selected}}>{{name}}</option>
                    {{/sites}}
                </select>
            </div>
            <div class="eb_setup_wp_site_details_inp eb_setup_conn_url_inp_wrap {{class}}">
                <span>{{{setupwpsitenote2}}}</span>
                <p>
                    <label class="eb_setup_h2">{{{namelabel}}}</label>
                    <i class="fa-solid fa-info eb-tooltip es-info-icon">
                        <span class='eb-tooltiptext'>{{{wpsitenametip}}}</span>
                    </i>
                </p>
                <input class="eb_setup_inp eb_setup_site_name" id="eb_setup_site_name" name="eb_setup_site_name" type="text" value="{{selectedname}}">
            </div>
            <div class="eb_setup_wp_site_details_inp eb_setup_conn_url_inp_wrap {{class}}">
                <p>
                    <label class="eb_setup_h2">{{{urllabel}}}</label>
                    <i class="fa-solid fa-info eb-tooltip es-info-icon">
                        <span class='eb-tooltiptext'>{{{wpsiteurltip}}}</span>
                    </i>
                </p>
                <input class="eb_setup_inp eb_setup_site_url" id="eb_setup_site_url" name="eb_setup_site_url" type="text" value="{{selectedurl}}">
            </div>
            <div class="eb_setup_btn_wrap">
                <a class="eb_setup_sec_btn" href="{{prevurl}}">{{{back}}}</a>
                <button class="eb_setup_btn eb_setup_wp_details_btn eb_setup_save_and_continue {{btnclass}}" data-step="{{step}}" data-next-step="{{nextstep}}" data-is-next-sub-step="{{isnextsubstep}}">
                    {{{setupcontinuebtn}}}
                </button>
            </div>
        </div>
    </div>
</div>

================
File: auth.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Authentication plugin for Edwiser Bridge.
 * This plugin allows users to login to Moodle using their WordPress credentials.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
use core\context\system as context_system;
/**
 * Plugin for no authentication.
 */
class auth_plugin_edwiserbridge extends auth_plugin_base {
⋮----
/**
     * Initializes the Edwiser Bridge authentication plugin.
     *
     * This constructor sets the authentication type to 'edwiserbridge' and loads the
     * plugin configuration from the 'auth_edwiserbridge' settings.
     */
public function __construct() {
⋮----
/**
     * Old syntax of class constructor. Deprecated in PHP7.
     *
     * This method is a deprecated constructor for the `auth_plugin_edwiserbridge` class.
     * It calls the modern constructor `__construct()` and outputs a debugging message
     * indicating that the old constructor syntax is deprecated.
     *
     * @deprecated since Moodle 3.1
     */
public function auth_plugin_wdmwpmoodle() {
⋮----
self::__construct();
⋮----
/**
     * Attempts to authenticate the user with the given username and password.
     *
     * This method checks if the provided username and password are valid for
     * authenticating the user. It returns true if the authentication is successful,
     * and false otherwise. Returns true if the username and password work or don't exist and false
     * if the user exists and the password is wrong.
     *
     * @param string $username The username to authenticate.
     * @param string $password The password to authenticate.
     * @return bool True if the authentication is successful, false otherwise.
     */
public function user_login($username, $password = null) {
⋮----
$user = $DB->get_record(
⋮----
/**
     * Indicates that local passwords are not prevented.
     *
     * This method returns false, which means that local passwords are not prevented
     * by this authentication plugin. This is likely an implementation detail of the
     * plugin, rather than an exported API.
     *
     * @return bool Always returns false.
     */
public function prevent_local_passwords() {
⋮----
/**
     * Returns true if this authentication plugin is 'internal'.
     *
     * This method indicates whether the authentication plugin is considered an
     * "internal" plugin, meaning it is part of the core Moodle authentication
     * system. This is likely an implementation detail of the plugin, rather than
     * an exported API.
     *
     * @return bool Always returns false, indicating this plugin is not internal.
     */
public function is_internal() {
⋮----
/**
     * Returns true if this authentication plugin can change the user's password.
     *
     * This method indicates whether the authentication plugin supports changing the
     * user's password. In this case, it returns false, indicating that the plugin
     * does not support changing the user's password.
     *
     * @return bool Always returns false.
     */
public function can_change_password() {
⋮----
/**
     * Returns the URL for changing the user's password, or an empty string if the default
     * password change mechanism can be used.
     *
     * This method is an implementation detail of the authentication plugin, rather than
     * an exported API. It indicates whether the plugin provides a custom password change
     * mechanism, or if the default Moodle password change functionality can be used.
     *
     * @return void
     */
public function change_password_url() {
⋮----
/**
     * Returns true if plugin allows resetting of internal password.
     *
     * This method indicates whether the authentication plugin supports resetting the
     * user's password. In this case, it returns false, indicating that the plugin
     * does not support resetting the user's password.
     *
     * @return bool Always returns false.
     */
public function can_reset_password() {
⋮----
/**
     * Sends a cURL request to the WordPress site.
     *
     * This method uses Moodle's cURL class to send a POST request to the WordPress site's
     * Edwiser Bridge SSO endpoint. It sets the necessary headers and options for the
     * cURL request, and returns the response.
     *
     * @param array $requestdata The data to be sent in the POST request.
     * @return string The response from the WordPress site.
     */
public function eb_send_curl_request($requestdata) {
⋮----
// Use Moodle's curl class
include_once($CFG->libdir . '/filelib.php'); // Ensure Moodle's curl class is available.
⋮----
$curl = new \curl();
⋮----
// Set user agent header
⋮----
$curl->setHeader('User-Agent: ' . $useragent);
⋮----
// Set additional options
⋮----
// Execute POST request
$response = $curl->post($requesturl, $requestdata, $options);
⋮----
/**
     * Handles user authentication for the Edwiser Bridge plugin.
     *
     * This method is called when a user is authenticated in the Moodle system. It performs
     * various checks to ensure the user is allowed to log in, such as checking if the user
     * is a guest, if the shared secret is empty, or if the WordPress site URL is not valid.
     * If all checks pass, it sends a cURL request to the WordPress site to log the user in.
     *
     * @param object $user The Moodle user object.
     * @param string $username The username of the authenticated user.
     * @param string $password The password of the authenticated user.
     * @return bool True if the user is authenticated, false otherwise.
     */
public function user_authenticated_hook(&$user, $username, $password) {
⋮----
// Guest user.
⋮----
// Secret key is empty.
⋮----
// WP URL is not a valid URL.
⋮----
// All conditions are passed.
⋮----
$encryptedargs = self::wdm_get_encrypted_query_args($args, $this->config->sharedsecret);
⋮----
// Send curl to wp site with data.
$this->eb_send_curl_request(['wdmargs' => $encryptedargs]);
⋮----
/**
     * Redirects the user to a specific page after logout, and also logs the user out from the WordPress site.
     *
     * This method is called when the user logs out from the Moodle site. It checks if the shared secret and the WordPress site URL are valid, and then constructs a URL to log the user out from the WordPress site. The method also sets the redirect URL for the user after logout.
     */
public function logoutpage_hook() {
⋮----
// Redirect URL is a valid URL.
⋮----
// WP Site URL is not a valid URL.
⋮----
/**
     * Encrypts the given query arguments using AES-128-CTR encryption.
     *
     * @param array $args The query arguments to be encrypted.
     * @param string $key The shared secret key used for encryption.
     * @return string The encrypted query arguments.
     */
public static function wdm_get_encrypted_query_args($args, $key) {
⋮----
$encmethod = 'AES-256-ECB'; // Changed to AES-256-ECB
⋮----
// Ensure the key is hashed to 256 bits (32 bytes) using SHA-256
⋮----
$crypttext = openssl_encrypt($token, $encmethod, $enckey, 0); // No IV needed for ECB mode
⋮----
// Base64 encode the encrypted token
⋮----
// Convert to URL-safe Base64 (replace + with -, / with _, and remove = padding)
⋮----
// Trim any unwanted spaces or characters
⋮----
/**
     * Return a list of identity providers to display on the login page.
     *
     * @param string|moodle_url $wantsurl The requested URL.
     * @return array List of arrays with keys url, iconurl and name.
     */
public function loginpage_idp_list($wantsurl) {
⋮----
$encryptedargs = self::wdm_get_encrypted_query_args($args, $this->config->sharedsecret );
⋮----
$iconurl = moodle_url::make_pluginfile_url(
context_system::instance()->id,
⋮----
// Load default icon from pix folder.

================
File: changes.txt
================
Version 1.0.0
* Plugin Launched

Version 1.4.0
Feature
* Enrolling users in Moodle Course will automatically enroll user in the WordPress course.
* Un-Enrolling users from course Moodle un-enroll user from the course on WordPress site.
* Creating user in Moodle will create same user with basic information like first name, last name and email on WordPress site.
* Deleting user in Moodle will delete same user on WordPress site.

Version 1.4.2
Tweak
* Added compatibility with Edwiser Bridge WordPress plugin.

Version 1.4.3
Feature
* Added functionality to show set-up wizard on Moodle plugin installation to create web service automatically with authorized user.
* Added functionality to add missing functions on linking the existing web-service.
* Added functionality to show all non added Moodle web service functions on test connection functionality.
 
Version 1.4.5
Feature
* Functionality to configure all required Moodle settings for Edwiser Bridge on Edwiser Bridge settings page itself.
* Settings and connection summary page will be shown on the Moodle.

Version 2.0.0
Tweak
* Added compatibility to WordPress plugin Edwiser Bridge 2.0.0

Version 2.1.2
Tweak
* Made plugin compatible with the Moodle Coding standards.

Version 2.1.3
Feature
* Added functionality to update password through user preference option.

Version 2.1.5
Feature
* Added functionality to enable Manual Enrollment method for course when it is disabled.

Version 2.1.9
Feature
* Added setup wizard functionality.
* Added setup wizard reueun link in plugins -> Edwiser Bridge section.  

Version 2.2.0
Feature
* Added webservice to check and enable mandatory settings for test enrollment.

Version 3.0.0
New
* New consolidated edwiser bridge pro plugin.

Version 3.0.5
Tweak
* Moodle Auto Plugin update functionality setting.

Version 3.0.7
Tweak
* Moodle coding standard update.

Version 3.0.8
Tweak
* Made plugin compatible with Moodle 4.5

Version 3.1.0
Fix
* Fixed Security issue with SSO login key encryption.

Version 4.0.0
Feature
* Refactored for compatibility with Moodle standards and new APIs. The plugin is now available on moodle.org.

Version 4.0.1
Fix
* Fixed an issue where we resolved backward compatibility in older moodle versions.

================
File: edwiserbridge.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Edwiser Bridge plugin settings page.
 * Functionality to manage and display settings page.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
use auth_edwiserbridge\settings\navigation_form as navigation_form;
use core\context\system as context_system;
⋮----
$PAGE->requires->jquery();
$PAGE->requires->jquery_plugin('ui');
$PAGE->requires->jquery_plugin('ui-css');
⋮----
// Restrict normal user to access this page.
⋮----
$strings = $stringmanager->load_component_strings('auth_edwiserbridge', 'en');
$PAGE->requires->strings_for_js(array_keys($strings), 'auth_edwiserbridge');
⋮----
// Require Login.
⋮----
$context = context_system::instance();
⋮----
/*
* Creating array of the objects which will be created.
*/
⋮----
/*
 * Necessary page requirements.
 */
$PAGE->set_pagelayout('admin');
⋮----
$PAGE->set_context($context);
$PAGE->set_url('/auth/edwiserbridge/edwiserbridge.php?tab=settings');
⋮----
$PAGE->set_title(get_string('eb-setting-page-title', 'auth_edwiserbridge'));
$PAGE->requires->css('/auth/edwiserbridge/styles/style.css');
$PAGE->requires->js_call_amd("auth_edwiserbridge/edwiser_bridge", "init");
⋮----
echo $OUTPUT->header();
echo $OUTPUT->container_start();
⋮----
/*
 * Navigation form
 */
$mformnavigation->display();
⋮----
/*
* Functionality to display tab wise forms
*/
⋮----
// initialize class based on key.
⋮----
$object = new auth_edwiserbridge\settings\service_form($pageurl . $key, null, 'post', '', ["id" => $mformdata['id']], true, null);
⋮----
$object = new auth_edwiserbridge\settings\connection_form($pageurl . $key, null, 'post', '', ["id" => $mformdata['id']], true, null);
⋮----
$object = new auth_edwiserbridge\settings\synchronization_form($pageurl . $key, null, 'post', '', ["id" => $mformdata['id']], true, null);
⋮----
$object = new auth_edwiserbridge\settings\settings_form($pageurl . $key, null, 'post', '', ["id" => $mformdata['id']], true, null);
⋮----
$object = new auth_edwiserbridge\settings\summary_form($pageurl . $key, null, 'post', '', ["id" => $mformdata['id']], true, null);
⋮----
$object = new auth_edwiserbridge\settings\sso_form($pageurl . $key, null, 'post', '', ["id" => $mformdata['id']], true, null);
⋮----
'context' => context_system::instance(),
⋮----
context_system::instance(),
⋮----
0 // 0 is the item id.
⋮----
if ($formdata = $object->get_data()) {
// In this case you process validated data. $mform->get_data() returns data posted in form.
⋮----
// Calling the save function for each tabn if present.
⋮----
$functionname($formdata, $object);
⋮----
// Save filename in database.
⋮----
$file = $fs->get_area_files(
context_system::instance()->id,
⋮----
if (!$f->is_directory()) {
$filename = $f->get_filename();
⋮----
// Display connection form  for the first time.
⋮----
$object->set_data($data);
⋮----
$object->display();
⋮----
echo $OUTPUT->container_end();
echo $OUTPUT->footer();

================
File: install_update.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Plugin update installation.
 * Functionality to manage plugin update installation.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
use core\update\remote_info;
use moodle_url;
use core\context\system as context_system;
use core\exception\moodle_exception as moodle_exception;
⋮----
$installupdate = required_param('installupdate', PARAM_COMPONENT); // Install given available update.
⋮----
$syscontext = context_system::instance();
⋮----
$PAGE->set_url($pageurl);
$PAGE->set_context($syscontext);
⋮----
$edwiserpluginupdate = new auth_edwiserbridge\local\update(!$download && !$confirminstallupdate);
$plugin = $edwiserpluginupdate->get_plugin_update($params);
⋮----
$output = $PAGE->get_renderer('core', 'admin');
echo $output->header();
⋮----
echo $output->footer();
⋮----
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
⋮----
$edwiserpluginupdate->upgrade_install_plugin(

================
File: lib.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Plugin lib file
 * All the general functions used by the plugin are defined here.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
// use core\plugin_manager as core_plugin_manager;
use core\exception\moodle_exception as moodle_exception;
⋮----
/**
 * Checks if the older Edwiser Bridge plugin is installed.
 *
 * @return bool true if the older Edwiser Bridge plugin is not installed, false if it is installed.
 */
function auth_edwiserbridge_check_pro_dependancy() {
⋮----
$pluginman   = core_plugin_manager::instance();
$localplugin = $pluginman->get_plugins_of_type('local');
⋮----
$authplugin = $pluginman->get_plugins_of_type('auth');
⋮----
// Dependancy check for older edwiser bridge plugin.
⋮----
// Abort installation. and redirect to plugin overview page.
⋮----
// Uninstall plugin.
$pluginmanager = core_plugin_manager::instance();
⋮----
$pluginmanager->cancel_plugin_installation('auth_edwiserbridge');
⋮----
$pluginmanager::reset_caches();
⋮----
/**
 * Saves the connection form settings for the Edwiser Bridge plugin.
 *
 * @param object $formdata The form data containing the connection settings.
 * @param bool $mform Whether the form is being saved from a Moodle form.
 */
function auth_edwiserbridge_save_connection_form_settings($formdata, $mform = false) {
// Checking if provided data count is correct or not.
⋮----
/**
 * Saves the synchronization settings for the individual site.
 *
 * @param object $formdata The form data containing the synchronization settings.
 * @param bool $mform Whether the form is being saved from a Moodle form.
 */
function auth_edwiserbridge_save_synchronization_form_settings($formdata, $mform = false) {
⋮----
/**
 * Saves the SSO settings for the individual site.
 *
 * @param object $formdata The form data containing the SSO settings.
 * @param bool $mform Whether the form is being saved from a Moodle form.
 */
function auth_edwiserbridge_save_sso_form_settings($formdata, $mform = false) {
⋮----
/**
 * Saves the general settings for Moodle.
 *
 * @param object $formdata The form data containing the general settings.
 * @param bool $mform Whether the form is being saved from a Moodle form.
 */
function auth_edwiserbridge_save_settings_form_settings($formdata, $mform = false) {
⋮----
/**
 * Retrieves the required settings for the Edwiser Bridge plugin from the Moodle configuration.
 *
 * This function retrieves the values of various Moodle settings that are required for the Edwiser Bridge plugin to function properly.
 * The settings include the status of the web services, whether extended username characters are enabled, the password policy, and whether automatic update checks are enabled.
 *
 * @return array An associative array containing the required settings.
 */
function auth_edwiserbridge_get_required_settings() {
⋮----
/**
 * Returns connection settings saved in the settings form.
 *
 * This function retrieves the connection settings for the Edwiser Bridge plugin that have been saved in the Moodle configuration.
 * The settings are stored in the $CFG->eb_connection_settings variable, which is decodes and returned as an associative array.
 *
 * @return array An associative array containing the connection settings, or false if the settings are not found.
 */
function auth_edwiserbridge_get_connection_settings() {
⋮----
/**
 * Returns the synchronization settings for the given index.
 *
 * This function retrieves the synchronization settings for the Edwiser Bridge plugin based on the provided index.
 * The settings are stored in the $CFG->eb_synch_settings variable, which is decoded and returned as an associative array.
 * If the settings are not found, a default array is returned.
 *
 * @param int $index The index of the synchronization settings to retrieve.
 * @return array The synchronization settings for the given index, or a default array if the settings are not found.
 */
function auth_edwiserbridge_get_synch_settings($index) {
⋮----
/**
 * Returns a list of all the sites created in the Edwiser settings.
 *
 * This function retrieves the list of sites that have been configured in the Edwiser Bridge plugin settings. It checks if the
 * $CFG->eb_connection_settings variable is set and decodes it to get the site information. If the variable is not set or
 * empty, it returns a single-element array with a default message.
 *
 * @return array An associative array of site keys and names, or a single-element array with a default message if no sites are found.
 */
function auth_edwiserbridge_get_site_list() {
⋮----
/**
 * Returns the main instance of EDW to prevent the need to use globals.
 *
 * @since  1.0.0
 *
 * @return \auth_edwiserbridge\local\api_handler The main instance of the EDW API handler.
 */
function auth_edwiserbridge_api_handler_instance() {
return auth_edwiserbridge\local\api_handler::instance();
⋮----
/**
 * Returns an array of course IDs that the specified user is enrolled in.
 *
 * @param int $userid The ID of the user to get the enrolled courses for.
 * @return array An array of course IDs that the user is enrolled in.
 */
function auth_edwiserbridge_get_array_of_enrolled_courses($userid) {
⋮----
/**
 * Removes a specific course ID from the provided array of course IDs. 
 * Removes processed coureses from the course whose progress is already provided.
 *
 * @param int   $courseid The ID of the course to remove from the array.
 * @param array $courses  The array of course IDs to remove the specified course from.
 * @return array The updated array of course IDs with the specified course removed.
 */
function auth_edwiserbridge_remove_processed_coures($courseid, $courses) {
⋮----
/**
 * Checks if the current request is from WordPress and stops processing the enrollment and unenrollment.
 *
 * This function checks if the current request contains the 'enrolments' or 'cohort' POST parameters,
 * which are used for enrollment and unenrollment processing. If either of these parameters is present,
 * the function returns 1 to indicate that the request is from WordPress and the processing should be stopped.
 *
 * @return int 1 if the request is from WordPress, 0 otherwise.
 */
function auth_edwiserbridge_check_if_request_is_from_wp() {
⋮----
// Using this condition because param enrollments and cohort are multi dimensional array
// and it is not working with optional_param or optional_param_array.
⋮----
// check the wsfunction param to check if the request is from WordPress (for user deletion). as there are no other unique params to check.
⋮----
/*
-----------------------------------------------------------
*   Functions used in Settings page
*----------------------------------------------------------*/
⋮----
/**
 * Retrieves a list of Moodle site administrators and their email addresses.
 *
 * This function fetches the list of Moodle site administrators using the `get_admins()` function,
 * and then creates an associative array where the keys are the administrator IDs and the values
 * are their email addresses. An empty string key is also included with the value of a localized
 * string for the "new service user" label.
 *
 * @return array An associative array of administrator IDs and their email addresses.
 */
function auth_edwiserbridge_get_administrators() {
⋮----
/**
 * Retrieves a list of available Moodle site services.
 *
 * This function fetches the list of external services from the Moodle database and
 * creates an associative array where the keys are the service IDs and the values
 * are the service names. It also includes a special entry with an empty key and
 * the value of a localized string for the "existing service" label, as well as
 * a "create" entry for creating a new service.
 *
 * @return array An associative array of available Moodle site services.
 */
function auth_edwiserbridge_get_existing_services() {
⋮----
// No method to fetch all the enabled webservices in the Moodle Webservice class so fetching directly from DB.
$services = $DB->get_records('external_services', ['enabled' => 1], 'id ASC', 'id,name');
⋮----
// Maintain original return format
⋮----
/**
 * Gets the list of service tokens for the given service ID. 
 *
 * This function fetches the list of external tokens from the Moodle database and
 * creates an associative array where the keys are the token values and the values
 * are the associated external service IDs.
 *
 * @param int $serviceid The ID of the external service.
 * @return array An array of tokens and their associated service IDs.
 */
function auth_edwiserbridge_get_service_tokens($serviceid) {
⋮----
// No method to fetch all the tokens in the Moodle's webservice class so fetching directly from DB.
// To be replaced in the future if available.
$result      = $DB->get_records('external_tokens', null, '', 'token, externalserviceid');
⋮----
/**
 * Generates an HTML field for creating a token.
 *
 * This function generates an HTML field that allows the user to create a token
 * for the specified external service. It retrieves the list of existing tokens
 * for the service and populates the field with the options. The function also
 * provides a "Copy" button to allow the user to easily copy the selected token.
 *
 * @param int $serviceid The ID of the external service.
 * @param string $existingtoken The existing token, if any.
 * @return string The HTML content for the token creation field.
 */
function auth_edwiserbridge_create_token_field($serviceid, $existingtoken = '') {
⋮----
$output = $PAGE->get_renderer('core');
$html = $output->render_from_template('auth_edwiserbridge/create_token_field', $data);
⋮----
/**
 * Gets the list of service tokens for the given service ID. 
 * Functionality to get count of not available services which are required for Edwiser-Bridge.
 *
 * @param int $serviceid The ID of the external service.
 * @return array An array of service tokens, with the token and ID for each.
 */
function auth_edwiserbridge_get_service_list($serviceid) {
$webservicemanager = new \webservice();
$service = $webservicemanager->get_external_service_by_id($serviceid);
⋮----
$license = new \auth_edwiserbridge\local\eb_pro_license_controller();
⋮----
if ($license->get_data_from_db() == 'available') {
⋮----
if (!$webservicemanager->service_function_exists($function, $serviceid)) {
⋮----
/**
 * Checks the status of various Edwiser Bridge settings and returns a summary status.
 *
 * This function checks the values of various Edwiser Bridge settings, such as
 * 'enablewebservices', 'passwordpolicy', 'extendedusernamechars', and
 * 'webserviceprotocols'. It also checks for the existence of certain configuration
 * variables, such as 'ebexistingserviceselect' and 'edwiser_bridge_last_created_token'.
 * Based on the results of these checks, the function returns one of three possible
 * status values: 'error', 'warning', or 'success'.
 *
 * @return string The summary status of the Edwiser Bridge settings.
 */
function auth_edwiserbridge_get_summary_status() {
⋮----
/**
 * Serves the files from the auth_edwiserbridge file areas.
 *
 * This function is responsible for serving files from the auth_edwiserbridge plugin's file areas.
 * It checks the context level, retrieves the file based on the provided arguments, and sends the
 * stored file to the client, forcing the download.
 *
 * @param stdClass $course the course object
 * @param stdClass $cm the course module object
 * @param stdClass $context the auth_edwiserbridge's context
 * @param string   $filearea the name of the file area
 * @param array    $args extra arguments (itemid, path)
 * @param bool     $forcedownload whether or not force download
 * @param array    $options additional options affecting the file serving
 */
function auth_edwiserbridge_pluginfile(
⋮----
if (! ($file = $fs->get_file_by_hash(sha1($fullpath)))) {
⋮----
// Download MUST be forced - security!
⋮----
/**
 * Checks and updates the web service functions for the auth_edwiserbridge plugin.
 *
 * This function retrieves the connection settings for the Edwiser Bridge plugin,
 * and then checks and updates the web service functions associated with the
 * external service ID. It adds any missing functions to the
 * external_services_functions table.
 */
function auth_edwiserbridge_check_and_update_webservice_functions() {
⋮----
$token = $webservicemanager->get_user_ws_token($connection['wp_token']);
⋮----
// Define required functions
⋮----
if (!$webservicemanager->service_function_exists($functionname, $serviceid)) {
$webservicemanager->add_external_function_to_service($functionname, $serviceid);
⋮----
/**
 * Enables the Edwiser Bridge authentication plugin in the default authentication method.
 *
 * This function checks if the Edwiser Bridge authentication plugin is enabled, and if not, adds it to the list of
 * enabled authentication plugins. It then removes any stale sessions and resets the plugin caches.
 */
function auth_edwiserbridge_enable_plugin() {
⋮----
get_enabled_auth_plugins(true); // Fix the list of enabled auths.
⋮----
\core\session\manager::gc(); // Remove stale sessions.
core_plugin_manager::reset_caches();
⋮----
/**
 * Checks for updates to the Edwiser Bridge plugin and prepares a notification if an update is available.
 *
 * This function retrieves the latest version information for the Edwiser Bridge plugin from a remote server,
 * compares it to the currently installed version, and if an update is available, it prepares a notification
 * to be displayed to the user.
 *
 * The notification includes information about the new version, a changelog URL, and links to download and
 * update the plugin.
 */
function auth_edwiserbridge_check_plugin_update() {
// Construct a user agent string.
⋮----
include_once($CFG->libdir . '/filelib.php'); // Include Moodle's filelib for the `curl` class.
⋮----
// Set up Moodle's curl instance.
$curl = new \curl([
⋮----
$output = $curl->get($url, null, $options);
⋮----
// Check the HTTP response code.
⋮----
$authplugin                   = $pluginman->get_plugins_of_type('auth');
⋮----
// $pluginsdata['edwiserbridge'] = '3.0.0';
⋮----
/**
 * Prepare the plugin update notification.
 *
 * This function is responsible for preparing the plugin update notification
 * that will be displayed to the user when a new version of the Edwiser Bridge
 * plugin is available.
 *
 * @param object $updatedata The update data for the Edwiser Bridge plugin.
 */
function auth_edwiserbridge_prepare_plugin_update_notification($updatedata) {
⋮----
$renderer = $PAGE->get_renderer('core');
⋮----
// Mustache rendering data
⋮----
'changelogurl' => 'https://wordpress.org/plugins/edwiser-bridge/#developers', // Replace with actual changelog URL
⋮----
'updateurl' => 'UPDATE_URL', // Replace with actual update URL
⋮----
'dismissurl' => 'DISMISS_URL', // Replace with actual dismiss URL
⋮----
// Rendering Mustache template with data
$msg = $renderer->render_from_template('auth_edwiserbridge/plugin_update_notification', $templatecontext);
⋮----
// Set configurations
⋮----
/**
 * Shows the plugin update notification if an update is available and the user has not dismissed the notification.
 * This function checks the configuration settings, retrieves the update message and URLs, and adds the notification to the Moodle interface.
 *
 * @return void
 */
function auth_edwiserbridge_show_plugin_update_notification() {
⋮----
// To resolve duplicate notification issue.
⋮----
$updatemsg = str_replace('UPDATE_URL', $updateurl->out(), $updatemsg);
⋮----
$updatemsg = str_replace('DISMISS_URL', $dismissurl->out(), $updatemsg);
⋮----
// Add notification.
\core\notification::add($updatemsg, \core\output\notification::NOTIFY_INFO);
⋮----
/**
 * Get the shared secret key for SSO authentication.
 * If the secret key is not set, redirect the user to the WordPress site with an error parameter.
 *
 * @return string The shared secret key, or an empty string if the key is not set and the user is redirected.
 */
function auth_edwiserbridge_get_sso_secret_key() {
⋮----
/**
 * Decrypts a base64-encoded string using the provided key.
 *
 * This function is used to decrypt incoming data that has been specially encoded in base64 format, where the
 * encoded data contains a string of key=value pairs.
 *
 * @param string $base64 The base64-encoded string to decrypt.
 * @param string $key The key to use for decryption.
 * @return string The decrypted string, or an empty string if the input is invalid.
 */
function auth_edwiserbridge_decrypt_string($base64, $key) {
⋮----
$data = str_replace(['-', '_'], ['+', '/'], $base64); // Convert URL-safe Base64 back to standard Base64
⋮----
// Base64 length must be evenly divisible by 4, so we pad if necessary
⋮----
// Decode the Base64 data
⋮----
// AES-256-ECB does not use an IV, so we don't need to split the data
// Directly decrypt the data
$encmethod = 'AES-256-ECB'; // Use AES-256-ECB encryption method
$enckey = openssl_digest( $key, 'SHA256', true); // Hash the key to 256 bits using SHA-256
// Decrypt the token with AES-256-ECB (no IV required)
⋮----
// Return the decrypted value, trimmed of any extra spaces or characters
⋮----
/**
 * Query string helper, returns the value of a key in a string formatted in key=value&key=value&key=value pairs,
 * e.g. saved querystrings.
 *
 * @param string $string The string containing the key-value pairs.
 * @param string $key The key to search for in the string.
 * @return string The value of the specified key, or an empty string if the key is not found.
 * @package auth_edwiserbridge
 */
function auth_edwiserbridge_get_key_value($string, $key) {
⋮----
// Not for use in $_GET etc, which is already decoded,
// however our encoder uses http_build_query() before encrypting.
⋮----
/**
 * Get user session data.
 *
 * @param int $userid user id.
 * @param string $sessionkey session key.
 * @return object session data.
 * @package auth_edwiserbridge
 */
function auth_edwiserbridge_get_user_session($userid, $sessionkey) {
⋮----
/**
 * Set user session data.
 *
 * @param int $userid user id.
 * @param string $sessionkey session key.
 * @param string $wdmdata session data.
 * @package auth_edwiserbridge
 */
function auth_edwiserbridge_set_user_session($userid, $sessionkey, $wdmdata) {
⋮----
/**
 * Remove user session data.
 *
 * @param int $userid user id.
 * @package auth_edwiserbridge
 */
function auth_edwiserbridge_remove_user_session($userid) {
⋮----
/**
 * Redirect the user to the root URL of the Moodle site.
 *
 * This function is used to redirect the user to the root URL of the Moodle site, which is stored in the $CFG->wwwroot global variable.
 * The current URL that the user wants to access is stored in the $SESSION->wantsurl global variable, and this function uses the redirect() function to redirect the user to the root URL.
 */
function auth_edwiserbridge_redirect_to_root() {

================
File: LICENSE.md
================
GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

================
File: login.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * SSO login script.
 * Functionality to manage SSO login.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
require_once('../../config.php'); // @codingStandardsIgnoreLine
⋮----
// Login may somehow modify this.
⋮----
// Killing session.
⋮----
$userid = auth_edwiserbridge_get_key_value( $userdata, 'moodle_user_id' ); // The users id in the wordpress database.
⋮----
// Get course id from login_redirect.
⋮----
$course = $DB->record_exists('course', ['id' => $courseid]);
// If course is not available then redirect to site home page.
⋮----
if ($DB->record_exists('user', ['id' => $userid])) {
// Update manually created user that has the same username but doesn't yet have the right idnumber
// ensure we have the latest data.
⋮----
// All that's left to do is to authenticate this user and set up their active session.
⋮----
if ($authplugin->user_login($user->username, $user->password)) {
⋮----
complete_user_login($user); // Now performs \core\event\user_loggedin event.

================
File: mod_form.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Settings form.
 * Functionality to manage and display settings form.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
/**
 * Defines the settings form for the Edwiser Bridge plugin.
 *
 * This class extends the Moodle form library to create a settings form for the Edwiser Bridge plugin.
 * The form includes various checkboxes for configuring the plugin's settings, such as the REST protocol,
 * web service, password policy, extended username, and auto-update check.
 *
 * The form also includes submit buttons for saving the settings and continuing to the next step.
 */
class edwiserbridge_settings_form extends moodleform {
⋮----
/**
     * Defines the form definition for the Edwiser Bridge plugin settings form.
     *
     * This method sets up the various form elements, including checkboxes for configuring
     * the plugin's settings, such as the REST protocol, web service, password policy,
     * extended username, and auto-update check. It also adds submit buttons for saving
     * the settings and continuing to the next step.
     */
public function definition() {
⋮----
// 1st field.
$mform->addElement(
⋮----
// 2nd field.
⋮----
// 3rd field.
⋮----
// 4th field.
⋮----
// 5th field.
⋮----
// Fill form with the existing values.
⋮----
$mform->setDefault('rest_protocol', $defaultvalues['rest_protocol']);
$mform->setDefault('web_service', $defaultvalues['web_service']);
$mform->setDefault('pass_policy', $defaultvalues['pass_policy']);
$mform->setDefault('extended_username', $defaultvalues['extended_username']);
$mform->setDefault('enable_auto_update_check', $defaultvalues['enable_auto_update_check']);
⋮----
/**
     * Validates the form data submitted by the user.
     *
     * @param array $data  The submitted form data.
     * @param array $files The submitted files.
     * @return array An array of validation errors, if any.
     */
public function validation($data, $files) {

================
File: README.md
================
Edwiser Bridge local plugin for Moodle
==============================================

# Table of Contents

- [Description](#description)
- [Features](#features)
- [Plugin Version](#plugin-version)
- [Required version of Moodle](#required-version-of-moodle)
- [Free Software](#free-software)
- [Support](#support)
- [Installation](#installation)
- [Uninstallation](#uninstallation)
- [Files Information](#files-information)
- [Roadmap](#roadmap)
- [History](#history)
- [Author](#author)
- [Provided by](#provided-by)

# Description

Edwiser Bridge - The #1 WordPress and Moodle Integration plugin that provides a robust platform to sell Moodle courses online.

Are you a Moodle user, who creates courses and wants a robust integration with WordPress/WooCommerce to sell them.
Then you are in the right place. Edwiser Bridge is the only WordPress plugin that provides stable and robust integration between the two platforms.

Edwiser Bridge provides the necessary platform for you to sell your Moodle courses through the default payment gateway, PayPal.

So to enhance its functionality and achieve a fully automated WooCommerce Solution for the purpose of selling your Moodle courses, you may consider choosing Edwiser Bridge Pro to be installed on both your Moodle and WordPress sites.

1. <a href="https://wordpress.org/plugins/edwiser-bridge/"> Edwiser Bridge - WordPress Add On </a>
2. <a href="https://edwiser.org/plugins/edwiserbridge.zip"> Edwiser Bridge - Moodle Add On </a>

1. <a href="https://edwiser.org/bridge/?utm_source=moodle&utm_medium=landingpage&utm_campaign=EBFreePlugin"> Edwiser Bridge Pro </a>

Please note: Edwiser Bridge WordPress plugin (https://downloads.wordpress.org/plugin/edwiser-bridge.zip) is mandatory for the setup and has to be installed on your WordPress site for WordPress - Moodle integration.
Refer to this documentation for setup: https://edwiser.org/documentation/edwiser-bridge/

[(Back to top)](#table-of-contents)

# Features

= CourseFront - =
* Integration between your WordPress and Moodle sites,
* Connect Moodle with multiple WordPress sites,
* Courses from single Moodle site could be sold through multiple WordPress sites.
* Import your Moodle courses to WordPress,
* Synchronize Moodle course categories to WordPress,
* Set the Moodle courses as drafts,
* Sell courses through WordPress and take payments through PayPal,
* Synchronize enrolled course data for users.
* Synchronize Moodle course images with WordPress.
* Automated 2-way synchronization between each WordPress site and your Moodle site,
* The course progress of student is synced from Moodle to WordPress in real time.

= Course Access Control - =
* Automation user registration in Moodle,
* Enable/Disable registration for courses,
* Identical login credentials to access courses in Moodle,
* Set course access time from WordPress,
* Update previously synchronized courses,
* Enroll / Unenrol users from WordPress,
* Provide refunds to your students from WordPress.

= Connect your Moodle with Multiple WordPress Sites - =
* Now connect single Moodle site with multiple WordPress sites,
* Courses from single Moodle site could be sold through multiple WordPress sites,
* Automated 2-way synchronization between each WordPress site and your Moodle site,
* Secured and efficient transfer of information across sites,
* The course progress of student is synced from Moodle to WordPress in real time.

[(Back to top)](#table-of-contents)

# Plugin Version

v3.0.0 - Plugin Released

[(Back to top)](#table-of-contents)

# Required version of Moodle

This version works with Moodle 3.11 version and above until the next release.

Please ensure that your hardware and software complies with 'Requirements' in 'Installing Moodle' on
'https://docs.moodle.org/39/en/Step-by-step_Installation_Guide_for_Ubuntu'.

[(Back to top)](#table-of-contents)

# Free Software

The Edwiser Bridge is 'free' software under the terms of the GNU GPLv3 License, please see 'LICENSE.md'.

The primary source is on https://github.com/WisdmLabs/edwiser-bridge

You have all the rights granted to you by the GPLv3 license.  If you are unsure about anything, then the
FAQ - http://www.gnu.org/licenses/gpl-faq.html - is a good place to look.

[(Back to top)](#table-of-contents)

# Support

For all support queries related to Edwiser Bridge plugin you could email us at edwiser@wisdmlabs.com
Apart from that you could raise your support queries in this forum too - https://forums.edwiser.org/category/27/edwiser-bridge

And if you wish to see any new features as part of the product then you could share your feature requests here
forum https://forums.edwiser.org/category/27/edwiser-bridge for support.
Together we could make this solution better for your Moodle.

[(Back to top)](#table-of-contents)

# Installation

 = Minimum Requirements =
* PHP version 5.6 or greater
* WordPress 5.9 or higher
* Moodle 3.11 or higher

 = Moodle Plugin Automatic Installation =
* Download the Moodle edwiserbridge plugin from <a href = "https://edwiser.org/plugins/edwiserbridge.zip">here</a>.
* Go to the Plugins menu in Moodle.
* Click on Install plugins.
* Upload plugins zip file.
* Then click on Install plugin from the Zip file.

 = Moodle Plugin Manual Installation  =
* Download the Moodle edwiserbridge plugin from <a href = "https://edwiser.org/plugins/edwiserbridge.zip">here</a>.
* Now unzip and upload the folder in local directory of Moodle using the FTP application of your choice.
* The plugin can then be activated by navigating to the Plugins menu in the dashboard.

 = Wordpress plugin Automatic Installation  =
* Go to the Plugins menu from the dashboard.
* Click on the 'Add New' button on this page.
* Search for 'Edwiser Bridge' in the search bar provided.
* Click on 'Install Now' once you have located the plugin.
* On successful installation, click the 'Activate Plugin' link to activate the plugin.

 = Wordpress Plugin Manual Installation  =
* Download the Edwiser Bridge plugin from WordPress.org.
* Now unzip and upload the folder using the FTP application of your choice.
* The plugin can then be activated by navigating to the Plugins menu in the admin dashboard.

 = Edwiser Bridge PRO License Key =
* To activate the Edwiser Bridge PRO functionality, you need to enter the license key.
* Go to the Site Administration > Plugins > Edwise Bridge > Settings > Summary.
* Enter the license key in the License Key field and click on the 'Activate License' button.
* License key can be obtained from <a href = "https://edwiser.org/my-account/"> Edwiser My Account </a> page.
* You can now access the PRO features of the plugin.

 = Moodle Configuration =
Take a look at the link below and follow the steps provided to configure your Moodle website.
<a href = "https://edwiser.org/documentation/edwiser-bridge/">Moodle Website Configurations</a>

[(Back to top)](#table-of-contents)

# Uninstallation

1. Go to Site administration > Plugins > Plugin overview and go to Edwiser Bridge section, click on uninstall link for 'Edwiser Bridge'.
2. In '/auth/' remove the folder 'edwiserbridge'.

[(Back to top)](#table-of-contents)

# Files Information
Languages
---------
The edwiserbridge/lang folder contains the language files for the format.

Note that existing formats store their language strings in the main
moodle.php, which you can also do, but this separate file is recommended
for contributed formats.

Of course you can have other folders as well as English etc. if you want to
provide multiple languages.

Styles
------
The file edwiserbridge/styles.css contains the CSS styles for the format.

[(Back to top)](#table-of-contents)

# Roadmap

1. Global Course Announcement Feature.

[(Back to top)](#table-of-contents)

# History
See changes.txt

[(Back to top)](#table-of-contents)

# Author

Wisdmlabs

[(Back to top)](#table-of-contents)

# Provided by

[![alt text](https://raw.githubusercontent.com/WisdmLabs/moodle-local_edwiserbridge/master/images/readme-img.png)](https://edwiser.org)

[(Back to top)](#table-of-contents)

================
File: settings.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Settings page for Edwiser Bridge plugin.
 * Plugin administration pages are defined here.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
// Plugin update notification.
⋮----
$PAGE->requires->js_call_amd('auth_edwiserbridge/settings', 'init');
$PAGE->requires->js_call_amd('auth_edwiserbridge/sso_settings', 'init');
⋮----
$strings = $stringmanager->load_component_strings('auth_edwiserbridge', 'en');
$PAGE->requires->strings_for_js(array_keys($strings), 'auth_edwiserbridge');
⋮----
// Add new cateogry in admin settings.
⋮----
$ADMIN->add(
⋮----
new \lang_string(
⋮----
$settingslink = new \moodle_url('/auth/edwiserbridge/edwiserbridge.php', ['tab' => 'sso']);
$heading = new \lang_string('settings_migration', 'auth_edwiserbridge')
⋮----
$settings->add(new admin_setting_heading('auth_edwiserbridge_settings', '', $heading));
⋮----
$settings->add(
⋮----
// Adding this field so that the setting page will be shown after installation.

================
File: setup_wizard.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Setup wizard for Edwiser Bridge plugin.
 * Functionality to manage amd display setup wizard.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
use core\context\system as context_system;
⋮----
$setupwizard = new auth_edwiserbridge\local\setup_wizard();
⋮----
// Check progress and redirect accordingly.
⋮----
$nextstep = $setupwizard->get_next_step( $progress );
⋮----
// Check if the get parameter have same progress.
⋮----
$PAGE->requires->jquery();
$PAGE->requires->jquery_plugin('ui');
$PAGE->requires->jquery_plugin('ui-css');
⋮----
// Restrict normal user to access this page.
⋮----
$strings = $stringmanager->load_component_strings('auth_edwiserbridge', 'en');
$PAGE->requires->strings_for_js(array_keys($strings), 'auth_edwiserbridge');
⋮----
// Require Login.
⋮----
$context = context_system::instance();
⋮----
/*
 * Necessary page requirements.
 */
⋮----
$PAGE->set_pagelayout("popup");
⋮----
$PAGE->set_context($context);
$PAGE->set_url('/auth/edwiserbridge/edwiserbridge.php?tab=settings');
⋮----
$PAGE->set_title(get_string('eb-setup-page-title', 'auth_edwiserbridge'));
⋮----
$PAGE->requires->css('/auth/edwiserbridge/styles/style.css');
$PAGE->requires->css('/auth/edwiserbridge/styles/setup-wizard.css');
⋮----
$PAGE->requires->js_call_amd('auth_edwiserbridge/settings', 'init');
⋮----
// Actual page template output starts here.
⋮----
// Output page header.
echo $OUTPUT->header();
⋮----
// Start page container.
echo $OUTPUT->container_start();
⋮----
// This outputs setup wizard template.
// This will use classes/class-setup-wizard.php file.
$setupwizard->eb_setup_wizard_template();
⋮----
// End page container.
echo $OUTPUT->container_end();
⋮----
// Output footer.
echo $OUTPUT->footer();

================
File: styles.css
================
#edwsier-bridge {
⋮----
.eb_toke_detail_tbl {
⋮----
/*************************************/
⋮----
#auth_edwiserbridge_copy {
⋮----
.eb_copy_btn {
⋮----
.eb_copy_text {
⋮----
#eb_create_service {
⋮----
#admin-ebnewserviceinp .form-defaultinfo,
⋮----
.eb_settings_err,
⋮----
#eb_common_success {
⋮----
#admin-ebexistingserviceselect {
⋮----
.eb-plugin-update-notice{
.eb-plugin-update-notice-heading{
.eb-plugin-update-notice-body{
.eb-plugin-update-changelog{
.eb-plugin-update-dismiss{
.eb-plugin-update-dismiss:hover{
.eb-plugin-update-action{
.eb-plugin-update-action span{
.eb-plugin-update-notice p{
⋮----
.alert-dismissible:has(.eb-plugin-update-notice) .close{

================
File: version.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * Version information
 * This version is compatible with WordPress plugin Edwiser Bridge Single Sign On (version 3.0.7 or higher)
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
$plugin->version   = 2025040205;    // The current plugin version (Date: YYYYMMDDXX).
⋮----
$plugin->requires  = 2023100900; // Requires this Moodle version (Moodle V4.3).
⋮----
$plugin->component = 'auth_edwiserbridge'; // Full name of the plugin (used for diagnostics).

================
File: wdmwplogin.php
================
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
⋮----
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
⋮----
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
⋮----
/**
 * SSO login page.
 * This file is responsible for SSO login page.
 *
 * @package    auth_edwiserbridge
 * @copyright  2016 WisdmLabs (https://wisdmlabs.com)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
⋮----
// Requested to wp login.
⋮----
// User is not logged in or is a guest user.
⋮----
// All checks are passed. Redirect to wp site for login.



================================================================
End of Codebase
================================================================
