aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Cache/File.php
blob: 10152d0966b4b05666f558b97225225f0e1a6a58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; pad
<?php

/**
 * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
 * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
 * SPDX-License-Identifier: AGPL-3.0-only
 */
namespace OC\Cache;

use OC\Files\Filesystem;
use OC\Files\View;
use OCP\ICache;
use OCP\Security\ISecureRandom;
use Psr\Log\LoggerInterface;

class File implements ICache {
	/** @var View */
	protected $storage;

	/**
	 * Returns the cache storage for the logged in user
	 *
	 * @return \OC\Files\View cache storage
	 * @throws \OC\ForbiddenException
	 * @throws \OC\User\NoUserException
	 */
	protected function getStorage() {
		if ($this->storage !== null) {
			return $this->storage;
		}
		if (\OC::$server->getUserSession()->isLoggedIn()) {
			$rootView = new View();
			$user = \OC::$server->getUserSession()->getUser();
			Filesystem::initMountPoints($user->getUID());
			if (!$rootView->file_exists('/' . $user->getUID() . '/cache')) {
				$rootView->mkdir('/' . $user->getUID() . '/cache');
			}
			$this->storage = new View('/' . $user->getUID() . '/cache');
			return $this->storage;
		} else {
			\OCP\Server::get(LoggerInterface::class)->error('Can\'t get cache storage, user not logged in', ['app' => 'core']);
			throw new \OC\ForbiddenException('Can\t get cache storage, user not logged in');
		}
	}

	/**
	 * @param string $key
	 * @return mixed|null
	 * @throws \OC\ForbiddenException
	 */
	public function get($key) {
		$result = null;
		if ($this->hasKey($key)) {
			$storage = $this->getStorage();
			$result = $storage->file_get_contents($key);
		}
		return $result;
	}

	/**
	 * Returns the size of the stored/cached data
	 *
	 * @param string $key
	 * @return int
	 */
	public function size($key) {
		$result = 0;
		if ($this->hasKey($key)) {
			$storage = $this->getStorage();
			$result = $storage->filesize($key);
		}
		return $result;
	}

	/**
	 * @param string $key
	 * @param mixed $value
	 * @param int $ttl
	 * @return bool|mixed
	 * @throws \OC\ForbiddenException
	 */
	public function set($key, $value, $ttl = 0) {
		$storage = $this->getStorage();
		$result = false;
		// unique id to avoid chunk collision, just in case
		$uniqueId = \OC::$server->get(ISecureRandom::class)->generate(
			16,
			ISecureRandom::CHAR_ALPHANUMERIC
		);

		// use part file to prevent hasKey() to find the key
		// while it is being written
		$keyPart = $key . '.' . $uniqueId . '.part';
		if ($storage and $storage->file_put_contents($keyPart, $value)) {
			if ($ttl === 0) {
				$ttl = 86400; // 60*60*24
			}
			$result = $storage->touch($keyPart, time() + $ttl);
			$result &= $storage->rename($keyPart, $key);
		}
		return $result;
	}

	/**
	 * @param string $key
	 * @return bool
	 * @throws \OC\ForbiddenException
	 */
	public function hasKey($key) {
		$storage = $this->getStorage();
		if ($storage && $storage->is_file($key) && $storage->isReadable($key)) {
			return true;
		}
		return false;
	}

	/**
	 * @param string $key
	 * @return bool|mixed
	 * @throws \OC\ForbiddenException
	 */
	public function remove($key) {
		$storage = $this->getStorage();
		if (!$storage) {
			return false;
		}
		return $storage->unlink($key);
	}

	/**
	 * @param string $prefix
	 * @return bool
	 * @throws \OC\ForbiddenException
	 */
	public function clear($prefix = '') {
		$storage = $this->getStorage();
		if ($storage and $storage->is_dir('/')) {
			$dh = $storage->opendir('/');
			if (is_resource($dh)) {
				while (($file = readdir($dh)) !== false) {
					if ($file != '.' and $file != '..' and ($prefix === '' || str_starts_with($file, $prefix))) {
						$storage->unlink('/' . $file);
					}
				}
			}
		}
		return true;
	}

