Bearsampp 2026.3.26
API documentation
Loading...
Searching...
No Matches
QuickPick Class Reference

Public Member Functions

 __construct ()
 checkDownloadId ()
 checkQuickpickJson ()
 fetchAndUnzipModule (string $moduleUrl, string $module)
 getErrorModal (string $errorMessage)
 getModuleDestinationPath (string $moduleType, string $moduleName)
 getModules ()
 getModuleUrl (string $module, string $version)
 getQuickpickJson ()
 getQuickpickMenu (array $modules, array $versions, string $imagesPath)
 getVersions ()
 installModule (string $module, string $version)
 loadQuickpick (string $imagesPath)
 normalizeModuleName (string $moduleName)
 rebuildQuickpickJson ()

Data Fields

 $modules

Private Member Functions

 formatVersionLabel ($version, $isPrerelease=false)
 getLocalFileCreationTime ()
 isValidHeaderResponse ($headers)
 logHeaders (array $headers)
 regenerateMenuSafe ()
 updateModuleConfig (string $module, string $version)

Private Attributes

 $jsonFilePath
 $versions = []

Detailed Description

Class QuickPick

The QuickPick class provides functionalities for managing and installing various modules within the Bearsampp application. It includes methods for retrieving available modules, fetching module versions, parsing release properties, and validating license keys.

Definition at line 18 of file class.action.quickPick.php.

Constructor & Destructor Documentation

◆ __construct()

__construct ( )

Constructor to initialize the jsonFilePath.

Definition at line 69 of file class.action.quickPick.php.

70 {
71 global $bearsamppCore;
72 $this->jsonFilePath = $bearsamppCore->getResourcesPath() . '/quickpick-releases.json';
73 }
global $bearsamppCore

References $bearsamppCore.

Member Function Documentation

◆ checkDownloadId()

checkDownloadId ( )

Validates the format of a given username key by checking it against an external API.

This method performs several checks to ensure the validity of the username key:

  1. Logs the method call.
  2. Ensures the global configuration is available.
  3. Retrieves the username key from the global configuration.
  4. Ensures the username key is not empty.
  5. Constructs the API URL using the username key.
  6. Fetches the API response.
  7. Decodes the JSON response.
  8. Validates the response data.
Returns
bool True if the username key is valid, false otherwise.

Definition at line 372 of file class.action.quickPick.php.

372 : bool
373 {
374 global $bearsamppConfig;
375
376 Util::logDebug( 'checkDownloadId method called.' );
377
378 // Ensure the global config is available
379 if ( !isset( $bearsamppConfig ) ) {
380 Util::logError( 'Global configuration is not set.' );
381
382 return false;
383 }
384
385 $DownloadId = $bearsamppConfig->getDownloadId();
386 Util::logDebug( 'DownloadId is: ' . $DownloadId );
387
388 // Ensure the license key is not empty
389 if ( empty( $DownloadId ) ) {
390 Util::logError( 'License key is empty.' );
391
392 return false;
393 }
394
395 $url = QUICKPICK_API_URL . QUICKPICK_API_KEY . '&download_id=' . $DownloadId;
396 Util::logDebug( 'API URL: ' . $url );
397
398 // Attempt to fetch the API response
399 // Note: If this fails, PHP will generate a warning which will be logged by the error handler
400 // This is expected behavior when the API server is unavailable
401 $response = file_get_contents( $url );
402
403 // Check if the response is false
404 if ( $response === false ) {
405 Util::logError( 'Failed to validate QuickPick license - API server unavailable' );
406 return false;
407 }
408
409 Util::logDebug( 'API response: ' . $response );
410
411 $data = json_decode( $response, true );
412
413 // Check if the JSON decoding was successful
414 if ( json_last_error() !== JSON_ERROR_NONE ) {
415 Util::logError( 'Error decoding JSON response: ' . json_last_error_msg() );
416
417 return false;
418 }
419
420 // Validate the response data
421 if ( isset( $data['success'] ) && $data['success'] === true && isset( $data['data'] ) && is_array( $data['data'] ) && count( $data['data'] ) > 0 ) {
422 Util::logDebug( 'License key valid: ' . $DownloadId );
423
424 return true;
425 }
426
427 Util::logError( 'Invalid license key: ' . $DownloadId );
428
429 return false;
430 }
static logError($data, $file=null)
static logDebug($data, $file=null)
global $bearsamppConfig
Definition homepage.php:41
const QUICKPICK_API_URL
Definition root.php:24
const QUICKPICK_API_KEY
Definition root.php:23

