Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ updates:
labels:
- Dependencies
# Actions are pulled by SHA, but a compromised release is still a risk —
# wait a week so takedowns/reverts can happen first.
# wait a week so takedowns/reverts can happen first. semver-major-days is
# not supported for the github-actions ecosystem, so only the default
# cooldown applies here.
cooldown:
default-days: 7
semver-major-days: 14
groups:
github-actions:
patterns:
Expand Down
40 changes: 40 additions & 0 deletions src/Block/Inspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
private readonly DeveloperAccessChecker $developerAccessChecker,
array $data = [],
) {
parent::__construct($context, $data);

Check warning on line 36 in src/Block/Inspector.php

View workflow job for this annotation

GitHub Actions / Mutation Tests (Infection)

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ private readonly DeveloperAccessChecker $developerAccessChecker, array $data = [], ) { - parent::__construct($context, $data); + } /**
}

/**
Expand Down Expand Up @@ -138,6 +138,46 @@
return is_string($value) && $value !== '' ? $value : InspectorConfig::DEFAULT_POSITION;
}

/**
* Whether keyboard shortcuts are enabled for toolbar and inspector
*
* @return bool
*/
public function getKeyboardShortcutsEnabled(): bool
{
$value = $this->scopeConfig->getValue(
InspectorConfig::XML_PATH_KEYBOARD_SHORTCUTS_ENABLED,
InspectorConfig::SCOPE_STORE,
);
// Default to true when not explicitly set to '0'
return !is_string($value) || $value !== '0';
}

/**
* Get configured toolbar keyboard shortcut
*
* @return string
*/
public function getToolbarShortcut(): string
{
$value = $this->scopeConfig->getValue(InspectorConfig::XML_PATH_TOOLBAR_SHORTCUT, InspectorConfig::SCOPE_STORE);
return is_string($value) && $value !== '' ? $value : InspectorConfig::DEFAULT_TOOLBAR_SHORTCUT;
}

/**
* Get configured inspector keyboard shortcut
*
* @return string
*/
public function getInspectorShortcut(): string
{
$value = $this->scopeConfig->getValue(
InspectorConfig::XML_PATH_INSPECTOR_SHORTCUT,
InspectorConfig::SCOPE_STORE,
);
return is_string($value) && $value !== '' ? $value : InspectorConfig::DEFAULT_INSPECTOR_SHORTCUT;
}

/**
* Render block HTML
*
Expand Down
5 changes: 5 additions & 0 deletions src/Model/Config/Inspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ class Inspector
public const XML_PATH_SHOW_BUTTON_LABELS = 'mageforge/inspector/show_button_labels';
public const XML_PATH_THEME = 'mageforge/inspector/theme';
public const XML_PATH_POSITION = 'mageforge/inspector/position';
public const XML_PATH_KEYBOARD_SHORTCUTS_ENABLED = 'mageforge/inspector/keyboard_shortcuts_enabled';
public const XML_PATH_TOOLBAR_SHORTCUT = 'mageforge/inspector/toolbar_shortcut';
public const XML_PATH_INSPECTOR_SHORTCUT = 'mageforge/inspector/inspector_shortcut';
public const DEFAULT_THEME = 'dark';
public const DEFAULT_POSITION = 'bottom-left';
public const DEFAULT_TOOLBAR_SHORTCUT = 'Ctrl+Shift+A';
public const DEFAULT_INSPECTOR_SHORTCUT = 'Ctrl+Shift+I';

/**
* Store scope type.
Expand Down
24 changes: 24 additions & 0 deletions src/Model/Config/TemplateOverride.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,30 @@ class TemplateOverride
{
public const XML_PATH_ADD_HEADER = 'mageforge/template_override/add_header';

// @mago-format-ignore-start
// Kept multi-line so PHPCS' 120-character limit is respected; Mago would re-fold them.
public const XML_PATH_SOURCE_HEADER_INCLUDE_DATE
= 'mageforge/template_override/source_header_include_date';
public const XML_PATH_SOURCE_HEADER_INCLUDE_MODULE_VERSION
= 'mageforge/template_override/source_header_include_module_version';
public const XML_PATH_SOURCE_HEADER_INCLUDE_SOURCE_PATH
= 'mageforge/template_override/source_header_include_source_path';
public const XML_PATH_SOURCE_HEADER_INCLUDE_SOURCE_MODULE
= 'mageforge/template_override/source_header_include_source_module';
public const XML_PATH_SOURCE_HEADER_INCLUDE_OVERRIDE_FOR
= 'mageforge/template_override/source_header_include_override_for';
public const XML_PATH_SOURCE_HEADER_ENABLE_PHTML
= 'mageforge/template_override/source_header_enable_phtml';
public const XML_PATH_SOURCE_HEADER_ENABLE_HTML
= 'mageforge/template_override/source_header_enable_html';
public const XML_PATH_SOURCE_HEADER_ENABLE_XML
= 'mageforge/template_override/source_header_enable_xml';
public const XML_PATH_SOURCE_HEADER_ENABLE_WEB_ASSETS
= 'mageforge/template_override/source_header_enable_web_assets';
public const XML_PATH_SOURCE_HEADER_ENABLE_SHELL
= 'mageforge/template_override/source_header_enable_shell';
// @mago-format-ignore-end

/**
* Store scope type.
*
Expand Down
167 changes: 151 additions & 16 deletions src/Service/TemplateOverride/TemplateCopier.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,104 @@ public function __construct(
) {
}

/**
* Check whether the override date should be included in the source header
*
* @return bool
*/
private function shouldIncludeDateInHeader(): bool
{
return $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_INCLUDE_DATE,
TemplateOverrideConfig::SCOPE_STORE,
);
}