	/**
	 * Runs GC
	 * @throws \OC\ForbiddenException
	 */
	public function gc() {
		$storage = $this->getStorage();
		if ($storage) {
			// extra hour safety, in case of stray part chunks that take longer to write,
			// because touch() is only called after the chunk was finished
			$now = time() - 3600;
			$dh = $storage->opendir('/');
			if (!is_resource($dh)) {
				return null;
			}
			while (($file = readdir($dh)) !== false) {
				if ($file != '.' and $file != '..') {
					try {
						$mtime = $storage->filemtime('/' . $file);
						if ($mtime < $now) {
							$storage->unlink('/' . $file);
						}
					} catch (\OCP\Lock\LockedException $e) {
						// ignore locked chunks
						\OCP\Server::get(LoggerInterface::class)->debug('Could not cleanup locked chunk "' . $file . '"', ['app' => 'core']);
					} catch (\OCP\Files\ForbiddenException $e) {
						\OCP\Server::get(LoggerInterface::class)->debug('Could not cleanup forbidden chunk "' . $file . '"', ['app' => 'core']);
					} catch (\OCP\Files\LockNotAcquiredException $e) {
						\OCP\Server::get(LoggerInterface::class)->debug('Could not cleanup locked chunk "' . $file . '"', ['app' => 'core']);
					}
				}
			}
		}
	}