References $bearsamppConfig, $response, Util\logDebug(), Util\logError(), QUICKPICK_API_KEY, and QUICKPICK_API_URL.

Referenced by getQuickpickMenu().

◆ checkQuickpickJson()

checkQuickpickJson ( )

Checks if the local quickpick-releases.json file is up-to-date with the remote version.

Compares the creation time of the local JSON file with the remote file's last modified time. If the remote file is newer or the local file does not exist, it fetches the latest JSON data by calling the rebuildQuickpickJson method.

Returns
array|false Returns the JSON data if the remote file is newer or the local file does not exist, otherwise returns false.
Exceptions
Exception

Definition at line 164 of file class.action.quickPick.php.

165 {
166 global $bearsamppConfig;
167
168 // Determine local file creation time or rebuild if missing
169 $localFileCreationTime = $this->getLocalFileCreationTime();
170
171 // Attempt to retrieve remote file headers
172 $headers = get_headers(QUICKPICK_JSON_URL, 1);
173 if (!$this->isValidHeaderResponse($headers)) {
174 // If headers or Date are invalid, assume no update needed
175 return false;
176 }
177
178 // Optionally log headers for verbose output
179 $this->logHeaders($headers);
180
181 // Compare the creation times (remote vs. local)
182 $remoteFileCreationTime = strtotime(isset($headers['Date']) ? $headers['Date'] : '');
183 if ($remoteFileCreationTime > $localFileCreationTime) { return $this->rebuildQuickpickJson(); }
184
185 // Return false if local file is already up-to-date
186 return false;
187 }
isValidHeaderResponse($headers)
logHeaders(array $headers)
const QUICKPICK_JSON_URL
Definition root.php:27

References $bearsamppConfig, getLocalFileCreationTime(), isValidHeaderResponse(), logHeaders(), QUICKPICK_JSON_URL, and rebuildQuickpickJson().

Referenced by loadQuickpick().

◆ fetchAndUnzipModule()

fetchAndUnzipModule ( string $moduleUrl,
string $module )

Fetches the module URL and stores it in /tmp, then unzips the file based on its extension.

Parameters
string$moduleUrlThe URL of the module to fetch.
string$moduleThe name of the module.
Returns
array An array containing the status and message.

Definition at line 526 of file class.action.quickPick.php.

526 : array
527{
528 Util::logDebug("$module is: " . $module);
529
531 $tmpDir = $bearsamppRoot->getTmpPath();
532 Util::logDebug('Temporary Directory: ' . $tmpDir);
533
534 $fileName = basename($moduleUrl);
535 Util::logDebug('File Name: ' . $fileName);
536
537 $tmpFilePath = $tmpDir . '/' . $fileName;
538 Util::logDebug('File Path: ' . $tmpFilePath);
539
540 $moduleName = str_replace('module-', '', $module);
541 Util::logDebug('Module Name: ' . $moduleName);
542
543 // Find the correct module key by searching through the modules array
544 // This handles proper capitalization for all module types
545 $moduleKey = null;
546 foreach ($this->modules as $key => $moduleInfo) {
547 if (strtolower($key) === strtolower($moduleName)) {
548 $moduleKey = $key;
549 break;
550 }
551 }
552
553 if (!$moduleKey) {
554 Util::logError("Module not found in modules array: $moduleName");
555 return ['error' => 'Module configuration not found'];
556 }
557
558 $moduleType = $this->modules[$moduleKey]['type'];
559 Util::logDebug('Module Type: ' . $moduleType);
560
561 // Get module type
562 $destination = $this->getModuleDestinationPath($moduleType, $moduleName);
563 Util::logDebug('Destination: ' . $destination);
564
565 // Retrieve the file path from the URL using the bearsamppCore module,
566 // passing the module URL and temporary file path, with the use Progress Bar parameter set to true.
567 $result = $bearsamppCore->getFileFromUrl($moduleUrl, $tmpFilePath, true);
568
569 // Check if $result is false
570 if ($result === false) {
571 Util::logError('Failed to retrieve file from URL: ' . $moduleUrl);
572 return ['error' => 'Failed to retrieve file from URL'];
573 }
574
575 // Determine the file extension and call the appropriate unzipping function
576 $fileExtension = pathinfo($tmpFilePath, PATHINFO_EXTENSION);
577 Util::logDebug('File extension: ' . $fileExtension);
578
579 if ($fileExtension === '7z' || $fileExtension === 'zip') {
580 // Send phase indicator for extraction
581 echo json_encode(['phase' => 'extracting']);
582 if (ob_get_length()) {
583 ob_flush();
584 }
585 flush();
586
587 $unzipResult = $bearsamppCore->unzipFile($tmpFilePath, $destination, function ($currentPercentage) {
588 echo json_encode(['progress' => "$currentPercentage%"]);
589 if (ob_get_length()) {
590 ob_flush();
591 }
592 flush();
593 });
594
595 if ($unzipResult === false) {
596 return ['error' => 'Failed to unzip file. File: ' . $tmpFilePath . ' could not be unzipped', 'Destination: ' . $destination];
597 }
598 } else {
599 Util::logError('Unsupported file extension: ' . $fileExtension);
600 return ['error' => 'Unsupported file extension'];
601 }
602
603 return ['success' => 'Module installed successfully'];
604}
$result
global $bearsamppRoot
getModuleDestinationPath(string $moduleType, string $moduleName)

