Skip to content

Commit

Permalink
Removed outdated hook system in extensions.
Browse files Browse the repository at this point in the history
  • Loading branch information
parpalak committed Sep 25, 2024
1 parent aa47874 commit a806706
Show file tree
Hide file tree
Showing 12 changed files with 4 additions and 140 deletions.
1 change: 0 additions & 1 deletion _admin/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,6 @@ textarea,
.bitbtn.saveopt { background-position: 1px -160px; }
.enabled .bitbtn.flip_ext { background-position: 1px -52px; }
.disabled .bitbtn.flip_ext { background-position: 1px -34px; }
.bitbtn.refresh-hooks { background: url(../i/r.png) 1px 2px no-repeat #f2f2f2; }
.bitbtn.uninst_ext { background-position: 1px -88px; }
.bitbtn.inst_ext { background-position: 1px -70px; }
.bitbtn.upgr_ext { background-position: 1px -178px; }
Expand Down
Binary file removed _admin/i/r.png
Binary file not shown.
1 change: 0 additions & 1 deletion _admin/install.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
define('S2_ROOT', '../');
define('S2_DEBUG', 1);
define('S2_SHOW_QUERIES', 1);
define('S2_DISABLE_HOOKS', 1);

// We need some stuff
require S2_ROOT . '_vendor/autoload.php';
Expand Down
5 changes: 0 additions & 5 deletions _admin/js/extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
* @package S2
*/

function RefreshHooks() {
fetch(sUrl + 'action=refresh_hooks');
return false;
}

function changeExtension(sAction, sId, sCsrfToken, sMessage) {
if (sAction === 'install_extension') {
if (!confirm((sMessage !== '' ? s2_lang.install_message.replaceAll('%s', sMessage) : '') + s2_lang.install_extension.replaceAll('%s', sId))) {
Expand Down
1 change: 0 additions & 1 deletion _admin/lang/en/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@
'Uninstall' => 'Uninstall',
'Enable' => 'Enable',
'Disable' => 'Disable',
'Refresh hooks' => 'Refresh hooks',
'Extension loading error' => 'Loading of extension “{{ extension }}” failed.',
'Illegal ID' => 'The ID must contain only lowercase alphanumeric characters (a-z and 0-9) and the underscore character (_).',
'Missing manifest' => 'Missing Manifest.php.',
Expand Down
1 change: 0 additions & 1 deletion _admin/lang/ru/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@
'Uninstall' => 'Удалить',
'Enable' => 'Включить',
'Disable' => 'Отключить',
'Refresh hooks' => 'Обновить хуки',
'Extension loading error' => 'Не удалось загрузить расширение «{{ extension }}».',
'Illegal ID' => 'Идентификатор расширения должен совпадать с названием папки расширения и состоять только из строчных английских букв или цифр (a-z, 0-9) или символа подчеркивания (_).',
'Missing manifest' => 'Отсутствует файл Manifest.php.',
Expand Down
5 changes: 0 additions & 5 deletions _admin/templates/extension/extension.php.inc
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,6 @@ $htmlEncode = static fn(string $str) => htmlspecialchars($str, ENT_QUOTES, 'UTF-
</div>
<?php endif; ?>

<?php if (count($installedExtensions) > 0): ?>
<button class="bitbtn refresh-hooks" style="position: relative; float:right; top:1em;"
onclick="return RefreshHooks();"><?= $trans('Refresh hooks') ?></button>
<?php endif; ?>

<h2><?= $trans('Installed extensions') ?></h2>

<?php if (count($installedExtensions) > 0): ?>
Expand Down
26 changes: 0 additions & 26 deletions _include/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,32 +292,6 @@ function s2_is_valid_email($email)
return preg_match('/^(([^<>()[\]\\.,;:\s@"\']+(\.[^<>()[\]\\.,;:\s@"\']+)*)|("[^"\']+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email);
}

//
// Return all code blocks that hook into $hook_id
//
function s2_hook($hook_id)
{
if (defined('S2_DISABLE_HOOKS')) {
return false;
}

static $hookNames = null;

if ($hookNames === null) {
/** @var ExtensionCache $cache */
$cache = \Container::get(ExtensionCache::class);
$hookNames = $cache->getHookNames();
}

if (!isset($hookNames[$hook_id])) {
return false;
}

$code = implode("\n", array_map(static fn(string $filename) => "\$_include_result = include S2_ROOT.'$filename'; if (\$_include_result !== 1) { return \$_include_result; }", $hookNames[$hook_id]));

return $code;
}

// Display a simple error message
function error()
{
Expand Down
12 changes: 0 additions & 12 deletions _include/src/Admin/AdminAjaxRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,6 @@ public function handle(Request $request): Response

return new Json(['success' => $error === null, 'message' => $error]);
},
'refresh_hooks' => static function (P $p, R $r, C $c, T $t) {
if (!$p->isGranted(P::PERMISSION_EDIT_USERS)) {
return new Json(['success' => false, 'message' => $t->trans('No permission')], Response::HTTP_FORBIDDEN);
}
/** @var ExtensionCache $extensionManager */
$cache = $c->get(ExtensionCache::class);
// Regenerate the hooks cache
$cache->generateHooks();
$cache->generateEnabledExtensionClassNames();

return new Json(['success' => true]);
},
'install_extension' => static function (P $p, R $r, C $c, T $t) {
if (!$p->isGranted(P::PERMISSION_EDIT_USERS)) {
return new Json(['success' => false, 'message' => $t->trans('No permission')], Response::HTTP_FORBIDDEN);
Expand Down
1 change: 0 additions & 1 deletion _include/src/CmsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ public function buildContainer(Container $container): void
return new ExtensionCache(
$container->get(DbLayer::class),
$container->getParameter('disable_cache'),
$container->getParameter('root_dir'),
$container->getParameter('cache_dir'),
);
});
Expand Down
9 changes: 3 additions & 6 deletions _include/src/Extensions/ExtensionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,8 @@ public function flipExtension(string $id): ?string
'WHERE' => 'id = :id',
], ['id' => $id]);

// Regenerate the hooks cache
// Regenerate the extension cache
$this->extensionCache->clear();
$this->extensionCache->generateHooks();

return null;
}
Expand Down Expand Up @@ -316,9 +315,8 @@ public function installExtension(string $id): array
// Extensions may add their own config params
$this->dynamicConfigProvider->regenerate();

// Regenerate the hooks cache
// Regenerate the extension cache
$this->extensionCache->clear();
$this->extensionCache->generateHooks();

return [];
}
Expand Down Expand Up @@ -367,9 +365,8 @@ public function uninstallExtension(string $id): ?string
'WHERE' => 'id = :id',
], ['id' => $id]);

