* @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 <<