References $bearsamppCore, $bearsamppRoot, $result, getModuleDestinationPath(), Util\logDebug(), and Util\logError().

Referenced by installModule().

◆ formatVersionLabel()

formatVersionLabel ( $version,
$isPrerelease = false )
private

Format version label with PR indicator if it's a prerelease

Parameters
string$versionThe version to format
bool$isPrereleaseWhether this version is a prerelease
Returns
string Formatted version string

Definition at line 82 of file class.action.quickPick.php.

82 {
83 global $bearsamppConfig;
84 $includePr = $bearsamppConfig->getIncludePr();
85
86 if ($isPrerelease && $includePr == 1) {
87 return '<span class="text-danger">' . htmlspecialchars($version) . ' PR</span>';
88 }
89
90 return htmlspecialchars($version);
91 }

References $bearsamppConfig.

◆ getErrorModal()

getErrorModal ( string $errorMessage)

Generates an error modal for configuration validation failures.

Parameters
string$errorMessageThe error message to display.
Returns
string The HTML content of the error modal.

Definition at line 733 of file class.action.quickPick.php.

733 : string
734 {
735 ob_start();
736 ?>
737 <div id="configErrorContainer" class="text-center mt-3 pe-3">
738 <div class="alert alert-danger d-inline-block" role="alert" style="max-width: 500px;">
739 <h4 class="alert-heading">
740 <i class="fas fa-exclamation-circle"></i> Configuration Error
741 </h4>
742 <hr>
743 <p class="mb-0">
744 <?php echo htmlspecialchars($errorMessage); ?>
745 </p>
746 <hr>
747 <small class="text-muted">
748 Please add the missing parameter to the <code>bearsampp.conf</code> file in the Bearsampp root directory.
749 </small>
750 </div>
751 </div>
752 <?php
753 return ob_get_clean();
754 }

Referenced by loadQuickpick().

◆ getLocalFileCreationTime()

getLocalFileCreationTime ( )
private

Returns the local file's creation time, or triggers and returns 0 if file does not exist.

Returns
int Local file's creation time or 0 if the file doesn't exist.

Definition at line 194 of file class.action.quickPick.php.

195 {
196 if (!file_exists($this->jsonFilePath)) {
197 // If local file is missing, rebuild it immediately
198 $this->rebuildQuickpickJson();
199 return 0;
200 }
201 return filectime($this->jsonFilePath);
202 }

References rebuildQuickpickJson().

Referenced by checkQuickpickJson().

◆ getModuleDestinationPath()

getModuleDestinationPath ( string $moduleType,
string $moduleName )

Get the destination path for a given module type and name.

This method constructs the destination path based on the type of module (application, binary, or tools) and the module name. It utilizes the bearsamppRoot global object to retrieve the base paths for each module type.

Parameters
string$moduleTypeThe type of the module ('application', 'binary', or 'tools').
string$moduleNameThe name of the module.
Returns
string The constructed destination path for the module.

Definition at line 618 of file class.action.quickPick.php.