// Regenerate the hooks cache
// Regenerate the extension cache
$this->extensionCache->clear();
$this->extensionCache->generateHooks();

return null;
}
Expand Down
82 changes: 1 addition & 81 deletions _include/src/Model/ExtensionCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class ExtensionCache
public function __construct(
private readonly DbLayer $dbLayer,
private readonly bool $disableCache,
private readonly string $rootDir,
private readonly string $cacheDir,
) {
}
Expand All @@ -36,8 +35,6 @@ public function clear(): void
$file_list = [
// Deprecated. Remove when all values are accessed through DynamicConfigProvider
$this->cacheDir . 'cache_config.php',

$this->getHookNamesCacheFilename(),
$this->cacheDir . self::CACHE_ENABLED_EXTENSIONS_FILENAME,
$this->getCachedRoutesFilename(),
];
Expand Down Expand Up @@ -86,86 +83,14 @@ public function generateEnabledExtensionClassNames(): array
);
} catch (\RuntimeException $e) {
error(sprintf(
'Unable to write hooks cache file to cache directory. Please make sure PHP has write access to the directory "%s".',
'Unable to write extensions cache file to cache directory. Please make sure PHP has write access to the directory "%s".',
$this->cacheDir
), __FILE__, __LINE__);
}

return $extensionClassNames;
}

/**
* Scans hook directories for enabled extensions and generates the map of hook file names.
*/
public function generateHooks(): array
{
// Get extensions from the DB
$query = [
'SELECT' => 'e.id',
'FROM' => 'extensions AS e',
'WHERE' => 'e.disabled=0',
];

$result = $this->dbLayer->buildAndQuery($query);

$map = [];
while ($extension = $this->dbLayer->fetchAssoc($result)) {
$hooks = glob($this->rootDir . '_extensions/' . $extension['id'] . '/hooks/*.php');
foreach ($hooks as $filename) {
if (1 !== preg_match($regex = '#/([a-z_\-0-9]+?)(?:_(\d))?\.php$#S', $filename, $matches)) {
throw new \RuntimeException(sprintf('Found invalid characters in hook filename "%s". Allowed name must match %s.', $filename, $regex));
}
$priority = (int)($matches[2] ?? 5);
$hookName = $matches[1];

// Structure
$map[$hookName][$priority][] = '_extensions/' . $extension['id'] . '/hooks' . $matches[0];
}
}

array_walk($map, static function (&$mapItem) {
// Sort by priority
ksort($mapItem);
// Remove grouping by priority
$mapItem = array_merge(...$mapItem);
});

if ($this->disableCache) {
return $map;
}

// Output hooks as PHP code
try {
s2_overwrite_file_skip_locked(
$this->getHookNamesCacheFilename(),
"<?php\n\nreturn " . var_export($map, true) . ';'
);
} catch (\RuntimeException $e) {
error(sprintf(
'Unable to write hooks cache file to cache directory. Please make sure PHP has write access to the directory "%s".',
$this->cacheDir
), __FILE__, __LINE__);
}

return $map;
}

/**
* Retrieves hook names for enabled extensions from cache or by scanning hook directories.
*/
public function getHookNames(): array
{
$hookNames = null;
if (!$this->disableCache && file_exists($filename = $this->getHookNamesCacheFilename())) {
$hookNames = include $filename;
}
if (!\is_array($hookNames)) {
$hookNames = $this->generateHooks();
}

return $hookNames;
}

public function clearRoutesCache(): void
{
@unlink($this->getCachedRoutesFilename());
Expand All @@ -175,9 +100,4 @@ public function getCachedRoutesFilename(): string
{
return $this->cacheDir . 'cache_routes.php';
}

private function getHookNamesCacheFilename(): string
{
return $this->cacheDir . 'cache_hook_names.php';
}
}

0 comments on commit a806706

Please sign in to comment.