	public static function isAvailable(): bool {
		return true;
	}
}
an class="s2">"Dom.", "Mon." : "Lun.", "Tue." : "Mar.", "Wed." : "Mie.", "Thu." : "Jue.", "Fri." : "Vie.", "Sat." : "Sab.", "Su" : "Do", "Mo" : "Lu", "Tu" : "Ma", "We" : "Mi", "Th" : "Ju", "Fr" : "Vi", "Sa" : "Sa", "January" : "Enero", "February" : "Febrero", "March" : "Marzo", "April" : "Abril", "May" : "Mayo", "June" : "Junio", "July" : "Julio", "August" : "Agosto", "September" : "Septiembre", "October" : "Octubre", "November" : "Noviembre", "December" : "Diciembre", "Jan." : "Ene.", "Feb." : "Feb.", "Mar." : "Mar.", "Apr." : "Abr.", "May." : "May.", "Jun." : "Jun.", "Jul." : "Jul.", "Aug." : "Ago.", "Sep." : "Sep.", "Oct." : "Oct.", "Nov." : "Nov.", "Dec." : "Dic.", "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Sólo se permiten los siguientes caracteres en el nombre de usuario: \"a-z\", \"A-Z\", \"0-9\" y \"_.@-'\"", "A valid username must be provided" : "Se debe proporcionar un nombre de usuario válido", "Username contains whitespace at the beginning or at the end" : "El nombre del usuario contiene un espacio en blanco al inicio o al final", "Username must not consist of dots only" : "El nombre de usuario no debe consistir de solo puntos. ", "A valid password must be provided" : "Se debe proporcionar una contraseña válida", "The username is already being used" : "Ese nombre de usuario ya está en uso", "User disabled" : "Usuario deshabilitado", "Login canceled by app" : "Inicio de sesión cancelado por la aplicación", "a safe home for all your data" : "un lugar seguro para todos sus datos", "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, favor de intentarlo más tarde. ", "Can't read file" : "No se puede leer el archivo", "Application is not enabled" : "La aplicación está deshabilitada", "Authentication error" : "Error de autenticación", "Token expired. Please reload page." : "La ficha ha expirado. Favor de recarga la página.", "No database drivers (sqlite, mysql, or postgresql) installed." : "No cuenta con controladores de base de datos (sqlite, mysql o postgresql) instalados. ", "Cannot write into \"config\" directory" : "No fue posible escribir en el directorio \"config\"", "Cannot write into \"apps\" directory" : "No fue posible escribir en el directorio \"apps\"", "This can usually be fixed by giving the webserver write access to the apps directory or disabling the appstore in the config file. See %s" : "Por lo general esto se puede resolver al darle al servidor web acceso de escritura al directorio de las aplicaciones o deshabilitando la appstore en el archivo config. Favor de ver %s", "Cannot create \"data\" directory" : "No fue posible crear el directorio \"data\"", "This can usually be fixed by giving the webserver write access to the root directory. See %s" : "Por lo general esto se puede resolver al darle al servidor web acceso de escritura al directorio raíz. Favor de ver %s", "Permissions can usually be fixed by giving the webserver write access to the root directory. See %s." : "Por lo general los permisos se pueden corregir al darle al servidor web acceso de escritura al directorio raíz. Favor de ver %s.", "Setting locale to %s failed" : "Se presentó una falla al establecer la regionalización a %s", "Please install one of these locales on your system and restart your webserver." : "Favor de instalar uno de las siguientes configuraciones locales en su sistema y reinicie su servidor web", "Please ask your server administrator to install the module." : "Favor de solicitar a su adminsitrador la instalación del módulo. ", "PHP module %s not installed." : "El módulo de PHP %s no está instalado. ", "PHP setting \"%s\" is not set to \"%s\"." : "El ajuste PHP \"%s\" no esta establecido a \"%s\".", "Adjusting this setting in php.ini will make Nextcloud run again" : "El cambiar este ajuste del archivo php.ini hará que Nextcloud corra de nuevo.", "mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload está establecido como \"%s\" en lugar del valor esperado de \"0\"", "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Para corregir este tema, establezca <code>mbstring.func_overload</code> a <code>0</code> en su archivo php.ini", "libxml2 2.7.0 is at least required. Currently %s is installed." : "Se requiere de por lo menos libxml2 2.7.0. Actualmente %s esta instalado. ", "To fix this issue update your libxml2 version and restart your web server." : "Para corregir este tema, favor de actualizar la versión de su libxml2 y reinicie su servidor web. ", "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "Al parecer PHP está configurado para quitar los bloques de comentarios internos. Esto hará que varias aplicaciones principales sean inaccesibles. ", "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Esto ha sido causado probablemente por un acelerador de caché como Zend OPcache o eAccelerator.", "PHP modules have been installed, but they are still listed as missing?" : "¿Los módulos de PHP han sido instalados, pero se siguen enlistando como faltantes?", "Please ask your server administrator to restart the web server." : "Favor de solicitar al administrador reiniciar el servidor web. ", "PostgreSQL >= 9 required" : "Se requiere PostgreSQL >= 9", "Please upgrade your database version" : "Favor de actualizar la versión de la base de datos", "Please change the permissions to 0770 so that the directory cannot be listed by other users." : "Favor de cambiar los permisos a 0770 para que el directorio no pueda ser enlistado por otros usuarios. ", "Your data directory is readable by other users" : "Su direcctorio data puede ser leído por otros usuarios", "Your data directory must be an absolute path" : "Su direcctorio data debe ser una ruta absoluta", "Check the value of \"datadirectory\" in your configuration" : "Verifique el valor de \"datadirectory\" en su configuración", "Your data directory is invalid" : "Su directorio de datos es inválido", "Could not obtain lock type %d on \"%s\"." : "No fue posible obtener el tipo de bloqueo %d en \"%s\". ", "Storage unauthorized. %s" : "Almacenamiento no autorizado. %s", "Storage incomplete configuration. %s" : "Configuración incompleta del almacenamiento. %s", "Storage connection error. %s" : "Se presentó un error con la conexión al almacenamiento. %s", "Storage is temporarily not available" : "El almacenamieto se encuentra temporalmente no disponible", "Storage connection timeout. %s" : "Se agotó el tiempo de conexión del almacenamiento. %s", "Sharing %s failed, because the backend does not allow shares from type %i" : "Se presentó una falla al compartir %s, porque el backend no permite elementos compartidos de tipo %i", "Sharing %s failed, because the file does not exist" : "Se presentó una falla al compartir %s porque el archivo no existe", "Sharing %s failed, because you can not share with yourself" : "Se presento una falla al compartir %s, porque no puede compartir con usted mismo", "You need to provide a password to create a public link, only protected links are allowed" : "Usted necesita proporcionar una contraseña para crear un link público, sólo los links protegidos están permitidos. ", "Sharing %s failed, because sharing with links is not allowed" : "Se presentó una falla al compartir %s porque no está permitido compartir con links", "Not allowed to create a federated share with the same user" : "No está permitido crear un elemento compartido federado con el mismo usuario", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "No ha sido posible establecer la fecha de expiración. Los recursos compartidos no pueden expirar después de %s tras haber sido compartidos", "Cannot set expiration date. Expiration date is in the past" : "No ha sido posible establecer la fecha de expiración. La fecha de expiración ya ha pasado", "Sharing failed, because the user %s is the original sharer" : "Se presento una falla al compartir, porque el usuario %s es quien compartió originalmente", "Sharing %s failed, because resharing is not allowed" : "Falla al compartir %s debído a que no se permite volver a compartir", "Sharing %s failed, because the file could not be found in the file cache" : "Se presentó una falla al compartir %s porque el archivo no se encontró en el caché de archivos" }, "nplurals=2; plural=(n != 1);");