619 {
620 global $bearsamppRoot;
621 if ( $moduleType === 'application' ) {
622 $destination = $bearsamppRoot->getAppsPath() . '/' . strtolower( $moduleName ) . '/';
623 }
624 elseif ( $moduleType === 'binary' ) {
625 $destination = $bearsamppRoot->getBinPath() . '/' . strtolower( $moduleName ) . '/';
626 }
627 elseif ( $moduleType === 'tools' ) {
628 $destination = $bearsamppRoot->getToolsPath() . '/' . strtolower( $moduleName ) . '/';
629 }
630 else {
631 $destination = '';
632 }
633
634 return $destination;
635 }

References $bearsamppRoot.

Referenced by fetchAndUnzipModule().

◆ getModules()

getModules ( )

Retrieves the list of available modules.

Returns
array An array of module names.

Definition at line 121 of file class.action.quickPick.php.

121 : array
122 {
123 return array_keys( $this->modules );
124 }

Referenced by loadQuickpick().

◆ getModuleUrl()

getModuleUrl ( string $module,
string $version )

Fetches the URL of a specified module version from the local quickpick-releases.json file.

This method reads the quickpick-releases.json file to find the URL associated with the given module and version. It logs the process and returns the URL if found, or an error message if not.

Parameters
string$moduleThe name of the module.
string$versionThe version of the module.
Returns
string|array The URL of the specified module version or an error message if the version is not found.

Definition at line 340 of file class.action.quickPick.php.

341 {
342 $this->getVersions();
343 Util::logDebug( 'getModuleUrl called for module: ' . $module . ' version: ' . $version );
344 $url = trim( $this->versions['module-' . strtolower( $module )][$version]['url'] );
345 if ( $url <> '' ) {
346 Util::logDebug( 'Found URL for version: ' . $version . ' URL: ' . $url );
347
348 return $url;
349 }
350 else {
351 Util::logError( 'Version not found: ' . $version );
352
353 return ['error' => 'Version not found'];
354 }
355 }

References getVersions(), Util\logDebug(), and Util\logError().

Referenced by installModule().

◆ getQuickpickJson()

getQuickpickJson ( )

Retrieves the QuickPick JSON data from the local file.

Returns
array The decoded JSON data, or an error message if the file cannot be fetched or decoded.

Definition at line 238 of file class.action.quickPick.php.

238 : array
239 {
240 $content = @file_get_contents( $this->jsonFilePath );
241 if ( $content === false ) {
242 Util::logError( 'Error fetching content from JSON file: ' . $this->jsonFilePath );
243
244 return ['error' => 'Error fetching JSON file'];
245 }
246
247 $data = json_decode( $content, true );
248 if ( json_last_error() !== JSON_ERROR_NONE ) {
249 Util::logError( 'Error decoding JSON content: ' . json_last_error_msg() );
250
251 return ['error' => 'Error decoding JSON content'];
252 }
253
254 return $data;
255 }

References Util\logError().

Referenced by getVersions().

◆ getQuickpickMenu()

getQuickpickMenu ( array $modules,
array $versions,
string $imagesPath )

Generates the HTML content for the QuickPick menu.

This method creates the HTML structure for the QuickPick interface, including a dropdown for selecting modules and their respective versions. It checks if the license key is valid before displaying the modules. If the license key is invalid, it displays a subscription prompt. If there is no internet connection, it displays a message indicating the lack of internet.

Parameters
array$modulesAn array of available modules.
array$versionsAn associative array where the key is the module name and the value is an array containing the module versions.
string$imagesPathThe path to the images directory.
Returns
string The HTML content of the QuickPick menu.

Definition at line 770 of file class.action.quickPick.php.