/**
* Check whether the source module version should be included in the source header
*
* @return bool
*/
private function shouldIncludeModuleVersionInHeader(): bool
{
return $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_INCLUDE_MODULE_VERSION,
TemplateOverrideConfig::SCOPE_STORE,
);
}

/**
* Check whether the relative source path should be included in the source header
*
* @return bool
*/
private function shouldIncludeSourcePathInHeader(): bool
{
return $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_INCLUDE_SOURCE_PATH,
TemplateOverrideConfig::SCOPE_STORE,
);
}

/**
* Check whether the source module name should be included in the source header
*
* @return bool
*/
private function shouldIncludeSourceModuleInHeader(): bool
{
return $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_INCLUDE_SOURCE_MODULE,
TemplateOverrideConfig::SCOPE_STORE,
);
}

/**
* Check whether the logical override target should be included in the source header
*
* @return bool
*/
private function shouldIncludeOverrideForInHeader(): bool
{
return $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_INCLUDE_OVERRIDE_FOR,
TemplateOverrideConfig::SCOPE_STORE,
);
}

/**
* Check whether source headers are enabled for the given file type
*
* @param string $filePath
* @return bool
*/
private function isHeaderEnabledForFile(string $filePath): bool
{
return match ($this->extension($filePath)) {
'phtml', 'php' => $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_ENABLE_PHTML,
TemplateOverrideConfig::SCOPE_STORE,
),
'html', 'htm' => $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_ENABLE_HTML,
TemplateOverrideConfig::SCOPE_STORE,
),
'xml', 'xhtml', 'svg' => $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_ENABLE_XML,
TemplateOverrideConfig::SCOPE_STORE,
),
'css', 'js', 'less', 'scss', 'sass', 'ts' => $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_ENABLE_WEB_ASSETS,
TemplateOverrideConfig::SCOPE_STORE,
),
'sh', 'bash', 'zsh', 'fish' => $this->scopeConfig->isSetFlag(
TemplateOverrideConfig::XML_PATH_SOURCE_HEADER_ENABLE_SHELL,
TemplateOverrideConfig::SCOPE_STORE,
),
default => false,
};
}

