* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved. * @license GNU General Public License version 3 or later; see LICENSE */ namespace Joomla\Component\MokoSuiteBackup\Administrator\Field; defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\Form\FormField; use Joomla\CMS\Language\Text; use Joomla\Component\MokoSuiteBackup\Administrator\Utility\BackupDirectory; class FolderPickerField extends FormField { protected $type = 'FolderPicker'; protected function getInput(): string { $value = htmlspecialchars($this->value ?: $this->default, ENT_QUOTES, 'UTF-8'); $id = htmlspecialchars($this->id, ENT_QUOTES, 'UTF-8'); $name = htmlspecialchars($this->name, ENT_QUOTES, 'UTF-8'); $jRoot = JPATH_ROOT; // Resolve to absolute for display $rawValue = $this->value ?: $this->default; if ($rawValue && $rawValue[0] !== '/') { $absPath = $jRoot . '/' . $rawValue; } else { $absPath = $rawValue; } // Build placeholder map for JS resolution $hostname = preg_replace('/[^a-zA-Z0-9._-]/', '', $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? php_uname('n')); $siteName = ''; try { $siteName = Factory::getApplication()->get('sitename', ''); } catch (\Throwable $e) { // fallback } $sanitizedSiteName = preg_replace('/[^a-zA-Z0-9._-]/', '', str_replace(' ', '-', trim($siteName))); $placeholders = [ '[DEFAULT_DIR]' => BackupDirectory::getDefaultAbsolute(), '[HOME]' => BackupDirectory::getHomeDirectory(), '[host]' => $hostname, '[site_name]' => $sanitizedSiteName ?: 'joomla', '[profile_id]' => '1', '[profile_name]' => 'default', '[type]' => 'full', '[year]' => date('Y'), '[month]' => date('m'), '[day]' => date('d'), '[date]' => date('Ymd'), ]; $placeholdersJson = json_encode($placeholders); // Resolve placeholders for the status display $resolvedPath = str_replace(array_keys($placeholders), array_values($placeholders), $absPath); $hasPlaceholders = preg_match('/\[.+\]/', $absPath); if ($hasPlaceholders) { $exists = is_dir($resolvedPath); $statusClass = $exists ? 'text-success' : 'text-info'; $statusIcon = $exists ? 'icon-publish' : 'icon-info-circle'; $statusText = Text::_('COM_MOKOJOOMBACKUP_FOLDER_PLACEHOLDER'); $resolvedSafe = htmlspecialchars($resolvedPath, ENT_QUOTES, 'UTF-8'); $statusDetail = "{$statusText}: {$resolvedSafe}"; } else { $exists = is_dir($absPath); $statusClass = $exists ? 'text-success' : 'text-danger'; $statusIcon = $exists ? 'icon-publish' : 'icon-unpublish'; $statusText = $exists ? Text::_('COM_MOKOJOOMBACKUP_FOLDER_EXISTS') : Text::_('COM_MOKOJOOMBACKUP_FOLDER_NOT_FOUND'); $absPathSafe = htmlspecialchars($absPath, ENT_QUOTES, 'UTF-8'); $statusDetail = "{$statusText}: {$absPathSafe}"; } return <<
Insert:
{$statusDetail}
HTML; } }