770 : string
771 {
772 global $bearsamppConfig;
773 $includePr = $bearsamppConfig->getIncludePr();
774 $enhancedMode = $bearsamppConfig->getEnhancedQuickPick();
775
776 ob_start();
777 if ( Util::checkInternetState() ) {
778
779 // Check if the license key is valid
780 if ( $this->checkDownloadId() ): ?>
781 <div id = 'quickPickContainer'>
782 <div class = 'quickpick'>
783
784 <div class = "custom-select">
785 <button class = "select-button" role = "combobox"
786 aria-label = "select button"
787 aria-haspopup = "listbox"
788 aria-expanded = "false"
789 aria-controls = "select-dropdown">
790 <span class = "selected-value">Select a module and version</span>
791 <span class = "arrow"></span>
792 </button>
793 <ul class = "select-dropdown" role = "listbox" id = "select-dropdown">
794
795 <?php
796 foreach ( $modules as $module ): ?>
797 <?php if ( is_string( $module ) ): ?>
798 <li role = "option" class = "moduleheader">
799 <?php echo htmlspecialchars( $module ); ?>
800 </li>
801
802 <?php
803 foreach ( $versions['module-' . strtolower( $module )] as $version_array ):
804 // Skip prerelease versions if includePr is not enabled
805 if (isset($version_array['prerelease']) && $version_array['prerelease'] === true && $includePr != 1) {
806 continue;
807 }
808 ?>
809 <li role = "option" class = "moduleoption"
810 id = "<?php echo htmlspecialchars( $module ); ?>-version-<?php echo htmlspecialchars( $version_array['version'] ); ?>-li">
811 <input type = "radio"
812 id = "<?php echo htmlspecialchars( $module ); ?>-version-<?php echo htmlspecialchars( $version_array['version'] ); ?>"
813 name = "module" data-module = "<?php echo htmlspecialchars( $module ); ?>"
814 data-value = "<?php echo htmlspecialchars( $version_array['version'] ); ?>">
815 <label
816 for = "<?php echo htmlspecialchars( $module ); ?>-version-<?php echo htmlspecialchars( $version_array['version'] ); ?>"><?php echo $this->formatVersionLabel( $version_array['version'], isset($version_array['prerelease']) && $version_array['prerelease'] === true ); ?></label>
817 </li>
818 <?php endforeach; ?>
819 <?php endif; ?>
820 <?php endforeach; ?>
821 </ul>
822 </div>
823 </div>
824 <div class = "progress " id = "progress" tabindex = "-1" style = "width:260px;display:none"
825 aria-labelledby = "progressbar" aria-hidden = "true">
826 <div class = "progress-bar progress-bar-striped progress-bar-animated" id = "progress-bar" role = "progressbar" aria-valuenow = "0" aria-valuemin = "0"
827 aria-valuemax = "100" data-module = "Module"
828 data-version = "0.0.0">0%
829 </div>
830 <div id = "download-module" style = "display: none">ModuleName</div>
831 <div id = "download-version" style = "display: none">Version</div>
832 </div>
833 </div>
834 <?php else: ?>
835 <div id = "subscribeContainer" class = "text-center mt-3 pe-3">
836 <a href = "<?php echo Util::getWebsiteUrl( 'subscribe' ); ?>" class = "btn btn-dark d-inline-flex align-items-center">
837 <img src = "<?php echo $imagesPath . 'subscribe.svg'; ?>" alt = "Subscribe Icon" class = "me-2">
838 Subscribe to QuickPick now
839 </a>
840 </div>
841 <?php endif;
842 }
843 else {
844 ?>
845 <div id = "InternetState" class = "text-center mt-3 pe-3">
846 <img src = "<?php echo $imagesPath . 'no-wifi-icon.svg'; ?>" alt = "No Wifi Icon" class = "me-2">
847 <span>No internet present</span>
848 </div>
849 <?php
850 }
851
852 return ob_get_clean();
853 }
static getWebsiteUrl($path='', $fragment='', $utmSource=true)
static checkInternetState()
$enhancedMode
Definition homepage.php:169
$imagesPath
Definition homepage.php:52

References $bearsamppConfig, $enhancedMode, $imagesPath, $modules, $versions, checkDownloadId(), Util\checkInternetState(), and Util\getWebsiteUrl().

Referenced by loadQuickpick().

◆ getVersions()

getVersions ( )

Retrieves the list of available versions for all modules.

This method fetches the QuickPick JSON data and returns an array of versions or If no versions are found, an error message is logged and returned.

Returns
array An array of version strings for the specified module, or an error message if no versions are found.

Definition at line 295 of file class.action.quickPick.php.

295 : array
296 {
297 Util::logDebug( 'Versions called' );
298
299 $versions = [];
300
301 $jsonData = $this->getQuickpickJson();
302
303 foreach ( $jsonData as $entry ) {
304 if ( is_array( $entry ) ) {
305 if ( isset( $entry['module'] ) && is_string( $entry['module'] ) ) {
306 if ( isset( $entry['versions'] ) && is_array( $entry['versions'] ) ) {
307 $versions[$entry['module']] = array_column( $entry['versions'], null, 'version' );
308 }
309 }
310 }
311 else {
312 Util::logError( 'Invalid entry format in JSON data' );
313 }
314 }
315
316 if ( empty( $versions ) ) {
317 Util::logError( 'No versions found' );
318
319 return ['error' => 'No versions found'];
320 }
321
322 Util::logDebug( 'Found versions' );
323
324 $this->versions = $versions;
325
326 return $versions;
327 }