/**
* Copy the source template to the target location
*
Expand All @@ -52,7 +150,7 @@ public function copy(string $sourceFile, string $targetFile, ?string $sourceModu
}

$commentStyle = $this->commentStyle->fromFilePath($targetFile);
if ($commentStyle->isSupported() && $this->shouldAddHeader()) {
if ($commentStyle->isSupported() && $this->shouldAddHeader() && $this->isHeaderEnabledForFile($targetFile)) {
$this->copyWithHeader($sourceFile, $targetFile, $sourceModuleName, $commentStyle);
return;
}
Expand Down Expand Up @@ -120,23 +218,34 @@ private function copyWithHeader(
*/
private function buildHeaderLines(string $sourceFile, ?string $sourceModuleName): array
{
$date = date('Y-m-d');
$lines = [
'MageForge Template Override from ' . $date,
'Source: ' . $this->toRelativePath($sourceFile),
'MageForge Template Override',
];

if ($this->shouldIncludeDateInHeader()) {
$lines[] = 'Date: ' . date('Y-m-d');
}

if ($this->shouldIncludeSourcePathInHeader()) {
$lines[] = 'Source: ' . $this->toRelativePath($sourceFile);
}

$actualSourceModule = $this->resolveSourceModule($sourceFile);
$includeSourceModule = $this->shouldIncludeSourceModuleInHeader();

if ($actualSourceModule !== null) {
if ($actualSourceModule !== null && $includeSourceModule) {
$lines[] = 'Source Module: ' . $actualSourceModule;
$version = $this->packageInfo->getVersion($actualSourceModule);
$version = $this->shouldIncludeModuleVersionInHeader()
? $this->packageInfo->getVersion($actualSourceModule)
: '';
if ($version !== '') {
$lines[] = 'Source Module-Version: ' . $version;
}
} elseif ($sourceModuleName !== null && $sourceModuleName !== '') {
} elseif ($sourceModuleName !== null && $sourceModuleName !== '' && $includeSourceModule) {
$lines[] = 'Override For: ' . $sourceModuleName;
$version = $this->packageInfo->getVersion($sourceModuleName);
$version = $this->shouldIncludeModuleVersionInHeader()
? $this->packageInfo->getVersion($sourceModuleName)
: '';
if ($version !== '') {
$lines[] = 'Module-Version: ' . $version;
}
Expand All @@ -158,36 +267,62 @@ private function buildHeaderLines(string $sourceFile, ?string $sourceModuleName)
*/
private function buildPhpDocHeaderLines(string $sourceFile, ?string $sourceModuleName): array
{
$date = date('Y-m-d');
$lines = [
'@mageforge-template-override',
'@date ' . $date,
'@source ' . $this->toRelativePath($sourceFile),
];

if ($this->shouldIncludeDateInHeader()) {
$lines[] = '@date ' . date('Y-m-d');
}

if ($this->shouldIncludeSourcePathInHeader()) {
$lines[] = '@source ' . $this->toRelativePath($sourceFile);
}

$actualSourceModule = $this->resolveSourceModule($sourceFile);
$includeSourceModule = $this->shouldIncludeSourceModuleInHeader();

if ($actualSourceModule !== null) {
if ($actualSourceModule !== null && $includeSourceModule) {
$lines[] = '@module ' . $actualSourceModule;
$version = $this->packageInfo->getVersion($actualSourceModule);
$version = $this->shouldIncludeModuleVersionInHeader()
? $this->packageInfo->getVersion($actualSourceModule)
: '';
if ($version !== '') {
$lines[] = '@module-version ' . $version;
}
} elseif ($sourceModuleName !== null && $sourceModuleName !== '') {
} elseif ($sourceModuleName !== null && $sourceModuleName !== '' && $includeSourceModule) {
$lines[] = '@module ' . $sourceModuleName;
$version = $this->packageInfo->getVersion($sourceModuleName);
$version = $this->shouldIncludeModuleVersionInHeader()
? $this->packageInfo->getVersion($sourceModuleName)
: '';
if ($version !== '') {
$lines[] = '@module-version ' . $version;
}
}

if ($this->isOverrideForDifferentModule($actualSourceModule, $sourceModuleName)) {
$includeOverrideFor =
$this->shouldIncludeOverrideForInHeader()
&& $this->isOverrideForDifferentModule($actualSourceModule, $sourceModuleName);
if ($includeOverrideFor) {
$lines[] = '@override-for ' . (string) $sourceModuleName;
}

return $lines;
}

/**
* Extract the lower-cased file extension from a path
*
* @param string $filePath
* @return string
*/
Comment on lines +313 to +318
private function extension(string $filePath): string
{
$lastDot = strrpos($filePath, '.');

return $lastDot === false ? '' : strtolower(substr($filePath, $lastDot + 1));
}

/**
* Check whether the source file belongs to a different module than the logical override target
*
Expand Down
Loading
Loading