Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
fix: Add missing ITemplate interface and clean code in Template class
Signed-off-by: Côme Chilliet <[email protected]>
  • Loading branch information
come-nc committed Mar 6, 2025
commit f19ddd55255a881de6efabdfc4468b2680ffc52d
4 changes: 4 additions & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,8 @@
'OCP\\Teams\\Team' => $baseDir . '/lib/public/Teams/Team.php',
'OCP\\Teams\\TeamResource' => $baseDir . '/lib/public/Teams/TeamResource.php',
'OCP\\Template' => $baseDir . '/lib/public/Template.php',
'OCP\\Template\\ITemplate' => $baseDir . '/lib/public/Template/ITemplate.php',
'OCP\\Template\\ITemplateManager' => $baseDir . '/lib/public/Template/ITemplateManager.php',
'OCP\\TextProcessing\\Events\\AbstractTextProcessingEvent' => $baseDir . '/lib/public/TextProcessing/Events/AbstractTextProcessingEvent.php',
'OCP\\TextProcessing\\Events\\TaskFailedEvent' => $baseDir . '/lib/public/TextProcessing/Events/TaskFailedEvent.php',
'OCP\\TextProcessing\\Events\\TaskSuccessfulEvent' => $baseDir . '/lib/public/TextProcessing/Events/TaskSuccessfulEvent.php',
Expand Down Expand Up @@ -2041,7 +2043,9 @@
'OC\\Template\\JSResourceLocator' => $baseDir . '/lib/private/Template/JSResourceLocator.php',
'OC\\Template\\ResourceLocator' => $baseDir . '/lib/private/Template/ResourceLocator.php',
'OC\\Template\\ResourceNotFoundException' => $baseDir . '/lib/private/Template/ResourceNotFoundException.php',
'OC\\Template\\Template' => $baseDir . '/lib/private/Template/Template.php',
'OC\\Template\\TemplateFileLocator' => $baseDir . '/lib/private/Template/TemplateFileLocator.php',
'OC\\Template\\TemplateManager' => $baseDir . '/lib/private/Template/TemplateManager.php',
'OC\\TextProcessing\\Db\\Task' => $baseDir . '/lib/private/TextProcessing/Db/Task.php',
'OC\\TextProcessing\\Db\\TaskMapper' => $baseDir . '/lib/private/TextProcessing/Db/TaskMapper.php',
'OC\\TextProcessing\\Manager' => $baseDir . '/lib/private/TextProcessing/Manager.php',
Expand Down
4 changes: 4 additions & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,8 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Teams\\Team' => __DIR__ . '/../../..' . '/lib/public/Teams/Team.php',
'OCP\\Teams\\TeamResource' => __DIR__ . '/../../..' . '/lib/public/Teams/TeamResource.php',
'OCP\\Template' => __DIR__ . '/../../..' . '/lib/public/Template.php',
'OCP\\Template\\ITemplate' => __DIR__ . '/../../..' . '/lib/public/Template/ITemplate.php',
'OCP\\Template\\ITemplateManager' => __DIR__ . '/../../..' . '/lib/public/Template/ITemplateManager.php',
'OCP\\TextProcessing\\Events\\AbstractTextProcessingEvent' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Events/AbstractTextProcessingEvent.php',
'OCP\\TextProcessing\\Events\\TaskFailedEvent' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Events/TaskFailedEvent.php',
'OCP\\TextProcessing\\Events\\TaskSuccessfulEvent' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Events/TaskSuccessfulEvent.php',
Expand Down Expand Up @@ -2090,7 +2092,9 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Template\\JSResourceLocator' => __DIR__ . '/../../..' . '/lib/private/Template/JSResourceLocator.php',
'OC\\Template\\ResourceLocator' => __DIR__ . '/../../..' . '/lib/private/Template/ResourceLocator.php',
'OC\\Template\\ResourceNotFoundException' => __DIR__ . '/../../..' . '/lib/private/Template/ResourceNotFoundException.php',
'OC\\Template\\Template' => __DIR__ . '/../../..' . '/lib/private/Template/Template.php',
'OC\\Template\\TemplateFileLocator' => __DIR__ . '/../../..' . '/lib/private/Template/TemplateFileLocator.php',
'OC\\Template\\TemplateManager' => __DIR__ . '/../../..' . '/lib/private/Template/TemplateManager.php',
'OC\\TextProcessing\\Db\\Task' => __DIR__ . '/../../..' . '/lib/private/TextProcessing/Db/Task.php',
'OC\\TextProcessing\\Db\\TaskMapper' => __DIR__ . '/../../..' . '/lib/private/TextProcessing/Db/TaskMapper.php',
'OC\\TextProcessing\\Manager' => __DIR__ . '/../../..' . '/lib/private/TextProcessing/Manager.php',
Expand Down
1 change: 1 addition & 0 deletions lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ public function __construct($webRoot, \OC\Config $config) {

$this->registerAlias(\OCP\DirectEditing\IManager::class, \OC\DirectEditing\Manager::class);
$this->registerAlias(ITemplateManager::class, TemplateManager::class);
$this->registerAlias(\OCP\Template\ITemplateManager::class, \OC\Template\TemplateManager::class);

$this->registerAlias(IActionFactory::class, ActionFactory::class);

Expand Down
90 changes: 39 additions & 51 deletions lib/private/Template/Template.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,87 +10,79 @@

namespace OC\Template;

use OC\Security\CSP\ContentSecurityPolicyNonceManager;
use OC\TemplateLayout;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Defaults;
use OCP\Server;
use OCP\Template\ITemplate;
use OCP\Util;

require_once __DIR__ . '/../legacy/template/functions.php';

class Template extends Base implements ITemplate {
/** @var string */
private $renderAs; // Create a full page?

/** @var string */
private $path; // The path to the template

/** @var array */
private $headers = []; //custom headers

/** @var string */
protected $app; // app id
private string $path;
private array $headers = [];

/**
* Constructor
*
* @param string $app app providing the template
* @param string $name of the template file (without suffix)
* @param string $renderAs If $renderAs is set, will try to
* produce a full page in the according layout. For
* now, $renderAs can be set to "guest", "user" or
* "admin".
* @param bool $registerCall = true
* @param TemplateResponse::RENDER_AS_* $renderAs If $renderAs is set, will try to
* produce a full page in the according layout.
*/
public function __construct(
$app,
$name,
$renderAs = TemplateResponse::RENDER_AS_BLANK,
$registerCall = true,
protected string $app,
string $name,
private string $renderAs = TemplateResponse::RENDER_AS_BLANK,
bool $registerCall = true,
) {
$theme = OC_Util::getTheme();
$theme = \OC_Util::getTheme();

$requestToken = (OC::$server->getSession() && $registerCall) ? \OCP\Util::callRegister() : '';
$cspNonce = \OCP\Server::get(\OC\Security\CSP\ContentSecurityPolicyNonceManager::class)->getNonce();
$requestToken = ($registerCall ? Util::callRegister() : '');
$cspNonce = Server::get(ContentSecurityPolicyNonceManager::class)->getNonce();

$parts = explode('/', $app); // fix translation when app is something like core/lostpassword
$l10n = \OC::$server->getL10N($parts[0]);
/** @var \OCP\Defaults $themeDefaults */
$themeDefaults = \OCP\Server::get(\OCP\Defaults::class);
// fix translation when app is something like core/lostpassword
$parts = explode('/', $app);
$l10n = Util::getL10N($parts[0]);

[$path, $template] = $this->findTemplate($theme, $app, $name);

// Set the private data
$this->renderAs = $renderAs;
$this->path = $path;
$this->app = $app;

parent::__construct(
$template,
$requestToken,
$l10n,
$themeDefaults,
Server::get(Defaults::class),
$cspNonce,
);
}


/**
* find the template with the given name
* @param string $name of the template file (without suffix)
*
* Will select the template file for the selected theme.
* Checking all the possible locations.
* @param string $theme
* @param string $app
*
* @param string $name of the template file (without suffix)
* @return string[]
*/
protected function findTemplate($theme, $app, $name) {
protected function findTemplate(string $theme, string $app, string $name): array {
// Check if it is a app template or not.
if ($app !== '') {
$dirs = $this->getAppTemplateDirs($theme, $app, OC::$SERVERROOT, OC_App::getAppPath($app));
try {
$appDir = Server::get(IAppManager::class)->getAppPath($app);
} catch (AppPathNotFoundException) {
$appDir = false;
}
$dirs = $this->getAppTemplateDirs($theme, $app, \OC::$SERVERROOT, $appDir);
} else {
$dirs = $this->getCoreTemplateDirs($theme, OC::$SERVERROOT);
$dirs = $this->getCoreTemplateDirs($theme, \OC::$SERVERROOT);
}
$locator = new \OC\Template\TemplateFileLocator($dirs);
$locator = new TemplateFileLocator($dirs);
$template = $locator->find($name);
$path = $locator->getPath();
return [$path, $template];
Expand All @@ -103,7 +95,7 @@ protected function findTemplate($theme, $app, $name) {
* @param string $text the text content for the element. If $text is null then the
* element will be written as empty element. So use "" to get a closing tag.
*/
public function addHeader($tag, $attributes, $text = null) {
public function addHeader(string $tag, array $attributes, ?string $text = null): void {
$this->headers[] = [
'tag' => $tag,
'attributes' => $attributes,
Expand All @@ -113,12 +105,11 @@ public function addHeader($tag, $attributes, $text = null) {

/**
* Process the template
* @return string
*
* This function process the template. If $this->renderAs is set, it
* will produce a full page.
*/
public function fetchPage($additionalParams = null) {
public function fetchPage(?array $additionalParams = null): string {
$data = parent::fetchPage($additionalParams);

if ($this->renderAs) {
Expand All @@ -132,23 +123,22 @@ public function fetchPage($additionalParams = null) {

// Add custom headers
$headers = '';
foreach (OC_Util::$headers as $header) {
$headers .= '<' . \OCP\Util::sanitizeHTML($header['tag']);
foreach (\OC_Util::$headers as $header) {
$headers .= '<' . Util::sanitizeHTML($header['tag']);
if (strcasecmp($header['tag'], 'script') === 0 && in_array('src', array_map('strtolower', array_keys($header['attributes'])))) {
$headers .= ' defer';
}
foreach ($header['attributes'] as $name => $value) {
$headers .= ' ' . \OCP\Util::sanitizeHTML($name) . '="' . \OCP\Util::sanitizeHTML($value) . '"';
$headers .= ' ' . Util::sanitizeHTML($name) . '="' . Util::sanitizeHTML($value) . '"';
}
if ($header['text'] !== null) {
$headers .= '>' . \OCP\Util::sanitizeHTML($header['text']) . '</' . \OCP\Util::sanitizeHTML($header['tag']) . '>';
$headers .= '>' . Util::sanitizeHTML($header['text']) . '</' . Util::sanitizeHTML($header['tag']) . '>';
} else {
$headers .= '/>';
}
}

$page->assign('headers', $headers);

$page->assign('content', $data);
return $page->fetchPage($additionalParams);
}
Expand All @@ -159,14 +149,12 @@ public function fetchPage($additionalParams = null) {
/**
* Include template
*
* @param string $file
* @param array|null $additionalParams
* @return string returns content of included template
*
* Includes another template. use <?php echo $this->inc('template'); ?> to
* do this.
*/
public function inc($file, $additionalParams = null) {
public function inc(string $file, ?array $additionalParams = null): string {
return $this->load($this->path . $file . '.php', $additionalParams);
}
}
3 changes: 1 addition & 2 deletions lib/private/legacy/OC_Util.php
Original file line number Diff line number Diff line change
Expand Up @@ -725,11 +725,10 @@ public static function getInstanceId() {
* string or array of strings before displaying it on a web page.
*
* @param string|string[] $value
* @return string|string[] an array of sanitized strings or a single sanitized string, depends on the input parameter.
* @return ($value is array ? string[] : string)
*/
public static function sanitizeHTML($value) {
if (is_array($value)) {
/** @var string[] $value */
$value = array_map(function ($value) {
return self::sanitizeHTML($value);
}, $value);
Expand Down
38 changes: 38 additions & 0 deletions lib/public/Template/ITemplate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCP\Template;

/**
* @since 32.0.0
*/
interface ITemplate {
/**
* Process the template
* @since 32.0.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: return value could be documented. I'm assuming it's the template HTML

*/
public function fetchPage(?array $additionalParams = null): string;

/**
* Proceed the template and print its output.
* @since 32.0.0
*/
public function printPage(): void;

/**
* Assign variables
*
* This function assigns a variable. It can be accessed via $_[$key] in
* the template.
*
* If the key existed before, it will be overwritten
* @since 32.0.0
*/
public function assign(string $key, float|array|bool|int|string|\Throwable $value): void;
}
2 changes: 1 addition & 1 deletion lib/public/Util.php
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ public static function callRegister() {
* string or array of strings before displaying it on a web page.
*
* @param string|string[] $value
* @return string|string[] an array of sanitized strings or a single sanitized string, depends on the input parameter.
* @return ($value is array ? string[] : string) an array of sanitized strings or a single sanitized string, depends on the input parameter.
* @since 4.5.0
*/
public static function sanitizeHTML($value) {
Expand Down