References $versions, getQuickpickJson(), Util\logDebug(), and Util\logError().

Referenced by getModuleUrl(), and loadQuickpick().

◆ installModule()

installModule ( string $module,
string $version )

Installs a specified module by fetching its URL and unzipping its contents.

This method retrieves the URL of the specified module and version from the QuickPick JSON data. If the URL is found, it fetches and unzips the module. If the URL is not found, it logs an error and returns an error message.

Parameters
string$moduleThe name of the module to install.
string$versionThe version of the module to install.
Returns
array An array containing the status and message of the installation process. If successful, it returns the response from the fetchAndUnzipModule method. If unsuccessful, it returns an error message indicating the issue.

Definition at line 446 of file class.action.quickPick.php.

446 : array
447 {
448 // Find the module URL and module name from the data
449 $moduleUrl = $this->getModuleUrl( $module, $version );
450
451 if ( is_array( $moduleUrl ) && isset( $moduleUrl['error'] ) ) {
452 Util::logError( 'Module URL not found for module: ' . $module . ' version: ' . $version );
453
454 return ['error' => 'Module URL not found'];
455 }
456
457 if ( empty( $moduleUrl ) ) {
458 Util::logError( 'Module URL not found for module: ' . $module . ' version: ' . $version );
459
460 return ['error' => 'Module URL not found'];
461 }
462
463 $state = Util::checkInternetState();
464 if ( $state ) {
465 $response = $this->fetchAndUnzipModule( $moduleUrl, $module );
466 Util::logDebug( 'Response is: ' . print_r( $response, true ) );
467
468 // Check if enhanced mode is enabled
469 global $bearsamppConfig;
470 $enhancedMode = $bearsamppConfig->getEnhancedQuickPick();
471
472 Util::logDebug('Enhanced mode: ' . ($enhancedMode ? 'enabled' : 'disabled'));
473
474 // If installation was successful and enhanced mode is enabled, update config
475 if (isset($response['success']) && $enhancedMode == 1) {
476 // Step 1: Update config FIRST (so reload can pick up the new version)
477 Util::logDebug('Enhanced mode enabled - Updating config for module: ' . $module . ' version: ' . $version);
478 $configUpdated = $this->updateModuleConfig($module, $version);
479
480 if ($configUpdated) {
481 // Step 2: Trigger reload AFTER config update (reload will apply the new version)
482 Util::logDebug('Config updated successfully, triggering reload to apply changes...');
483
484 // Send progress update to user - temporarily stop output buffering
485 $obLevel = ob_get_level();
486 while (ob_get_level() > 0) {
487 ob_end_flush();
488 }
489
490 echo json_encode(['phase' => 'updating', 'message' => 'Updating system configuration...']);
491 flush();
492
493 // Restart output buffering
494 for ($i = 0; $i < $obLevel; $i++) {
495 ob_start();
496 }
497
498 // Note: User must manually reload from tray menu to activate the new version
499 Util::logDebug('Installation complete - user must manually reload from tray menu');
500 $response['reload_required'] = true;
501 } else {
502 Util::logError('Config update failed for module: ' . $module);
503 $response['reload_triggered'] = false;
504 }
505 } else if (isset($response['success']) && $enhancedMode == 0) {
506 Util::logDebug('Enhanced mode disabled - skipping config update');
507 }
508
509 return $response;
510 }
511 else {
512 Util::logError( 'No internet connection available.' );
513
514 return ['error' => 'No internet connection'];
515 }
516 }
fetchAndUnzipModule(string $moduleUrl, string $module)
getModuleUrl(string $module, string $version)
updateModuleConfig(string $module, string $version)

References $bearsamppConfig, $enhancedMode, $response, Util\checkInternetState(), fetchAndUnzipModule(), getModuleUrl(), Util\logDebug(), Util\logError(), and updateModuleConfig().

◆ isValidHeaderResponse()

isValidHeaderResponse ( $headers)
private

Determines whether the header response is valid and includes a 'Date' key.

Parameters
mixed$headersHeaders retrieved from get_headers().
Returns
bool True if headers are valid and contain 'Date', false otherwise.

Definition at line 210 of file class.action.quickPick.php.

210 : bool
211 {
212 // If headers retrieval failed or Date is not set, return false
213 if ($headers === false || !isset($headers['Date'])) {
214 return false;
215 }
216 return true;
217 }

Referenced by checkQuickpickJson().

◆ loadQuickpick()

loadQuickpick ( string $imagesPath)

Loads the QuickPick interface with the available modules and their versions.

Parameters
string$imagesPathThe path to the images directory.
Returns
string The HTML content of the QuickPick interface.
Exceptions
Exception

Definition at line 135 of file class.action.quickPick.php.

135 : string
136 {
137 global $bearsamppConfig;
138
139 // Validate EnhancedQuickPick parameter
140 $validation = $bearsamppConfig->validateEnhancedQuickPick();
141 if (!$validation['valid']) {
142 return $this->getErrorModal($validation['error']);
143 }
144
145 $this->checkQuickpickJson();
146
147 $modules = $this->getModules();
148 $versions = $this->getVersions();
149
151 }
getErrorModal(string $errorMessage)
getQuickpickMenu(array $modules, array $versions, string $imagesPath)

References $bearsamppConfig, $imagesPath, $modules, $versions, checkQuickpickJson(), getErrorModal(), getModules(), getQuickpickMenu(), and getVersions().

◆ logHeaders()

logHeaders ( array $headers)
private

Logs the headers in debug mode if logsVerbose is set to 2.

Parameters
array$headersThe headers returned by get_headers().

Definition at line 224 of file class.action.quickPick.php.

224 : void
225 {
226 global $bearsamppConfig;
227
228 if ($bearsamppConfig->getLogsVerbose() === 2) {
229 Util::logDebug('Headers: ' . print_r($headers, true));
230 }
231 }

References $bearsamppConfig, and Util\logDebug().

Referenced by checkQuickpickJson().

◆ normalizeModuleName()

normalizeModuleName ( string $moduleName)

Normalizes a module name to find the correct module key from the modules array. Handles case-insensitive matching for all module types.

Parameters
string$moduleNameThe module name to normalize (may include 'module-' prefix)
Returns
string|null The correctly capitalized module key, or null if not found

Definition at line 100 of file class.action.quickPick.php.

100 : ?string
101 {
102 // Remove 'module-' prefix if present
103 $moduleName = str_replace('module-', '', $moduleName);
104
105 // Find the correct module key by searching through the modules array
106 // This handles proper capitalization for all module types
107 foreach ($this->modules as $key => $moduleInfo) {
108 if (strtolower($key) === strtolower($moduleName)) {
109 return $key;
110 }
111 }
112
113 return null;
114 }

◆ rebuildQuickpickJson()

rebuildQuickpickJson ( )

Rebuilds the local quickpick-releases.json file by fetching the latest data from the remote URL.

Returns
array An array containing the status and message of the rebuild process.
Exceptions
ExceptionIf the JSON content cannot be fetched or saved.

Definition at line 263 of file class.action.quickPick.php.

263 : array
264 {
265 Util::logDebug( 'Fetching JSON file: ' . $this->jsonFilePath );
266
267 // Fetch the JSON content from the URL
268 $jsonContent = file_get_contents( QUICKPICK_JSON_URL );
269
270 if ( $jsonContent === false ) {
271 // Handle error if the file could not be fetched
272 throw new Exception( 'Failed to fetch JSON content from the URL.' );
273 }
274
275 // Save the JSON content to the specified path
276 $result = file_put_contents( $this->jsonFilePath, $jsonContent );
277
278 if ( $result === false ) {
279 // Handle error if the file could not be saved
280 throw new Exception( 'Failed to save JSON content to the specified path.' );
281 }
282
283 // Return success message
284 return ['success' => 'JSON content fetched and saved successfully'];
285 }

References $result, Util\logDebug(), and QUICKPICK_JSON_URL.

Referenced by checkQuickpickJson(), and getLocalFileCreationTime().

◆ regenerateMenuSafe()

regenerateMenuSafe ( )
private

Regenerates the bearsampp.ini menu file without VBS checks (AJAX-safe version). This is a simplified version of TplApp\process() that avoids VBS errors in web context.

Returns
string The generated INI content

Definition at line 643 of file class.action.quickPick.php.

643 : string
644 {
645 Util::logDebug('Regenerating menu (AJAX-safe mode)...');
646
647 // Suppress errors temporarily during menu generation
648 $oldErrorReporting = error_reporting();
649 error_reporting($oldErrorReporting & ~E_WARNING);
650
651 try {
652 // Generate the menu content
653 $menuContent = TplApp::process();
654
655 // Restore error reporting
656 error_reporting($oldErrorReporting);
657
658 Util::logDebug('Menu regenerated successfully');
659 return $menuContent;
660
661 } catch (Exception $e) {
662 // Restore error reporting
663 error_reporting($oldErrorReporting);
664
665 Util::logWarning('Error during menu regeneration: ' . $e->getMessage());
666 throw $e;
667 }
668 }
static process()
static logWarning($data, $file=null)

References Util\logDebug(), Util\logWarning(), and TplApp\process().

◆ updateModuleConfig()

updateModuleConfig ( string $module,
string $version )
private

Updates the bearsampp.conf configuration file with the new module version. This method handles all module types: binaries, apps, and tools.

Parameters
string$moduleThe name of the module (e.g., 'Apache', 'PhpMyAdmin', 'Git').
string$versionThe version to set in the configuration.
Returns
bool True if the configuration was updated successfully, false otherwise.

Definition at line 679 of file class.action.quickPick.php.

679 : bool
680 {
681 try {
682 $bearsamppConfig = new Config();
683
684 // Remove 'module-' prefix if present and normalize the module name
685 $moduleName = str_replace('module-', '', $module);
686
687 // Find the correct module key by searching through the modules array
688 // This handles proper capitalization for all module types
689 $moduleKey = null;
690 foreach ($this->modules as $key => $moduleInfo) {
691 if (strtolower($key) === strtolower($moduleName)) {
692 $moduleKey = $key;
693 break;
694 }
695 }
696
697 if (!$moduleKey) {
698 Util::logError("Module not found in modules array: $moduleName");
699 return false;
700 }
701
702 $moduleType = $this->modules[$moduleKey]['type'];
703
704 // Map module names to their config section names
705 // For all types, use the lowercase name for the config key
706 $configSection = strtolower($moduleKey);
707
708 Util::logDebug("Updating config for module: $module (key: $moduleKey, type: $moduleType) to version: $version");
709 Util::logDebug("Config section: $configSection");
710
711 // Update the configuration file
712 // The Config class expects a flat key like "nodejsVersion" not a section
713 $configKey = $configSection . 'Version';
714 $bearsamppConfig->replace($configKey, $version);
715
716 Util::logInfo("Successfully updated $configSection version to $version in bearsampp.conf");
717
718 return true;
719
720 } catch (Exception $e) {
721 Util::logError("Failed to update module config: " . $e->getMessage());
722 return false;
723 }
724 }
static logInfo($data, $file=null)

References $bearsamppConfig, Util\logDebug(), Util\logError(), and Util\logInfo().

Referenced by installModule().

Field Documentation

◆ $jsonFilePath

$jsonFilePath
private

The file path to the local quickpick-releases.json file.

Definition at line 64 of file class.action.quickPick.php.

◆ $modules

$modules
Initial value:
= [
'Apache' => ['type' => 'binary'],
'Bruno' => ['type' => 'tools'],
'Composer' => ['type' => 'tools'],
'Ghostscript' => ['type' => 'tools'],
'Git' => ['type' => 'tools'],
'Mailpit' => ['type' => 'binary'],
'MariaDB' => ['type' => 'binary'],
'Memcached' => ['type' => 'binary'],
'MySQL' => ['type' => 'binary'],
'Ngrok' => ['type' => 'tools'],
'NodeJS' => ['type' => 'binary'],
'Perl' => ['type' => 'tools'],
'PHP' => ['type' => 'binary'],
'PhpMyAdmin' => ['type' => 'application'],
'PhpPgAdmin' => ['type' => 'application'],
'PostgreSQL' => ['type' => 'binary'],
'PowerShell' => ['type' => 'tools'],
'Python' => ['type' => 'tools'],
'Ruby' => ['type' => 'tools'],
'Xlight' => ['type' => 'binary']
]

An associative array where the key is the module name and the value is an array containing the module type. The module type can be one of the following:

  • 'application'
  • 'binary'
  • 'tool'

Definition at line 29 of file class.action.quickPick.php.

Referenced by getQuickpickMenu(), and loadQuickpick().

◆ $versions

$versions = []
private

An associative array where the key is the module name and the value is an array containing the module versions.

Definition at line 57 of file class.action.quickPick.php.

Referenced by getQuickpickMenu(), getVersions(), and loadQuickpick().


The documentation for this class was generated from the following file: