summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/cache/file.php16
-rw-r--r--lib/db.php403
-rw-r--r--lib/db/adapter.php72
-rw-r--r--lib/db/adapteroci8.php28
-rw-r--r--lib/db/adapterpgsql.php23
-rw-r--r--lib/db/adaptersqlite.php60
-rw-r--r--lib/db/adaptersqlsrv.php28
-rw-r--r--lib/db/connection.php197
-rw-r--r--lib/db/mdb2schemamanager.php8
-rw-r--r--lib/db/statementwrapper.php4
-rw-r--r--lib/group.php2
-rw-r--r--lib/l10n.php168
-rw-r--r--lib/l10n/af_ZA.php4
-rw-r--r--lib/l10n/ar.php4
-rw-r--r--lib/l10n/bg_BG.php4
-rw-r--r--lib/l10n/bn_BD.php4
-rw-r--r--lib/l10n/ca.php4
-rw-r--r--lib/l10n/cs_CZ.php38
-rw-r--r--lib/l10n/cy_GB.php4
-rw-r--r--lib/l10n/da.php4
-rw-r--r--lib/l10n/de.php4
-rw-r--r--lib/l10n/de_CH.php59
-rw-r--r--lib/l10n/de_DE.php4
-rw-r--r--lib/l10n/el.php8
-rw-r--r--lib/l10n/en@pirate.php4
-rw-r--r--lib/l10n/eo.php4
-rw-r--r--lib/l10n/es.php4
-rw-r--r--lib/l10n/es_AR.php4
-rw-r--r--lib/l10n/et_EE.php4
-rw-r--r--lib/l10n/eu.php4
-rw-r--r--lib/l10n/fa.php4
-rw-r--r--lib/l10n/fi.php4
-rw-r--r--lib/l10n/fi_FI.php4
-rw-r--r--lib/l10n/fr.php4
-rw-r--r--lib/l10n/gl.php4
-rw-r--r--lib/l10n/he.php4
-rw-r--r--lib/l10n/hi.php4
-rw-r--r--lib/l10n/hr.php4
-rw-r--r--lib/l10n/hu_HU.php4
-rw-r--r--lib/l10n/ia.php4
-rw-r--r--lib/l10n/id.php4
-rw-r--r--lib/l10n/is.php4
-rw-r--r--lib/l10n/it.php4
-rw-r--r--lib/l10n/ja_JP.php8
-rw-r--r--lib/l10n/ka.php4
-rw-r--r--lib/l10n/ka_GE.php4
-rw-r--r--lib/l10n/ko.php4
-rw-r--r--lib/l10n/ku_IQ.php4
-rw-r--r--lib/l10n/lb.php4
-rw-r--r--lib/l10n/lt_LT.php4
-rw-r--r--lib/l10n/lv.php4
-rw-r--r--lib/l10n/mk.php4
-rw-r--r--lib/l10n/ms_MY.php4
-rw-r--r--lib/l10n/my_MM.php4
-rw-r--r--lib/l10n/nb_NO.php4
-rw-r--r--lib/l10n/nl.php4
-rw-r--r--lib/l10n/nn_NO.php4
-rw-r--r--lib/l10n/oc.php4
-rw-r--r--lib/l10n/pl.php4
-rw-r--r--lib/l10n/pl_PL.php4
-rw-r--r--lib/l10n/pt_BR.php4
-rw-r--r--lib/l10n/pt_PT.php4
-rw-r--r--lib/l10n/ro.php4
-rw-r--r--lib/l10n/ru.php4
-rw-r--r--lib/l10n/ru_RU.php4
-rw-r--r--lib/l10n/si_LK.php4
-rw-r--r--lib/l10n/sk_SK.php8
-rw-r--r--lib/l10n/sl.php4
-rw-r--r--lib/l10n/sq.php4
-rw-r--r--lib/l10n/sr.php4
-rw-r--r--lib/l10n/sr@latin.php4
-rw-r--r--lib/l10n/string.php39
-rw-r--r--lib/l10n/sv.php4
-rw-r--r--lib/l10n/ta_LK.php4
-rw-r--r--lib/l10n/te.php4
-rw-r--r--lib/l10n/th_TH.php4
-rw-r--r--lib/l10n/tr.php4
-rw-r--r--lib/l10n/ug.php4
-rw-r--r--lib/l10n/uk.php4
-rw-r--r--lib/l10n/ur_PK.php4
-rw-r--r--lib/l10n/vi.php4
-rw-r--r--lib/l10n/zh_CN.GB2312.php4
-rw-r--r--lib/l10n/zh_CN.php4
-rw-r--r--lib/l10n/zh_HK.php4
-rw-r--r--lib/l10n/zh_TW.php4
-rw-r--r--lib/user.php1
86 files changed, 1000 insertions, 438 deletions
diff --git a/lib/cache/file.php b/lib/cache/file.php
index 531e1d50f40..ba3dedaf8f3 100644
--- a/lib/cache/file.php
+++ b/lib/cache/file.php
@@ -29,22 +29,30 @@ class OC_Cache_File{
}
public function get($key) {
+ $result = null;
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
if ($this->hasKey($key)) {
$storage = $this->getStorage();
- return $storage->file_get_contents($key);
+ $result = $storage->file_get_contents($key);
}
- return null;
+ \OC_FileProxy::$enabled = $proxyStatus;
+ return $result;
}
public function set($key, $value, $ttl=0) {
$storage = $this->getStorage();
+ $result = false;
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
if ($storage and $storage->file_put_contents($key, $value)) {
if ($ttl === 0) {
$ttl = 86400; // 60*60*24
}
- return $storage->touch($key, time() + $ttl);
+ $result = $storage->touch($key, time() + $ttl);
}
- return false;
+ \OC_FileProxy::$enabled = $proxyStatus;
+ return $result;
}
public function hasKey($key) {
diff --git a/lib/db.php b/lib/db.php
index a96f4697235..ebd012c72f8 100644
--- a/lib/db.php
+++ b/lib/db.php
@@ -41,68 +41,25 @@ class DatabaseException extends Exception {
* Doctrine with some adaptions.
*/
class OC_DB {
- const BACKEND_DOCTRINE=2;
-
- static private $preparedQueries = array();
- static private $cachingEnabled = true;
-
/**
- * @var \Doctrine\DBAL\Connection
+ * @var \OC\DB\Connection $connection
*/
- static private $connection; //the preferred connection to use, only Doctrine
- static private $backend=null;
- /**
- * @var \Doctrine\DBAL\Connection
- */
- static private $DOCTRINE=null;
+ static private $connection; //the prefered connection to use, only Doctrine
static private $prefix=null;
static private $type=null;
/**
- * check which backend we should use
- * @return int BACKEND_DOCTRINE
- */
- private static function getDBBackend() {
- return self::BACKEND_DOCTRINE;
- }
-
- /**
* @brief connects to the database
- * @param int $backend
* @return bool true if connection can be established or false on error
*
* Connects to the database as specified in config.php
*/
- public static function connect($backend=null) {
+ public static function connect() {
if(self::$connection) {
return true;
}
- if(is_null($backend)) {
- $backend=self::getDBBackend();
- }
- if($backend==self::BACKEND_DOCTRINE) {
- $success = self::connectDoctrine();
- self::$connection=self::$DOCTRINE;
- self::$backend=self::BACKEND_DOCTRINE;
- }
- return $success;
- }
- /**
- * connect to the database using doctrine
- *
- * @return bool
- */
- public static function connectDoctrine() {
- if(self::$connection) {
- if(self::$backend!=self::BACKEND_DOCTRINE) {
- self::disconnect();
- } else {
- return true;
- }
- }
- self::$preparedQueries = array();
// The global data we need
$name = OC_Config::getValue( "dbname", "owncloud" );
$host = OC_Config::getValue( "dbhost", "" );
@@ -116,7 +73,7 @@ class OC_DB {
}
// do nothing if the connection already has been established
- if(!self::$DOCTRINE) {
+ if (!self::$connection) {
$config = new \Doctrine\DBAL\Configuration();
switch($type) {
case 'sqlite':
@@ -128,6 +85,7 @@ class OC_DB {
'path' => $datadir.'/'.$name.'.db',
'driver' => 'pdo_sqlite',
);
+ $connectionParams['adapter'] = '\OC\DB\AdapterSqlite';
break;
case 'mysql':
$connectionParams = array(
@@ -139,6 +97,7 @@ class OC_DB {
'charset' => 'UTF8',
'driver' => 'pdo_mysql',
);
+ $connectionParams['adapter'] = '\OC\DB\Adapter';
break;
case 'pgsql':
$connectionParams = array(
@@ -149,6 +108,7 @@ class OC_DB {
'dbname' => $name,
'driver' => 'pdo_pgsql',
);
+ $connectionParams['adapter'] = '\OC\DB\AdapterPgSql';
break;
case 'oci':
$connectionParams = array(
@@ -162,6 +122,7 @@ class OC_DB {
if (!empty($port)) {
$connectionParams['port'] = $port;
}
+ $connectionParams['adapter'] = '\OC\DB\AdapterOCI8';
break;
case 'mssql':
$connectionParams = array(
@@ -173,12 +134,20 @@ class OC_DB {
'charset' => 'UTF8',
'driver' => 'pdo_sqlsrv',
);
+ $connectionParams['adapter'] = '\OC\DB\AdapterSQLSrv';
break;
default:
return false;
}
+ $connectionParams['wrapperClass'] = 'OC\DB\Connection';
+ $connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_' );
try {
- self::$DOCTRINE = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
+ self::$connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
+ if ($type === 'sqlite' || $type === 'sqlite3') {
+ // Sqlite doesn't handle query caching and schema changes
+ // TODO: find a better way to handle this
+ self::$connection->disableQueryStatementCaching();
+ }
} catch(\Doctrine\DBAL\DBALException $e) {
OC_Log::write('core', $e->getMessage(), OC_Log::FATAL);
OC_User::setUserId(null);
@@ -194,12 +163,9 @@ class OC_DB {
}
/**
- * get the database connection object
- *
- * @return \Doctrine\DBAL\Connection
+ * @return \OC\DB\Connection
*/
- private static function getConnection()
- {
+ static public function getConnection() {
self::connect();
return self::$connection;
}
@@ -226,25 +192,6 @@ class OC_DB {
* SQL query via Doctrine prepare(), needs to be execute()'d!
*/
static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) {
-
- if (!is_null($limit) && $limit != -1) {
- if ($limit === -1) {
- $limit = null;
- }
- $platform = self::$connection->getDatabasePlatform();
- $query = $platform->modifyLimitQuery($query, $limit, $offset);
- } else {
- if (isset(self::$preparedQueries[$query]) and self::$cachingEnabled) {
- return self::$preparedQueries[$query];
- }
- }
- $rawQuery = $query;
-
- // Optimize the query
- $query = self::processQuery( $query );
- if(OC_Config::getValue( "log_query", false)) {
- OC_Log::write('core', 'DB prepare : '.$query, OC_Log::DEBUG);
- }
self::connect();
if ($isManipulation === null) {
@@ -253,45 +200,38 @@ class OC_DB {
}
// return the result
- if (self::$backend == self::BACKEND_DOCTRINE) {
- try {
- $result=self::$connection->prepare($query);
- } catch(\Doctrine\DBAL\DBALException $e) {
- throw new \DatabaseException($e->getMessage(), $query);
- }
- // differentiate between query and manipulation
- $result=new OC_DB_StatementWrapper($result, $isManipulation);
- }
- if ((is_null($limit) || $limit == -1) and self::$cachingEnabled ) {
- $type = OC_Config::getValue( "dbtype", "sqlite" );
- if( $type != 'sqlite' && $type != 'sqlite3' ) {
- self::$preparedQueries[$rawQuery] = $result;
- }
+ try {
+ $result = self::$connection->prepare($query, $limit, $offset);
+ } catch (\Doctrine\DBAL\DBALException $e) {
+ throw new \DatabaseException($e->getMessage(), $query);
}
+ // differentiate between query and manipulation
+ $result = new OC_DB_StatementWrapper($result, $isManipulation);
return $result;
}
-
+
/**
* tries to guess the type of statement based on the first 10 characters
* the current check allows some whitespace but does not work with IF EXISTS or other more complex statements
*
* @param string $sql
+ * @return bool
*/
static public function isManipulation( $sql ) {
- $selectOccurence = stripos ($sql, "SELECT");
- if ($selectOccurence !== false && $selectOccurence < 10) {
+ $selectOccurrence = stripos($sql, 'SELECT');
+ if ($selectOccurrence !== false && $selectOccurrence < 10) {
return false;
}
- $insertOccurence = stripos ($sql, "INSERT");
- if ($insertOccurence !== false && $insertOccurence < 10) {
+ $insertOccurrence = stripos($sql, 'INSERT');
+ if ($insertOccurrence !== false && $insertOccurrence < 10) {
return true;
}
- $updateOccurence = stripos ($sql, "UPDATE");
- if ($updateOccurence !== false && $updateOccurence < 10) {
+ $updateOccurrence = stripos($sql, 'UPDATE');
+ if ($updateOccurrence !== false && $updateOccurrence < 10) {
return true;
}
- $deleteOccurance = stripos ($sql, "DELETE");
- if ($deleteOccurance !== false && $deleteOccurance < 10) {
+ $deleteOccurrence = stripos($sql, 'DELETE');
+ if ($deleteOccurrence !== false && $deleteOccurrence < 10) {
return true;
}
return false;
@@ -309,7 +249,7 @@ class OC_DB {
static public function executeAudited( $stmt, array $parameters = null) {
if (is_string($stmt)) {
// convert to an array with 'sql'
- if (stripos($stmt,'LIMIT') !== false) { //OFFSET requires LIMIT, se we only neet to check for LIMIT
+ if (stripos($stmt, 'LIMIT') !== false) { //OFFSET requires LIMIT, so we only need to check for LIMIT
// TODO try to convert LIMIT OFFSET notation to parameters, see fixLimitClauseForMSSQL
$message = 'LIMIT and OFFSET are forbidden for portability reasons,'
. ' pass an array with \'limit\' and \'offset\' instead';
@@ -317,7 +257,7 @@ class OC_DB {
}
$stmt = array('sql' => $stmt, 'limit' => null, 'offset' => null);
}
- if (is_array($stmt)){
+ if (is_array($stmt)) {
// convert to prepared statement
if ( ! array_key_exists('sql', $stmt) ) {
$message = 'statement array must at least contain key \'sql\'';
@@ -359,55 +299,49 @@ class OC_DB {
*/
public static function insertid($table=null) {
self::connect();
- $type = OC_Config::getValue( "dbtype", "sqlite" );
- if( $type === 'pgsql' ) {
- $result = self::executeAudited('SELECT lastval() AS id');
- $row = $result->fetchRow();
- self::raiseExceptionOnError($row, 'fetching row for insertid failed');
- return (int)$row['id'];
- } else if( $type === 'mssql') {
- if($table !== null) {
- $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
- $table = str_replace( '*PREFIX*', $prefix, $table );
- }
- return self::$connection->lastInsertId($table);
- }
- if( $type === 'oci' ) {
- if($table !== null) {
- $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
- $suffix = '_SEQ';
- $table = '"'.str_replace( '*PREFIX*', $prefix, $table ).$suffix.'"';
- }
- return self::$connection->lastInsertId($table);
- } else {
- if($table !== null) {
- $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
- $suffix = OC_Config::getValue( "dbsequencesuffix", "_id_seq" );
- $table = str_replace( '*PREFIX*', $prefix, $table ).$suffix;
- }
- $result = self::$connection->lastInsertId($table);
- }
- self::raiseExceptionOnError($result, 'insertid failed');
- return (int)$result;
+ return self::$connection->lastInsertId($table);
+ }
+
+ /**
+ * @brief Insert a row if a matching row doesn't exists.
+ * @param string $table. The table to insert into in the form '*PREFIX*tableName'
+ * @param array $input. An array of fieldname/value pairs
+ * @return int number of updated rows
+ */
+ public static function insertIfNotExist($table, $input) {
+ self::connect();
+ return self::$connection->insertIfNotExist($table, $input);
+ }
+
+ /**
+ * Start a transaction
+ */
+ public static function beginTransaction() {
+ self::connect();
+ self::$connection->beginTransaction();
+ }
+
+ /**
+ * Commit the database changes done during a transaction that is in progress
+ */
+ public static function commit() {
+ self::connect();
+ self::$connection->commit();
}
/**
* @brief Disconnect
- * @return bool
*
* This is good bye, good bye, yeah!
*/
public static function disconnect() {
// Cut connection if required
if(self::$connection) {
- self::$connection=false;
- self::$DOCTRINE=false;
+ self::$connection->close();
}
-
- return true;
}
- /** else {
+ /**
* @brief saves database schema to xml file
* @param string $file name of file
* @param int $mode
@@ -415,7 +349,7 @@ class OC_DB {
*
* TODO: write more documentation
*/
- public static function getDbStructure( $file, $mode=MDB2_SCHEMA_DUMP_STRUCTURE) {
+ public static function getDbStructure( $file, $mode = 0) {
$schemaManager = self::getMDB2SchemaManager();
return $schemaManager->getDbStructure($file);
}
@@ -451,172 +385,6 @@ class OC_DB {
}
/**
- * @brief Insert a row if a matching row doesn't exists.
- * @param string $table. The table to insert into in the form '*PREFIX*tableName'
- * @param array $input. An array of fieldname/value pairs
- * @returns int number of updated rows
- */
- public static function insertIfNotExist($table, $input) {
- self::connect();
- $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
- $table = str_replace( '*PREFIX*', $prefix, $table );
-
- if(is_null(self::$type)) {
- self::$type=OC_Config::getValue( "dbtype", "sqlite" );
- }
- $type = self::$type;
-
- $query = '';
- $inserts = array_values($input);
- // differences in escaping of table names ('`' for mysql) and getting the current timestamp
- if( $type == 'sqlite' || $type == 'sqlite3' ) {
- // NOTE: For SQLite we have to use this clumsy approach
- // otherwise all fieldnames used must have a unique key.
- $query = 'SELECT * FROM `' . $table . '` WHERE ';
- foreach($input as $key => $value) {
- $query .= '`' . $key . '` = ? AND ';
- }
- $query = substr($query, 0, strlen($query) - 5);
- try {
- $result = self::executeAudited($query, $inserts);
- } catch(DatabaseException $e) {
- OC_Template::printExceptionErrorPage( $e );
- }
-
- if((int)$result->numRows() === 0) {
- $query = 'INSERT INTO `' . $table . '` (`'
- . implode('`,`', array_keys($input)) . '`) VALUES('
- . str_repeat('?,', count($input)-1).'? ' . ')';
- } else {
- return 0; //no rows updated
- }
- } elseif( $type == 'pgsql' || $type == 'oci' || $type == 'mysql' || $type == 'mssql') {
- $query = 'INSERT INTO `' .$table . '` (`'
- . implode('`,`', array_keys($input)) . '`) SELECT '
- . str_repeat('?,', count($input)-1).'? ' // Is there a prettier alternative?
- . 'FROM `' . $table . '` WHERE ';
-
- foreach($input as $key => $value) {
- $query .= '`' . $key . '` = ? AND ';
- }
- $query = substr($query, 0, strlen($query) - 5);
- $query .= ' HAVING COUNT(*) = 0';
- $inserts = array_merge($inserts, $inserts);
- }
-
- try {
- $result = self::executeAudited($query, $inserts);
- } catch(\Doctrine\DBAL\DBALException $e) {
- OC_Template::printExceptionErrorPage( $e );
- }
-
- return $result;
- }
-
- /**
- * @brief does minor changes to query
- * @param string $query Query string
- * @return string corrected query string
- *
- * This function replaces *PREFIX* with the value of $CONFIG_DBTABLEPREFIX
- * and replaces the ` with ' or " according to the database driver.
- */
- private static function processQuery( $query ) {
- self::connect();
- // We need Database type and table prefix
- if(is_null(self::$type)) {
- self::$type=OC_Config::getValue( "dbtype", "sqlite" );
- }
- $type = self::$type;
- if(is_null(self::$prefix)) {
- self::$prefix=OC_Config::getValue( "dbtableprefix", "oc_" );
- }
- $prefix = self::$prefix;
-
- // differences in escaping of table names ('`' for mysql) and getting the current timestamp
- if( $type == 'sqlite' || $type == 'sqlite3' ) {
- $query = str_replace( '`', '"', $query );
- $query = str_ireplace( 'NOW()', 'datetime(\'now\')', $query );
- $query = str_ireplace( 'UNIX_TIMESTAMP()', 'strftime(\'%s\',\'now\')', $query );
- } elseif( $type == 'pgsql' ) {
- $query = str_replace( '`', '"', $query );
- $query = str_ireplace( 'UNIX_TIMESTAMP()', 'cast(extract(epoch from current_timestamp) as integer)',
- $query );
- } elseif( $type == 'oci' ) {
- $query = str_replace( '`', '"', $query );
- $query = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $query );
- $query = str_ireplace( 'UNIX_TIMESTAMP()', "(cast(sys_extract_utc(systimestamp) as date) - date'1970-01-01') * 86400", $query );
- }elseif( $type == 'mssql' ) {
- $query = preg_replace( "/\`(.*?)`/", "[$1]", $query );
- $query = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $query );
- $query = str_replace( 'LENGTH(', 'LEN(', $query );
- $query = str_replace( 'SUBSTR(', 'SUBSTRING(', $query );
- $query = str_ireplace( 'UNIX_TIMESTAMP()', 'DATEDIFF(second,{d \'1970-01-01\'},GETDATE())', $query );
-
- $query = self::fixLimitClauseForMSSQL($query);
- }
-
- // replace table name prefix
- $query = str_replace( '*PREFIX*', $prefix, $query );
-
- return $query;
- }
-
- private static function fixLimitClauseForMSSQL($query) {
- $limitLocation = stripos ($query, "LIMIT");
-
- if ( $limitLocation === false ) {
- return $query;
- }
-
- // total == 0 means all results - not zero results
- //
- // First number is either total or offset, locate it by first space
- //
- $offset = substr ($query, $limitLocation + 5);
- $offset = substr ($offset, 0, stripos ($offset, ' '));
- $offset = trim ($offset);
-
- // check for another parameter
- if (stripos ($offset, ',') === false) {
- // no more parameters
- $offset = 0;
- $total = intval ($offset);
- } else {
- // found another parameter
- $offset = intval ($offset);
-
- $total = substr ($query, $limitLocation + 5);
- $total = substr ($total, stripos ($total, ','));
-
- $total = substr ($total, 0, stripos ($total, ' '));
- $total = intval ($total);
- }
-
- $query = trim (substr ($query, 0, $limitLocation));
-
- if ($offset == 0 && $total !== 0) {
- if (strpos($query, "SELECT") === false) {
- $query = "TOP {$total} " . $query;
- } else {
- $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP '.$total, $query);
- }
- } else if ($offset > 0) {
- $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP(10000000) ', $query);
- $query = 'SELECT *
- FROM (SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3
- FROM (SELECT 1 AS line2, sub1.* FROM (' . $query . ') AS sub1) as sub2) AS sub3';
-
- if ($total > 0) {
- $query .= ' WHERE line3 BETWEEN ' . ($offset + 1) . ' AND ' . ($offset + $total);
- } else {
- $query .= ' WHERE line3 > ' . $offset;
- }
- }
- return $query;
- }
-
- /**
* @brief drop a table
* @param string $tableName the table to drop
*/
@@ -644,22 +412,6 @@ class OC_DB {
}
/**
- * Start a transaction
- */
- public static function beginTransaction() {
- self::connect();
- self::$connection->beginTransaction();
- }
-
- /**
- * Commit the database changes done during a transaction that is in progress
- */
- public static function commit() {
- self::connect();
- self::$connection->commit();
- }
-
- /**
* check if a result is an error, works with Doctrine
* @param mixed $result
* @return bool
@@ -697,17 +449,9 @@ class OC_DB {
* @return string
*/
public static function getErrorMessage($error) {
- if (self::$backend==self::BACKEND_DOCTRINE and self::$DOCTRINE) {
- $msg = self::$DOCTRINE->errorCode() . ': ';
- $errorInfo = self::$DOCTRINE->errorInfo();
- if (is_array($errorInfo)) {
- $msg .= 'SQLSTATE = '.$errorInfo[0] . ', ';
- $msg .= 'Driver Code = '.$errorInfo[1] . ', ';
- $msg .= 'Driver Message = '.$errorInfo[2];
- }
- return $msg;
+ if (self::$connection) {
+ return self::$connection->getError();
}
-
return '';
}
@@ -715,9 +459,10 @@ class OC_DB {
* @param bool $enabled
*/
static public function enableCaching($enabled) {
- if (!$enabled) {
- self::$preparedQueries = array();
+ if ($enabled) {
+ self::$connection->enableQueryStatementCaching();
+ } else {
+ self::$connection->disableQueryStatementCaching();
}
- self::$cachingEnabled = $enabled;
}
}
diff --git a/lib/db/adapter.php b/lib/db/adapter.php
new file mode 100644
index 00000000000..6b31f37dd98
--- /dev/null
+++ b/lib/db/adapter.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\DB;
+
+/**
+ * This handles the way we use to write queries, into something that can be
+ * handled by the database abstraction layer.
+ */
+class Adapter {
+
+ /**
+ * @var \OC\DB\Connection $conn
+ */
+ protected $conn;
+
+ public function __construct($conn) {
+ $this->conn = $conn;
+ }
+
+ /**
+ * @param string $table name
+ * @return int id of last insert statement
+ */
+ public function lastInsertId($table) {
+ return $this->conn->realLastInsertId($table);
+ }
+
+ /**
+ * @param string $statement that needs to be changed so the db can handle it
+ * @return string changed statement
+ */
+ public function fixupStatement($statement) {
+ return $statement;
+ }
+
+ /**
+ * @brief insert the @input values when they do not exist yet
+ * @param string $table name
+ * @param array $input key->value pairs
+ * @return int count of inserted rows
+ */
+ public function insertIfNotExist($table, $input) {
+ $query = 'INSERT INTO `' .$table . '` (`'
+ . implode('`,`', array_keys($input)) . '`) SELECT '
+ . str_repeat('?,', count($input)-1).'? ' // Is there a prettier alternative?
+ . 'FROM `' . $table . '` WHERE ';
+
+ foreach($input as $key => $value) {
+ $query .= '`' . $key . '` = ? AND ';
+ }
+ $query = substr($query, 0, strlen($query) - 5);
+ $query .= ' HAVING COUNT(*) = 0';
+ $inserts = array_values($input);
+ $inserts = array_merge($inserts, $inserts);
+
+ try {
+ return $this->conn->executeUpdate($query, $inserts);
+ } catch(\Doctrine\DBAL\DBALException $e) {
+ $entry = 'DB Error: "'.$e->getMessage() . '"<br />';
+ $entry .= 'Offending command was: ' . $query.'<br />';
+ \OC_Log::write('core', $entry, \OC_Log::FATAL);
+ error_log('DB error: ' . $entry);
+ \OC_Template::printErrorPage( $entry );
+ }
+ }
+}
diff --git a/lib/db/adapteroci8.php b/lib/db/adapteroci8.php
new file mode 100644
index 00000000000..bc226e979ec
--- /dev/null
+++ b/lib/db/adapteroci8.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+
+namespace OC\DB;
+
+class AdapterOCI8 extends Adapter {
+ public function lastInsertId($table) {
+ if($table !== null) {
+ $suffix = '_SEQ';
+ $table = '"'.$table.$suffix.'"';
+ }
+ return $this->conn->realLastInsertId($table);
+ }
+
+ const UNIX_TIMESTAMP_REPLACEMENT = "(cast(sys_extract_utc(systimestamp) as date) - date'1970-01-01') * 86400";
+ public function fixupStatement($statement) {
+ $statement = str_replace( '`', '"', $statement );
+ $statement = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $statement );
+ $statement = str_ireplace( 'UNIX_TIMESTAMP()', self::UNIX_TIMESTAMP_REPLACEMENT, $statement );
+ return $statement;
+ }
+}
diff --git a/lib/db/adapterpgsql.php b/lib/db/adapterpgsql.php
new file mode 100644
index 00000000000..990d71c9f29
--- /dev/null
+++ b/lib/db/adapterpgsql.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+
+namespace OC\DB;
+
+class AdapterPgSql extends Adapter {
+ public function lastInsertId($table) {
+ return $this->conn->fetchColumn('SELECT lastval()');
+ }
+
+ const UNIX_TIMESTAMP_REPLACEMENT = 'cast(extract(epoch from current_timestamp) as integer)';
+ public function fixupStatement($statement) {
+ $statement = str_replace( '`', '"', $statement );
+ $statement = str_ireplace( 'UNIX_TIMESTAMP()', self::UNIX_TIMESTAMP_REPLACEMENT, $statement );
+ return $statement;
+ }
+}
diff --git a/lib/db/adaptersqlite.php b/lib/db/adaptersqlite.php
new file mode 100644
index 00000000000..fa6d308ae32
--- /dev/null
+++ b/lib/db/adaptersqlite.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+
+namespace OC\DB;
+
+class AdapterSqlite extends Adapter {
+ public function fixupStatement($statement) {
+ $statement = str_replace( '`', '"', $statement );
+ $statement = str_ireplace( 'NOW()', 'datetime(\'now\')', $statement );
+ $statement = str_ireplace( 'UNIX_TIMESTAMP()', 'strftime(\'%s\',\'now\')', $statement );
+ return $statement;
+ }
+
+ public function insertIfNotExist($table, $input) {
+ // NOTE: For SQLite we have to use this clumsy approach
+ // otherwise all fieldnames used must have a unique key.
+ $query = 'SELECT COUNT(*) FROM `' . $table . '` WHERE ';
+ foreach($input as $key => $value) {
+ $query .= '`' . $key . '` = ? AND ';
+ }
+ $query = substr($query, 0, strlen($query) - 5);
+ try {
+ $stmt = $this->conn->prepare($query);
+ $result = $stmt->execute(array_values($input));
+ } catch(\Doctrine\DBAL\DBALException $e) {
+ $entry = 'DB Error: "'.$e->getMessage() . '"<br />';
+ $entry .= 'Offending command was: ' . $query . '<br />';
+ \OC_Log::write('core', $entry, \OC_Log::FATAL);
+ error_log('DB error: '.$entry);
+ \OC_Template::printErrorPage( $entry );
+ }
+
+ if ($stmt->fetchColumn() === '0') {
+ $query = 'INSERT INTO `' . $table . '` (`'
+ . implode('`,`', array_keys($input)) . '`) VALUES('
+ . str_repeat('?,', count($input)-1).'? ' . ')';
+ } else {
+ return 0; //no rows updated
+ }
+
+ try {
+ $statement = $this->conn->prepare($query);
+ $result = $statement->execute(array_values($input));
+ } catch(\Doctrine\DBAL\DBALException $e) {
+ $entry = 'DB Error: "'.$e->getMessage() . '"<br />';
+ $entry .= 'Offending command was: ' . $query.'<br />';
+ \OC_Log::write('core', $entry, \OC_Log::FATAL);
+ error_log('DB error: ' . $entry);
+ \OC_Template::printErrorPage( $entry );
+ }
+
+ return $result;
+ }
+}
diff --git a/lib/db/adaptersqlsrv.php b/lib/db/adaptersqlsrv.php
new file mode 100644
index 00000000000..d0a67af28a7
--- /dev/null
+++ b/lib/db/adaptersqlsrv.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+
+namespace OC\DB;
+
+class AdapterSQLSrv extends Adapter {
+ public function lastInsertId($table) {
+ if($table !== null) {
+ $table = $this->conn->replaceTablePrefix( $table );
+ }
+ return $this->conn->lastInsertId($table);
+ }
+
+ public function fixupStatement($statement) {
+ $statement = preg_replace( "/\`(.*?)`/", "[$1]", $statement );
+ $statement = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $statement );
+ $statement = str_replace( 'LENGTH(', 'LEN(', $statement );
+ $statement = str_replace( 'SUBSTR(', 'SUBSTRING(', $statement );
+ $statement = str_ireplace( 'UNIX_TIMESTAMP()', 'DATEDIFF(second,{d \'1970-01-01\'},GETDATE())', $statement );
+ return $statement;
+ }
+}
diff --git a/lib/db/connection.php b/lib/db/connection.php
new file mode 100644
index 00000000000..2581969dbd0
--- /dev/null
+++ b/lib/db/connection.php
@@ -0,0 +1,197 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\DB;
+use Doctrine\DBAL\Driver;
+use Doctrine\DBAL\Configuration;
+use Doctrine\DBAL\Cache\QueryCacheProfile;
+use Doctrine\Common\EventManager;
+
+class Connection extends \Doctrine\DBAL\Connection {
+ /**
+ * @var string $tablePrefix
+ */
+ protected $tablePrefix;
+
+ /**
+ * @var \OC\DB\Adapter $adapter
+ */
+ protected $adapter;
+
+ /**
+ * @var \Doctrine\DBAL\Driver\Statement[] $preparedQueries
+ */
+ protected $preparedQueries = array();
+
+ protected $cachingQueryStatementEnabled = true;
+
+ /**
+ * Initializes a new instance of the Connection class.
+ *
+ * @param array $params The connection parameters.
+ * @param \Doctrine\DBAL\Driver $driver
+ * @param \Doctrine\DBAL\Configuration $config
+ * @param \Doctrine\Common\EventManager $eventManager
+ * @throws \Exception
+ */
+ public function __construct(array $params, Driver $driver, Configuration $config = null,
+ EventManager $eventManager = null)
+ {
+ if (!isset($params['adapter'])) {
+ throw new \Exception('adapter not set');
+ }
+ if (!isset($params['tablePrefix'])) {
+ throw new \Exception('tablePrefix not set');
+ }
+ parent::__construct($params, $driver, $config, $eventManager);
+ $this->adapter = new $params['adapter']($this);
+ $this->tablePrefix = $params['tablePrefix'];
+ }
+
+ /**
+ * Prepares an SQL statement.
+ *
+ * @param string $statement The SQL statement to prepare.
+ * @param int $limit
+ * @param int $offset
+ * @return \Doctrine\DBAL\Driver\Statement The prepared statement.
+ */
+ public function prepare( $statement, $limit=null, $offset=null ) {
+ if ($limit === -1) {
+ $limit = null;
+ }
+ if (!is_null($limit)) {
+ $platform = $this->getDatabasePlatform();
+ $statement = $platform->modifyLimitQuery($statement, $limit, $offset);
+ } else {
+ if (isset($this->preparedQueries[$statement]) && $this->cachingQueryStatementEnabled) {
+ return $this->preparedQueries[$statement];
+ }
+ $origStatement = $statement;
+ }
+ $statement = $this->replaceTablePrefix($statement);
+ $statement = $this->adapter->fixupStatement($statement);
+
+ if(\OC_Config::getValue( 'log_query', false)) {
+ \OC_Log::write('core', 'DB prepare : '.$statement, \OC_Log::DEBUG);
+ }
+ $result = parent::prepare($statement);
+ if (is_null($limit) && $this->cachingQueryStatementEnabled) {
+ $this->preparedQueries[$origStatement] = $result;
+ }
+ return $result;
+ }
+
+ /**
+ * Executes an, optionally parameterized, SQL query.
+ *
+ * If the query is parameterized, a prepared statement is used.
+ * If an SQLLogger is configured, the execution is logged.
+ *
+ * @param string $query The SQL query to execute.
+ * @param array $params The parameters to bind to the query, if any.
+ * @param array $types The types the previous parameters are in.
+ * @param QueryCacheProfile $qcp
+ * @return \Doctrine\DBAL\Driver\Statement The executed statement.
+ * @internal PERF: Directly prepares a driver statement, not a wrapper.
+ */
+ public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
+ {
+ $query = $this->replaceTablePrefix($query);
+ $query = $this->adapter->fixupStatement($query);
+ return parent::executeQuery($query, $params, $types, $qcp);
+ }
+
+ /**
+ * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
+ * and returns the number of affected rows.
+ *
+ * This method supports PDO binding types as well as DBAL mapping types.
+ *
+ * @param string $query The SQL query.
+ * @param array $params The query parameters.
+ * @param array $types The parameter types.
+ * @return integer The number of affected rows.
+ * @internal PERF: Directly prepares a driver statement, not a wrapper.
+ */
+ public function executeUpdate($query, array $params = array(), array $types = array())
+ {
+ $query = $this->replaceTablePrefix($query);
+ $query = $this->adapter->fixupStatement($query);
+ return parent::executeUpdate($query, $params, $types);
+ }
+
+ /**
+ * Returns the ID of the last inserted row, or the last value from a sequence object,
+ * depending on the underlying driver.
+ *
+ * Note: This method may not return a meaningful or consistent result across different drivers,
+ * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
+ * columns or sequences.
+ *
+ * @param string $seqName Name of the sequence object from which the ID should be returned.
+ * @return string A string representation of the last inserted ID.
+ */
+ public function lastInsertId($seqName = null)
+ {
+ if ($seqName) {
+ $seqName = $this->replaceTablePrefix($seqName);
+ }
+ return $this->adapter->lastInsertId($seqName);
+ }
+
+ // internal use
+ public function realLastInsertId($seqName = null)
+ {
+ return parent::lastInsertId($seqName);
+ }
+
+ /**
+ * @brief Insert a row if a matching row doesn't exists.
+ * @param string $table. The table to insert into in the form '*PREFIX*tableName'
+ * @param array $input. An array of fieldname/value pairs
+ * @return bool The return value from execute()
+ */
+ public function insertIfNotExist($table, $input) {
+ return $this->adapter->insertIfNotExist($table, $input);
+ }
+
+ /**
+ * returns the error code and message as a string for logging
+ * works with DoctrineException
+ * @return string
+ */
+ public function getError() {
+ $msg = $this->errorCode() . ': ';
+ $errorInfo = $this->errorInfo();
+ if (is_array($errorInfo)) {
+ $msg .= 'SQLSTATE = '.$errorInfo[0] . ', ';
+ $msg .= 'Driver Code = '.$errorInfo[1] . ', ';
+ $msg .= 'Driver Message = '.$errorInfo[2];
+ }
+ return $msg;
+ }
+
+ // internal use
+ /**
+ * @param string $statement
+ * @return string
+ */
+ protected function replaceTablePrefix($statement) {
+ return str_replace( '*PREFIX*', $this->tablePrefix, $statement );
+ }
+
+ public function enableQueryStatementCaching() {
+ $this->cachingQueryStatementEnabled = true;
+ }
+
+ public function disableQueryStatementCaching() {
+ $this->cachingQueryStatementEnabled = false;
+ $this->preparedQueries = array();
+ }
+}
diff --git a/lib/db/mdb2schemamanager.php b/lib/db/mdb2schemamanager.php
index a34bc9dae75..8e76f46c78f 100644
--- a/lib/db/mdb2schemamanager.php
+++ b/lib/db/mdb2schemamanager.php
@@ -10,12 +10,12 @@ namespace OC\DB;
class MDB2SchemaManager {
/**
- * @var \Doctrine\DBAL\Connection $conn
+ * @var \OC\DB\Connection $conn
*/
protected $conn;
/**
- * @param \Doctrine\DBAL\Connection $conn
+ * @param \OC\DB\Connection $conn
*/
public function __construct($conn) {
$this->conn = $conn;
@@ -95,7 +95,7 @@ class MDB2SchemaManager {
$toSchema = clone $fromSchema;
$toSchema->dropTable($tableName);
$sql = $fromSchema->getMigrateToSql($toSchema, $this->conn->getDatabasePlatform());
- $this->conn->execute($sql);
+ $this->conn->executeQuery($sql);
}
/**
@@ -122,7 +122,7 @@ class MDB2SchemaManager {
$apps = \OC_App::getAllApps();
$this->conn->beginTransaction();
// Delete the old tables
- $this->removeDBStructure( OC::$SERVERROOT . '/db_structure.xml' );
+ $this->removeDBStructure( \OC::$SERVERROOT . '/db_structure.xml' );
foreach($apps as $app) {
$path = \OC_App::getAppPath($app).'/appinfo/database.xml';
diff --git a/lib/db/statementwrapper.php b/lib/db/statementwrapper.php
index f7bc45e068f..b8da1afc0e5 100644
--- a/lib/db/statementwrapper.php
+++ b/lib/db/statementwrapper.php
@@ -53,7 +53,7 @@ class OC_DB_StatementWrapper {
*/
public function execute($input=array()) {
if(OC_Config::getValue( "log_query", false)) {
- $params_str = str_replace("\n"," ",var_export($input,true));
+ $params_str = str_replace("\n", " ", var_export($input, true));
OC_Log::write('core', 'DB execute with arguments : '.$params_str, OC_Log::DEBUG);
}
$this->lastArguments = $input;
@@ -134,7 +134,7 @@ class OC_DB_StatementWrapper {
$host = OC_Config::getValue( "dbhost", "" );
$user = OC_Config::getValue( "dbuser", "" );
$pass = OC_Config::getValue( "dbpassword", "" );
- if (strpos($host,':')) {
+ if (strpos($host, ':')) {
list($host, $port) = explode(':', $host, 2);
} else {
$port = false;
diff --git a/lib/group.php b/lib/group.php
index 8fbf5f86418..ba93dc129a1 100644
--- a/lib/group.php
+++ b/lib/group.php
@@ -230,7 +230,7 @@ class OC_Group {
public static function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) {
$group = self::getManager()->get($gid);
if ($group) {
- $users = $group->searchUsers($search . $limit, $offset);
+ $users = $group->searchUsers($search, $limit, $offset);
$userIds = array();
foreach ($users as $user) {
$userIds[] = $user->getUID();
diff --git a/lib/l10n.php b/lib/l10n.php
index a28aa89c5f1..d2da302b644 100644
--- a/lib/l10n.php
+++ b/lib/l10n.php
@@ -2,8 +2,10 @@
/**
* ownCloud
*
+ * @author Frank Karlitschek
* @author Jakob Sack
* @copyright 2012 Frank Karlitschek frank@owncloud.org
+ * @copyright 2013 Jakob Sack
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -23,7 +25,7 @@
/**
* This class is for i18n and l10n
*/
-class OC_L10N{
+class OC_L10N {
/**
* cached instances
*/
@@ -55,6 +57,16 @@ class OC_L10N{
private $translations = array();
/**
+ * Plural forms (string)
+ */
+ private $plural_form_string = 'nplurals=2; plural=(n != 1);';
+
+ /**
+ * Plural forms (function)
+ */
+ private $plural_form_function = null;
+
+ /**
* Localization
*/
private $localizations = array(
@@ -66,6 +78,8 @@ class OC_L10N{
/**
* get an L10N instance
+ * @param $app string
+ * @param $lang string|null
* @return OC_L10N
*/
public static function get($app, $lang=null) {
@@ -81,8 +95,8 @@ class OC_L10N{
/**
* @brief The constructor
- * @param $app the app requesting l10n
- * @param $lang default: null Language
+ * @param $app string app requesting l10n
+ * @param $lang string default: null Language
* @returns OC_L10N-Object
*
* If language is not set, the constructor tries to find the right
@@ -93,6 +107,17 @@ class OC_L10N{
$this->lang = $lang;
}
+ public function load($transFile) {
+ $this->app = true;
+ include $transFile;
+ if(isset($TRANSLATIONS) && is_array($TRANSLATIONS)) {
+ $this->translations = $TRANSLATIONS;
+ }
+ if(isset($PLURAL_FORMS)) {
+ $this->plural_form_string = $PLURAL_FORMS;
+ }
+ }
+
protected function init() {
if ($this->app === true) {
return;
@@ -138,6 +163,9 @@ class OC_L10N{
}
}
}
+ if(isset($PLURAL_FORMS)) {
+ $this->plural_form_string = $PLURAL_FORMS;
+ }
}
if(file_exists(OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php')) {
@@ -154,6 +182,65 @@ class OC_L10N{
}
/**
+ * @brief Creates a function that The constructor
+ *
+ * If language is not set, the constructor tries to find the right
+ * language.
+ *
+ * Parts of the code is copied from Habari:
+ * https://github.com/habari/system/blob/master/classes/locale.php
+ * @param $string string
+ * @return string
+ */
+ protected function createPluralFormFunction($string){
+ if(preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
+ // sanitize
+ $nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
+ $plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
+
+ $body = str_replace(
+ array( 'plural', 'n', '$n$plurals', ),
+ array( '$plural', '$n', '$nplurals', ),
+ 'nplurals='. $nplurals . '; plural=' . $plural
+ );
+
+ // add parents
+ // important since PHP's ternary evaluates from left to right
+ $body .= ';';
+ $res = '';
+ $p = 0;
+ for($i = 0; $i < strlen($body); $i++) {
+ $ch = $body[$i];
+ switch ( $ch ) {
+ case '?':
+ $res .= ' ? (';
+ $p++;
+ break;
+ case ':':
+ $res .= ') : (';
+ break;
+ case ';':
+ $res .= str_repeat( ')', $p ) . ';';
+ $p = 0;
+ break;
+ default:
+ $res .= $ch;
+ }
+ }
+
+ $body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
+ return create_function('$n', $body);
+ }
+ else {
+ // default: one plural form for all cases but n==1 (english)
+ return create_function(
+ '$n',
+ '$nplurals=2;$plural=($n==1?0:1);return ($plural>=$nplurals?$nplurals-1:$plural);'
+ );
+ }
+ }
+
+ /**
* @brief Translating
* @param $text String The text we need a translation for
* @param array $parameters default:array() Parameters for sprintf
@@ -168,6 +255,37 @@ class OC_L10N{
/**
* @brief Translating
+ * @param $text_singular String the string to translate for exactly one object
+ * @param $text_plural String the string to translate for n objects
+ * @param $count Integer Number of objects
+ * @param array $parameters default:array() Parameters for sprintf
+ * @return \OC_L10N_String Translation or the same text
+ *
+ * Returns the translation. If no translation is found, $text will be
+ * returned. %n will be replaced with the number of objects.
+ *
+ * The correct plural is determined by the plural_forms-function
+ * provided by the po file.
+ *
+ */
+ public function n($text_singular, $text_plural, $count, $parameters = array()) {
+ $this->init();
+ $identifier = "_${text_singular}__${text_plural}_";
+ if( array_key_exists($identifier, $this->translations)) {
+ return new OC_L10N_String( $this, $identifier, $parameters, $count );
+ }
+ else{
+ if($count === 1) {
+ return new OC_L10N_String($this, $text_singular, $parameters, $count);
+ }
+ else{
+ return new OC_L10N_String($this, $text_plural, $parameters, $count);
+ }
+ }
+ }
+
+ /**
+ * @brief Translating
* @param $textArray The text array we need a translation for
* @returns Translation or the same text
*
@@ -201,6 +319,42 @@ class OC_L10N{
}
/**
+ * @brief getPluralFormString
+ * @returns string containing the gettext "Plural-Forms"-string
+ *
+ * Returns a string like "nplurals=2; plural=(n != 1);"
+ */
+ public function getPluralFormString() {
+ $this->init();
+ return $this->plural_form_string;
+ }
+
+ /**
+ * @brief getPluralFormFunction
+ * @returns string the plural form function
+ *
+ * returned function accepts the argument $n
+ */
+ public function getPluralFormFunction() {
+ $this->init();
+ if(is_null($this->plural_form_function)) {
+ $this->plural_form_function = $this->createPluralFormFunction($this->plural_form_string);
+ }
+ return $this->plural_form_function;
+ }
+
+ /**
+ * @brief get localizations
+ * @returns Fetch all localizations
+ *
+ * Returns an associative array with all localizations
+ */
+ public function getLocalizations() {
+ $this->init();
+ return $this->localizations;
+ }
+
+ /**
* @brief Localization
* @param $type Type of localization
* @param $params parameters for this localization
@@ -230,8 +384,12 @@ class OC_L10N{
case 'date':
case 'datetime':
case 'time':
- if($data instanceof DateTime) return $data->format($this->localizations[$type]);
- elseif(is_string($data)) $data = strtotime($data);
+ if($data instanceof DateTime) {
+ return $data->format($this->localizations[$type]);
+ }
+ elseif(is_string($data)) {
+ $data = strtotime($data);
+ }
$locales = array(self::findLanguage());
if (strlen($locales[0]) == 2) {
$locales[] = $locales[0].'_'.strtoupper($locales[0]);
diff --git a/lib/l10n/af_ZA.php b/lib/l10n/af_ZA.php
index de32778026f..67353b8fb42 100644
--- a/lib/l10n/af_ZA.php
+++ b/lib/l10n/af_ZA.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Hulp",
"Personal" => "Persoonlik",
"Settings" => "Instellings",
@@ -7,3 +8,4 @@
"Admin" => "Admin",
"web services under your control" => "webdienste onder jou beheer"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/ar.php b/lib/l10n/ar.php
index 107b27a1fc8..50881cb627b 100644
--- a/lib/l10n/ar.php
+++ b/lib/l10n/ar.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "المساعدة",
"Personal" => "شخصي",
"Settings" => "إعدادات",
@@ -50,3 +51,4 @@
"years ago" => "سنة مضت",
"Could not find category \"%s\"" => "تعذر العثور على المجلد \"%s\""
);
+$PLURAL_FORMS = "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;";
diff --git a/lib/l10n/bg_BG.php b/lib/l10n/bg_BG.php
index e23112c8302..4a558426a89 100644
--- a/lib/l10n/bg_BG.php
+++ b/lib/l10n/bg_BG.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Помощ",
"Personal" => "Лични",
"Settings" => "Настройки",
@@ -51,3 +52,4 @@
"years ago" => "последните години",
"Could not find category \"%s\"" => "Невъзможно откриване на категорията \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/bn_BD.php b/lib/l10n/bn_BD.php
index ab1d9b94d0d..3e1340b3689 100644
--- a/lib/l10n/bn_BD.php
+++ b/lib/l10n/bn_BD.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "সহায়িকা",
"Personal" => "ব্যক্তিগত",
"Settings" => "নিয়ামকসমূহ",
@@ -26,3 +27,4 @@
"last year" => "গত বছর",
"years ago" => "বছর পূর্বে"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/ca.php b/lib/l10n/ca.php
index 14f9edfe34c..a0c7b10e734 100644
--- a/lib/l10n/ca.php
+++ b/lib/l10n/ca.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Ajuda",
"Personal" => "Personal",
"Settings" => "Configuració",
@@ -55,3 +56,4 @@
"Caused by:" => "Provocat per:",
"Could not find category \"%s\"" => "No s'ha trobat la categoria \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/cs_CZ.php b/lib/l10n/cs_CZ.php
index 7390c5f432a..354c61f6a12 100644
--- a/lib/l10n/cs_CZ.php
+++ b/lib/l10n/cs_CZ.php
@@ -1,17 +1,18 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Nápověda",
"Personal" => "Osobní",
"Settings" => "Nastavení",
"Users" => "Uživatelé",
"Apps" => "Aplikace",
"Admin" => "Administrace",
-"Failed to upgrade \"%s\"." => "Selhalo povýšení verze \"%s\".",
-"web services under your control" => "služby webu pod Vaší kontrolou",
+"Failed to upgrade \"%s\"." => "Selhala aktualizace verze \"%s\".",
+"web services under your control" => "webové služby pod Vaší kontrolou",
"cannot open \"%s\"" => "nelze otevřít \"%s\"",
-"ZIP download is turned off." => "Stahování ZIPu je vypnuto.",
+"ZIP download is turned off." => "Stahování v ZIPu je vypnuto.",
"Files need to be downloaded one by one." => "Soubory musí být stahovány jednotlivě.",
"Back to Files" => "Zpět k souborům",
-"Selected files too large to generate zip file." => "Vybrané soubory jsou příliš velké pro vytvoření zip souboru.",
+"Selected files too large to generate zip file." => "Vybrané soubory jsou příliš velké pro vytvoření ZIP souboru.",
"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Stáhněte soubory po menších částech, samostatně, nebo se obraťte na správce.",
"couldn't be determined" => "nelze zjistit",
"Application is not enabled" => "Aplikace není povolena",
@@ -23,24 +24,24 @@
"%s enter the database username." => "Zadejte uživatelské jméno %s databáze.",
"%s enter the database name." => "Zadejte název databáze pro %s databáze.",
"%s you may not use dots in the database name" => "V názvu databáze %s nesmíte používat tečky.",
-"MS SQL username and/or password not valid: %s" => "Uživatelské jméno, či heslo MSSQL není platné: %s",
-"You need to enter either an existing account or the administrator." => "Musíte zadat existující účet, či správce.",
-"MySQL username and/or password not valid" => "Uživatelské jméno, či heslo MySQL není platné",
-"DB Error: \"%s\"" => "Chyba DB: \"%s\"",
-"Offending command was: \"%s\"" => "Podezřelý příkaz byl: \"%s\"",
+"MS SQL username and/or password not valid: %s" => "Uživatelské jméno či heslo MSSQL není platné: %s",
+"You need to enter either an existing account or the administrator." => "Musíte zadat existující účet či správce.",
+"MySQL username and/or password not valid" => "Uživatelské jméno či heslo MySQL není platné",
+"DB Error: \"%s\"" => "Chyba databáze: \"%s\"",
+"Offending command was: \"%s\"" => "Příslušný příkaz byl: \"%s\"",
"MySQL user '%s'@'localhost' exists already." => "Uživatel '%s'@'localhost' již v MySQL existuje.",
-"Drop this user from MySQL" => "Zahodit uživatele z MySQL",
+"Drop this user from MySQL" => "Zrušte tohoto uživatele z MySQL",
"MySQL user '%s'@'%%' already exists" => "Uživatel '%s'@'%%' již v MySQL existuje",
-"Drop this user from MySQL." => "Zahodit uživatele z MySQL.",
+"Drop this user from MySQL." => "Zrušte tohoto uživatele z MySQL",
"Oracle connection could not be established" => "Spojení s Oracle nemohlo být navázáno",
-"Oracle username and/or password not valid" => "Uživatelské jméno, či heslo Oracle není platné",
-"Offending command was: \"%s\", name: %s, password: %s" => "Podezřelý příkaz byl: \"%s\", jméno: %s, heslo: %s",
-"PostgreSQL username and/or password not valid" => "Uživatelské jméno, či heslo PostgreSQL není platné",
+"Oracle username and/or password not valid" => "Uživatelské jméno či heslo Oracle není platné",
+"Offending command was: \"%s\", name: %s, password: %s" => "Příslušný příkaz byl: \"%s\", jméno: %s, heslo: %s",
+"PostgreSQL username and/or password not valid" => "Uživatelské jméno či heslo PostgreSQL není platné",
"Set an admin username." => "Zadejte uživatelské jméno správce.",
"Set an admin password." => "Zadejte heslo správce.",
-"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Váš webový server není správně nastaven pro umožnění synchronizace, protože rozhraní WebDAV je rozbité.",
+"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Váš webový server není správně nastaven pro umožnění synchronizace, rozhraní WebDAV se zdá být rozbité.",
"Please double check the <a href='%s'>installation guides</a>." => "Zkonzultujte, prosím, <a href='%s'>průvodce instalací</a>.",
-"seconds ago" => "před pár vteřinami",
+"seconds ago" => "před pár sekundami",
"1 minute ago" => "před minutou",
"%d minutes ago" => "před %d minutami",
"1 hour ago" => "před hodinou",
@@ -49,9 +50,10 @@
"yesterday" => "včera",
"%d days ago" => "před %d dny",
"last month" => "minulý měsíc",
-"%d months ago" => "Před %d měsíci",
+"%d months ago" => "před %d měsíci",
"last year" => "minulý rok",
"years ago" => "před lety",
"Caused by:" => "Příčina:",
"Could not find category \"%s\"" => "Nelze nalézt kategorii \"%s\""
);
+$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;";
diff --git a/lib/l10n/cy_GB.php b/lib/l10n/cy_GB.php
index 27140ba6dbb..7ba8378cb41 100644
--- a/lib/l10n/cy_GB.php
+++ b/lib/l10n/cy_GB.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Cymorth",
"Personal" => "Personol",
"Settings" => "Gosodiadau",
@@ -50,3 +51,4 @@
"years ago" => "blwyddyn yn ôl",
"Could not find category \"%s\"" => "Methu canfod categori \"%s\""
);
+$PLURAL_FORMS = "nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;";
diff --git a/lib/l10n/da.php b/lib/l10n/da.php
index 789328a3100..aa5bb74bd31 100644
--- a/lib/l10n/da.php
+++ b/lib/l10n/da.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Hjælp",
"Personal" => "Personligt",
"Settings" => "Indstillinger",
@@ -55,3 +56,4 @@
"Caused by:" => "Forårsaget af:",
"Could not find category \"%s\"" => "Kunne ikke finde kategorien \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/de.php b/lib/l10n/de.php
index f1c4a1171e2..5dcbea4e022 100644
--- a/lib/l10n/de.php
+++ b/lib/l10n/de.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Hilfe",
"Personal" => "Persönlich",
"Settings" => "Einstellungen",
@@ -55,3 +56,4 @@
"Caused by:" => "Verursacht durch:",
"Could not find category \"%s\"" => "Die Kategorie \"%s\" konnte nicht gefunden werden."
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/de_CH.php b/lib/l10n/de_CH.php
new file mode 100644
index 00000000000..2dbf22b9a7d
--- /dev/null
+++ b/lib/l10n/de_CH.php
@@ -0,0 +1,59 @@
+<?php
+$TRANSLATIONS = array(
+"Help" => "Hilfe",
+"Personal" => "Persönlich",
+"Settings" => "Einstellungen",
+"Users" => "Benutzer",
+"Apps" => "Apps",
+"Admin" => "Administrator",
+"Failed to upgrade \"%s\"." => "Konnte \"%s\" nicht aktualisieren.",
+"web services under your control" => "Web-Services unter Ihrer Kontrolle",
+"cannot open \"%s\"" => "Öffnen von \"%s\" fehlgeschlagen",
+"ZIP download is turned off." => "Der ZIP-Download ist deaktiviert.",
+"Files need to be downloaded one by one." => "Die Dateien müssen einzeln heruntergeladen werden.",
+"Back to Files" => "Zurück zu \"Dateien\"",
+"Selected files too large to generate zip file." => "Die gewählten Dateien sind zu gross, um eine ZIP-Datei zu erstellen.",
+"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Laden Sie die Dateien in kleineren, separaten, Stücken herunter oder bitten Sie Ihren Administrator.",
+"couldn't be determined" => "konnte nicht ermittelt werden",
+"Application is not enabled" => "Die Anwendung ist nicht aktiviert",
+"Authentication error" => "Authentifizierungs-Fehler",
+"Token expired. Please reload page." => "Token abgelaufen. Bitte laden Sie die Seite neu.",
+"Files" => "Dateien",
+"Text" => "Text",
+"Images" => "Bilder",
+"%s enter the database username." => "%s geben Sie den Datenbank-Benutzernamen an.",
+"%s enter the database name." => "%s geben Sie den Datenbank-Namen an.",
+"%s you may not use dots in the database name" => "%s Der Datenbank-Name darf keine Punkte enthalten",
+"MS SQL username and/or password not valid: %s" => "MS SQL Benutzername und/oder Passwort ungültig: %s",
+"You need to enter either an existing account or the administrator." => "Sie müssen entweder ein existierendes Benutzerkonto oder das Administratoren-Konto angeben.",
+"MySQL username and/or password not valid" => "MySQL Benutzername und/oder Passwort ungültig",
+"DB Error: \"%s\"" => "DB Fehler: \"%s\"",
+"Offending command was: \"%s\"" => "Fehlerhafter Befehl war: \"%s\"",
+"MySQL user '%s'@'localhost' exists already." => "MySQL Benutzer '%s'@'localhost' existiert bereits.",
+"Drop this user from MySQL" => "Lösche diesen Benutzer aus MySQL",
+"MySQL user '%s'@'%%' already exists" => "MySQL Benutzer '%s'@'%%' existiert bereits",
+"Drop this user from MySQL." => "Lösche diesen Benutzer aus MySQL.",
+"Oracle connection could not be established" => "Die Oracle-Verbindung konnte nicht aufgebaut werden.",
+"Oracle username and/or password not valid" => "Oracle Benutzername und/oder Passwort ungültig",
+"Offending command was: \"%s\", name: %s, password: %s" => "Fehlerhafter Befehl war: \"%s\", Name: %s, Passwort: %s",
+"PostgreSQL username and/or password not valid" => "PostgreSQL Benutzername und/oder Passwort ungültig",
+"Set an admin username." => "Setze Administrator Benutzername.",
+"Set an admin password." => "Setze Administrator Passwort",
+"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Ihr Web-Server ist noch nicht für eine Datei-Synchronisation konfiguriert, weil die WebDAV-Schnittstelle vermutlich defekt ist.",
+"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfen Sie die <a href='%s'>Installationsanleitungen</a>.",
+"seconds ago" => "Gerade eben",
+"1 minute ago" => "Vor 1 Minute",
+"%d minutes ago" => "Vor %d Minuten",
+"1 hour ago" => "Vor einer Stunde",
+"%d hours ago" => "Vor %d Stunden",
+"today" => "Heute",
+"yesterday" => "Gestern",
+"%d days ago" => "Vor %d Tag(en)",
+"last month" => "Letzten Monat",
+"%d months ago" => "Vor %d Monaten",
+"last year" => "Letztes Jahr",
+"years ago" => "Vor Jahren",
+"Caused by:" => "Verursacht durch:",
+"Could not find category \"%s\"" => "Die Kategorie «%s» konnte nicht gefunden werden."
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/de_DE.php b/lib/l10n/de_DE.php
index 276e526e2ed..91731585d48 100644
--- a/lib/l10n/de_DE.php
+++ b/lib/l10n/de_DE.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Hilfe",
"Personal" => "Persönlich",
"Settings" => "Einstellungen",
@@ -55,3 +56,4 @@
"Caused by:" => "Verursacht durch:",
"Could not find category \"%s\"" => "Die Kategorie \"%s\" konnte nicht gefunden werden."
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/el.php b/lib/l10n/el.php
index 3e876aefdfe..9989fc967b1 100644
--- a/lib/l10n/el.php
+++ b/lib/l10n/el.php
@@ -1,15 +1,19 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Βοήθεια",
"Personal" => "Προσωπικά",
"Settings" => "Ρυθμίσεις",
"Users" => "Χρήστες",
"Apps" => "Εφαρμογές",
"Admin" => "Διαχειριστής",
+"Failed to upgrade \"%s\"." => "Αποτυχία αναβάθμισης του \"%s\".",
"web services under your control" => "υπηρεσίες δικτύου υπό τον έλεγχό σας",
+"cannot open \"%s\"" => "αδυναμία ανοίγματος \"%s\"",
"ZIP download is turned off." => "Η λήψη ZIP απενεργοποιήθηκε.",
"Files need to be downloaded one by one." => "Τα αρχεία πρέπει να ληφθούν ένα-ένα.",
"Back to Files" => "Πίσω στα Αρχεία",
"Selected files too large to generate zip file." => "Τα επιλεγμένα αρχεία είναι μεγάλα ώστε να δημιουργηθεί αρχείο zip.",
+"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Λήψη των αρχείων σε μικρότερα κομμάτια, χωριστά ή ρωτήστε τον διαχειριστή σας.",
"couldn't be determined" => "δεν μπορούσε να προσδιορισθεί",
"Application is not enabled" => "Δεν ενεργοποιήθηκε η εφαρμογή",
"Authentication error" => "Σφάλμα πιστοποίησης",
@@ -49,5 +53,7 @@
"%d months ago" => "%d μήνες πριν",
"last year" => "τελευταίο χρόνο",
"years ago" => "χρόνια πριν",
+"Caused by:" => "Προκλήθηκε από:",
"Could not find category \"%s\"" => "Αδυναμία εύρεσης κατηγορίας \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/en@pirate.php b/lib/l10n/en@pirate.php
index 02ff0331e05..a86492d2a93 100644
--- a/lib/l10n/en@pirate.php
+++ b/lib/l10n/en@pirate.php
@@ -1,3 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"web services under your control" => "web services under your control"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/eo.php b/lib/l10n/eo.php
index fd45f30c69b..6ccc2025382 100644
--- a/lib/l10n/eo.php
+++ b/lib/l10n/eo.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Helpo",
"Personal" => "Persona",
"Settings" => "Agordo",
@@ -47,3 +48,4 @@
"years ago" => "jaroj antaŭe",
"Could not find category \"%s\"" => "Ne troviĝis kategorio “%s”"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/es.php b/lib/l10n/es.php
index 66011e61a0d..e30e4d711e7 100644
--- a/lib/l10n/es.php
+++ b/lib/l10n/es.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Ayuda",
"Personal" => "Personal",
"Settings" => "Ajustes",
@@ -55,3 +56,4 @@
"Caused by:" => "Causado por:",
"Could not find category \"%s\"" => "No puede encontrar la categoria \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/es_AR.php b/lib/l10n/es_AR.php
index da0f6fae84a..3f1c098dbf5 100644
--- a/lib/l10n/es_AR.php
+++ b/lib/l10n/es_AR.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Ayuda",
"Personal" => "Personal",
"Settings" => "Configuración",
@@ -55,3 +56,4 @@
"Caused by:" => "Provocado por:",
"Could not find category \"%s\"" => "No fue posible encontrar la categoría \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/et_EE.php b/lib/l10n/et_EE.php
index c2cd8ff0389..403f0871c53 100644
--- a/lib/l10n/et_EE.php
+++ b/lib/l10n/et_EE.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Abiinfo",
"Personal" => "Isiklik",
"Settings" => "Seaded",
@@ -55,3 +56,4 @@
"Caused by:" => "Põhjustaja:",
"Could not find category \"%s\"" => "Ei leia kategooriat \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/eu.php b/lib/l10n/eu.php
index 94b4cfb902e..0d9a8860a09 100644
--- a/lib/l10n/eu.php
+++ b/lib/l10n/eu.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Laguntza",
"Personal" => "Pertsonala",
"Settings" => "Ezarpenak",
@@ -55,3 +56,4 @@
"Caused by:" => "Honek eraginda:",
"Could not find category \"%s\"" => "Ezin da \"%s\" kategoria aurkitu"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/fa.php b/lib/l10n/fa.php
index 40a778e2126..fa886531bba 100644
--- a/lib/l10n/fa.php
+++ b/lib/l10n/fa.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "راه‌نما",
"Personal" => "شخصی",
"Settings" => "تنظیمات",
@@ -51,3 +52,4 @@
"years ago" => "سال‌های قبل",
"Could not find category \"%s\"" => "دسته بندی %s یافت نشد"
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/fi.php b/lib/l10n/fi.php
index daaddb25e48..ac1f80a8f73 100644
--- a/lib/l10n/fi.php
+++ b/lib/l10n/fi.php
@@ -1,3 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Settings" => "asetukset"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/fi_FI.php b/lib/l10n/fi_FI.php
index 75576c3034d..5892a968d5b 100644
--- a/lib/l10n/fi_FI.php
+++ b/lib/l10n/fi_FI.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Ohje",
"Personal" => "Henkilökohtainen",
"Settings" => "Asetukset",
@@ -47,3 +48,4 @@
"years ago" => "vuotta sitten",
"Could not find category \"%s\"" => "Luokkaa \"%s\" ei löytynyt"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/fr.php b/lib/l10n/fr.php
index 9f30b602696..18fbe55270f 100644
--- a/lib/l10n/fr.php
+++ b/lib/l10n/fr.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Aide",
"Personal" => "Personnel",
"Settings" => "Paramètres",
@@ -51,3 +52,4 @@
"years ago" => "il y a plusieurs années",
"Could not find category \"%s\"" => "Impossible de trouver la catégorie \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n > 1);";
diff --git a/lib/l10n/gl.php b/lib/l10n/gl.php
index f5309d95081..f5cda20e135 100644
--- a/lib/l10n/gl.php
+++ b/lib/l10n/gl.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Axuda",
"Personal" => "Persoal",
"Settings" => "Axustes",
@@ -55,3 +56,4 @@
"Caused by:" => "Causado por:",
"Could not find category \"%s\"" => "Non foi posíbel atopar a categoría «%s»"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/he.php b/lib/l10n/he.php
index 2e011e342a0..fa597dadea7 100644
--- a/lib/l10n/he.php
+++ b/lib/l10n/he.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "עזרה",
"Personal" => "אישי",
"Settings" => "הגדרות",
@@ -32,3 +33,4 @@
"years ago" => "שנים",
"Could not find category \"%s\"" => "לא ניתן למצוא את הקטגוריה „%s“"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/hi.php b/lib/l10n/hi.php
index f507993f494..7986b3b6b7f 100644
--- a/lib/l10n/hi.php
+++ b/lib/l10n/hi.php
@@ -1,7 +1,9 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "सहयोग",
"Personal" => "यक्तिगत",
"Settings" => "सेटिंग्स",
"Users" => "उपयोगकर्ता",
"Apps" => "Apps"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/hr.php b/lib/l10n/hr.php
index 41c34d3108c..9c158447729 100644
--- a/lib/l10n/hr.php
+++ b/lib/l10n/hr.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Pomoć",
"Personal" => "Osobno",
"Settings" => "Postavke",
@@ -16,3 +17,4 @@
"last year" => "prošlu godinu",
"years ago" => "godina"
);
+$PLURAL_FORMS = "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;";
diff --git a/lib/l10n/hu_HU.php b/lib/l10n/hu_HU.php
index 7738dcc05c8..422c7266680 100644
--- a/lib/l10n/hu_HU.php
+++ b/lib/l10n/hu_HU.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Súgó",
"Personal" => "Személyes",
"Settings" => "Beállítások",
@@ -55,3 +56,4 @@
"Caused by:" => "Okozta:",
"Could not find category \"%s\"" => "Ez a kategória nem található: \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/ia.php b/lib/l10n/ia.php
index e5f6e3ddf58..50ebf20c591 100644
--- a/lib/l10n/ia.php
+++ b/lib/l10n/ia.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Adjuta",
"Personal" => "Personal",
"Settings" => "Configurationes",
@@ -9,3 +10,4 @@
"Files" => "Files",
"Text" => "Texto"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/id.php b/lib/l10n/id.php
index c247651f0c9..0881f5349bc 100644
--- a/lib/l10n/id.php
+++ b/lib/l10n/id.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Bantuan",
"Personal" => "Pribadi",
"Settings" => "Setelan",
@@ -50,3 +51,4 @@
"years ago" => "beberapa tahun lalu",
"Could not find category \"%s\"" => "Tidak dapat menemukan kategori \"%s\""
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/is.php b/lib/l10n/is.php
index 0f7a22fd13e..5ccb20882ad 100644
--- a/lib/l10n/is.php
+++ b/lib/l10n/is.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Hjálp",
"Personal" => "Um mig",
"Settings" => "Stillingar",
@@ -30,3 +31,4 @@
"years ago" => "einhverjum árum",
"Could not find category \"%s\"" => "Fann ekki flokkinn \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/it.php b/lib/l10n/it.php
index 693f86b6b80..c85ba08f4cd 100644
--- a/lib/l10n/it.php
+++ b/lib/l10n/it.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Aiuto",
"Personal" => "Personale",
"Settings" => "Impostazioni",
@@ -55,3 +56,4 @@
"Caused by:" => "Causato da:",
"Could not find category \"%s\"" => "Impossibile trovare la categoria \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/ja_JP.php b/lib/l10n/ja_JP.php
index 36d06d360b9..716db8706f0 100644
--- a/lib/l10n/ja_JP.php
+++ b/lib/l10n/ja_JP.php
@@ -1,15 +1,19 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "ヘルプ",
"Personal" => "個人",
"Settings" => "設定",
"Users" => "ユーザ",
"Apps" => "アプリ",
"Admin" => "管理",
+"Failed to upgrade \"%s\"." => "\"%s\" へのアップグレードに失敗しました。",
"web services under your control" => "管理下のウェブサービス",
+"cannot open \"%s\"" => "\"%s\" が開けません",
"ZIP download is turned off." => "ZIPダウンロードは無効です。",
"Files need to be downloaded one by one." => "ファイルは1つずつダウンロードする必要があります。",
"Back to Files" => "ファイルに戻る",
"Selected files too large to generate zip file." => "選択したファイルはZIPファイルの生成には大きすぎます。",
+"Download the files in smaller chunks, seperately or kindly ask your administrator." => "ファイルは、小さいファイルに分割されてダウンロードされます。もしくは、管理者にお尋ねください。",
"couldn't be determined" => "測定できませんでした",
"Application is not enabled" => "アプリケーションは無効です",
"Authentication error" => "認証エラー",
@@ -49,5 +53,7 @@
"%d months ago" => "%d 分前",
"last year" => "一年前",
"years ago" => "年前",
+"Caused by:" => "原因は以下:",
"Could not find category \"%s\"" => "カテゴリ \"%s\" が見つかりませんでした"
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/ka.php b/lib/l10n/ka.php
index e5a3e659668..b6e06997638 100644
--- a/lib/l10n/ka.php
+++ b/lib/l10n/ka.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "შველა",
"Personal" => "პერსონა",
"Users" => "მომხმარებლები",
@@ -13,3 +14,4 @@
"yesterday" => "გუშინ",
"%d days ago" => "%d დღის წინ"
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/ka_GE.php b/lib/l10n/ka_GE.php
index c6e77da2dac..5001eee0c27 100644
--- a/lib/l10n/ka_GE.php
+++ b/lib/l10n/ka_GE.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "დახმარება",
"Personal" => "პირადი",
"Settings" => "პარამეტრები",
@@ -50,3 +51,4 @@
"years ago" => "წლის წინ",
"Could not find category \"%s\"" => "\"%s\" კატეგორიის მოძებნა ვერ მოხერხდა"
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/ko.php b/lib/l10n/ko.php
index 1f32ebe402a..c163d8c9fa4 100644
--- a/lib/l10n/ko.php
+++ b/lib/l10n/ko.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "도움말",
"Personal" => "개인",
"Settings" => "설정",
@@ -40,3 +41,4 @@
"years ago" => "년 전",
"Could not find category \"%s\"" => "분류 \"%s\"을(를) 찾을 수 없습니다."
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/ku_IQ.php b/lib/l10n/ku_IQ.php
index 6d7461a1685..05959b89cff 100644
--- a/lib/l10n/ku_IQ.php
+++ b/lib/l10n/ku_IQ.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "یارمەتی",
"Settings" => "ده‌ستكاری",
"Users" => "به‌كارهێنه‌ر",
@@ -6,3 +7,4 @@
"Admin" => "به‌ڕێوه‌به‌ری سه‌ره‌كی",
"web services under your control" => "ڕاژه‌ی وێب له‌ژێر چاودێریت دایه"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/lb.php b/lib/l10n/lb.php
index 867b0a37409..11552bcce82 100644
--- a/lib/l10n/lb.php
+++ b/lib/l10n/lb.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Hëllef",
"Personal" => "Perséinlech",
"Settings" => "Astellungen",
@@ -18,3 +19,4 @@
"last year" => "Läscht Joer",
"years ago" => "Joren hier"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/lt_LT.php b/lib/l10n/lt_LT.php
index 5e3a0482033..e35f3bee16b 100644
--- a/lib/l10n/lt_LT.php
+++ b/lib/l10n/lt_LT.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Pagalba",
"Personal" => "Asmeniniai",
"Settings" => "Nustatymai",
@@ -29,3 +30,4 @@
"last year" => "praeitais metais",
"years ago" => "prieš metus"
);
+$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/lv.php b/lib/l10n/lv.php
index 662f4d5b245..0dfaf6b6780 100644
--- a/lib/l10n/lv.php
+++ b/lib/l10n/lv.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Palīdzība",
"Personal" => "Personīgi",
"Settings" => "Iestatījumi",
@@ -50,3 +51,4 @@
"years ago" => "gadus atpakaļ",
"Could not find category \"%s\"" => "Nevarēja atrast kategoriju “%s”"
);
+$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);";
diff --git a/lib/l10n/mk.php b/lib/l10n/mk.php
index 30fa9ab73c1..eeece35ea6d 100644
--- a/lib/l10n/mk.php
+++ b/lib/l10n/mk.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Помош",
"Personal" => "Лично",
"Settings" => "Подесувања",
@@ -30,3 +31,4 @@
"years ago" => "пред години",
"Could not find category \"%s\"" => "Не можам да најдам категорија „%s“"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;";
diff --git a/lib/l10n/ms_MY.php b/lib/l10n/ms_MY.php
index a2930597971..5de0eb95991 100644
--- a/lib/l10n/ms_MY.php
+++ b/lib/l10n/ms_MY.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Bantuan",
"Personal" => "Peribadi",
"Settings" => "Tetapan",
@@ -10,3 +11,4 @@
"Files" => "Fail-fail",
"Text" => "Teks"
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/my_MM.php b/lib/l10n/my_MM.php
index f214a1ed794..731aa33d576 100644
--- a/lib/l10n/my_MM.php
+++ b/lib/l10n/my_MM.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "အကူအညီ",
"Users" => "သုံးစွဲသူ",
"Apps" => "Apps",
@@ -27,3 +28,4 @@
"years ago" => "နှစ် အရင်က",
"Could not find category \"%s\"" => "\"%s\"ခေါင်းစဉ်ကို ရှာမတွေ့ပါ"
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/nb_NO.php b/lib/l10n/nb_NO.php
index ab2d4f91920..42a43bfd98f 100644
--- a/lib/l10n/nb_NO.php
+++ b/lib/l10n/nb_NO.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Hjelp",
"Personal" => "Personlig",
"Settings" => "Innstillinger",
@@ -32,3 +33,4 @@
"years ago" => "år siden",
"Could not find category \"%s\"" => "Kunne ikke finne kategori \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/nl.php b/lib/l10n/nl.php
index 0a221b11f00..8983aa81bfd 100644
--- a/lib/l10n/nl.php
+++ b/lib/l10n/nl.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Help",
"Personal" => "Persoonlijk",
"Settings" => "Instellingen",
@@ -55,3 +56,4 @@
"Caused by:" => "Gekomen door:",
"Could not find category \"%s\"" => "Kon categorie \"%s\" niet vinden"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/nn_NO.php b/lib/l10n/nn_NO.php
index c1739398109..3cbd0159bc2 100644
--- a/lib/l10n/nn_NO.php
+++ b/lib/l10n/nn_NO.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Hjelp",
"Personal" => "Personleg",
"Settings" => "Innstillingar",
@@ -20,3 +21,4 @@
"last year" => "i fjor",
"years ago" => "år sidan"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/oc.php b/lib/l10n/oc.php
index a72da90790a..6f0645bf77a 100644
--- a/lib/l10n/oc.php
+++ b/lib/l10n/oc.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Ajuda",
"Personal" => "Personal",
"Settings" => "Configuracion",
@@ -21,3 +22,4 @@
"last year" => "an passat",
"years ago" => "ans a"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n > 1);";
diff --git a/lib/l10n/pl.php b/lib/l10n/pl.php
index d06d5ba8a3e..bd24614751a 100644
--- a/lib/l10n/pl.php
+++ b/lib/l10n/pl.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Pomoc",
"Personal" => "Osobiste",
"Settings" => "Ustawienia",
@@ -55,3 +56,4 @@
"Caused by:" => "Spowodowane przez:",
"Could not find category \"%s\"" => "Nie można odnaleźć kategorii \"%s\""
);
+$PLURAL_FORMS = "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/pl_PL.php b/lib/l10n/pl_PL.php
index 67cf0a33259..5494e3dab25 100644
--- a/lib/l10n/pl_PL.php
+++ b/lib/l10n/pl_PL.php
@@ -1,3 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Settings" => "Ustawienia"
);
+$PLURAL_FORMS = "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/pt_BR.php b/lib/l10n/pt_BR.php
index 23385e8c7d1..cae6107b9e8 100644
--- a/lib/l10n/pt_BR.php
+++ b/lib/l10n/pt_BR.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Ajuda",
"Personal" => "Pessoal",
"Settings" => "Ajustes",
@@ -55,3 +56,4 @@
"Caused by:" => "Causados ​​por:",
"Could not find category \"%s\"" => "Impossível localizar categoria \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n > 1);";
diff --git a/lib/l10n/pt_PT.php b/lib/l10n/pt_PT.php
index 96cb5f65f56..cb8bc99096c 100644
--- a/lib/l10n/pt_PT.php
+++ b/lib/l10n/pt_PT.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Ajuda",
"Personal" => "Pessoal",
"Settings" => "Configurações",
@@ -55,3 +56,4 @@
"Caused by:" => "Causado por:",
"Could not find category \"%s\"" => "Não foi encontrado a categoria \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/ro.php b/lib/l10n/ro.php
index 5a34e9571e5..006e97ed865 100644
--- a/lib/l10n/ro.php
+++ b/lib/l10n/ro.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Ajutor",
"Personal" => "Personal",
"Settings" => "Setări",
@@ -33,3 +34,4 @@
"years ago" => "ani în urmă",
"Could not find category \"%s\"" => "Cloud nu a gasit categoria \"%s\""
);
+$PLURAL_FORMS = "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));";
diff --git a/lib/l10n/ru.php b/lib/l10n/ru.php
index d9d1f5c53fe..544f9c9b809 100644
--- a/lib/l10n/ru.php
+++ b/lib/l10n/ru.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Помощь",
"Personal" => "Личное",
"Settings" => "Конфигурация",
@@ -55,3 +56,4 @@
"Caused by:" => "Вызвано:",
"Could not find category \"%s\"" => "Категория \"%s\" не найдена"
);
+$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/ru_RU.php b/lib/l10n/ru_RU.php
index 7639a3cc97e..1761c1ebf3b 100644
--- a/lib/l10n/ru_RU.php
+++ b/lib/l10n/ru_RU.php
@@ -1,4 +1,6 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Settings" => "Настройки",
"Text" => "Текст"
);
+$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/si_LK.php b/lib/l10n/si_LK.php
index 49ded7026e0..36e7b19ba97 100644
--- a/lib/l10n/si_LK.php
+++ b/lib/l10n/si_LK.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "උදව්",
"Personal" => "පෞද්ගලික",
"Settings" => "සිටුවම්",
@@ -26,3 +27,4 @@
"last year" => "පෙර අවුරුද්දේ",
"years ago" => "අවුරුදු කීපයකට පෙර"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/sk_SK.php b/lib/l10n/sk_SK.php
index 64ad1e540f3..93699439ee2 100644
--- a/lib/l10n/sk_SK.php
+++ b/lib/l10n/sk_SK.php
@@ -1,15 +1,19 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Pomoc",
"Personal" => "Osobné",
"Settings" => "Nastavenia",
"Users" => "Používatelia",
"Apps" => "Aplikácie",
"Admin" => "Administrátor",
+"Failed to upgrade \"%s\"." => "Zlyhala aktualizácia \"%s\".",
"web services under your control" => "webové služby pod Vašou kontrolou",
+"cannot open \"%s\"" => "nemožno otvoriť \"%s\"",
"ZIP download is turned off." => "Sťahovanie súborov ZIP je vypnuté.",
"Files need to be downloaded one by one." => "Súbory musia byť nahrávané jeden za druhým.",
"Back to Files" => "Späť na súbory",
"Selected files too large to generate zip file." => "Zvolené súbory sú príliš veľké na vygenerovanie zip súboru.",
+"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Stiahnite súbory po menších častiach, samostatne, alebo sa obráťte na správcu.",
"couldn't be determined" => "nedá sa zistiť",
"Application is not enabled" => "Aplikácia nie je zapnutá",
"Authentication error" => "Chyba autentifikácie",
@@ -49,5 +53,7 @@
"%d months ago" => "Pred %d mesiacmi.",
"last year" => "minulý rok",
"years ago" => "pred rokmi",
+"Caused by:" => "Príčina:",
"Could not find category \"%s\"" => "Nemožno nájsť danú kategóriu \"%s\""
);
+$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;";
diff --git a/lib/l10n/sl.php b/lib/l10n/sl.php
index a5b4decd61a..bffc6d5929b 100644
--- a/lib/l10n/sl.php
+++ b/lib/l10n/sl.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Pomoč",
"Personal" => "Osebno",
"Settings" => "Nastavitve",
@@ -51,3 +52,4 @@
"years ago" => "let nazaj",
"Could not find category \"%s\"" => "Kategorije \"%s\" ni mogoče najti."
);
+$PLURAL_FORMS = "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);";
diff --git a/lib/l10n/sq.php b/lib/l10n/sq.php
index df5e2a31743..9a332bc671e 100644
--- a/lib/l10n/sq.php
+++ b/lib/l10n/sq.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Ndihmë",
"Personal" => "Personale",
"Settings" => "Parametra",
@@ -50,3 +51,4 @@
"years ago" => "vite më parë",
"Could not find category \"%s\"" => "Kategoria \"%s\" nuk u gjet"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/sr.php b/lib/l10n/sr.php
index 71d627e7890..a42df978b4d 100644
--- a/lib/l10n/sr.php
+++ b/lib/l10n/sr.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Помоћ",
"Personal" => "Лично",
"Settings" => "Поставке",
@@ -33,3 +34,4 @@
"years ago" => "година раније",
"Could not find category \"%s\"" => "Не могу да пронађем категорију „%s“."
);
+$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/sr@latin.php b/lib/l10n/sr@latin.php
index 13cedc83279..a0c46c2487b 100644
--- a/lib/l10n/sr@latin.php
+++ b/lib/l10n/sr@latin.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Pomoć",
"Personal" => "Lično",
"Settings" => "Podešavanja",
@@ -9,3 +10,4 @@
"Files" => "Fajlovi",
"Text" => "Tekst"
);
+$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/string.php b/lib/l10n/string.php
index 8eef10071e6..88c85b32e70 100644
--- a/lib/l10n/string.php
+++ b/lib/l10n/string.php
@@ -7,19 +7,50 @@
*/
class OC_L10N_String{
+ /**
+ * @var OC_L10N
+ */
protected $l10n;
- public function __construct($l10n, $text, $parameters) {
+
+ /**
+ * @var string
+ */
+ protected $text;
+
+ /**
+ * @var array
+ */
+ protected $parameters;
+
+ /**
+ * @var integer
+ */
+ protected $count;
+
+ public function __construct($l10n, $text, $parameters, $count = 1) {
$this->l10n = $l10n;
$this->text = $text;
$this->parameters = $parameters;
-
+ $this->count = $count;
}
public function __toString() {
$translations = $this->l10n->getTranslations();
+
+ $text = $this->text;
if(array_key_exists($this->text, $translations)) {
- return vsprintf($translations[$this->text], $this->parameters);
+ if(is_array($translations[$this->text])) {
+ $fn = $this->l10n->getPluralFormFunction();
+ $id = $fn($this->count);
+ $text = $translations[$this->text][$id];
+ }
+ else{
+ $text = $translations[$this->text];
+ }
}
- return vsprintf($this->text, $this->parameters);
+
+ // Replace %n first (won't interfere with vsprintf)
+ $text = str_replace('%n', $this->count, $text);
+ return vsprintf($text, $this->parameters);
}
}
diff --git a/lib/l10n/sv.php b/lib/l10n/sv.php
index 0e2e806b4f6..72e2d18654a 100644
--- a/lib/l10n/sv.php
+++ b/lib/l10n/sv.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Hjälp",
"Personal" => "Personligt",
"Settings" => "Inställningar",
@@ -55,3 +56,4 @@
"Caused by:" => "Orsakad av:",
"Could not find category \"%s\"" => "Kunde inte hitta kategorin \"%s\""
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/ta_LK.php b/lib/l10n/ta_LK.php
index 9193f6f1d2f..88b9de5f7d1 100644
--- a/lib/l10n/ta_LK.php
+++ b/lib/l10n/ta_LK.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "உதவி",
"Personal" => "தனிப்பட்ட",
"Settings" => "அமைப்புகள்",
@@ -30,3 +31,4 @@
"years ago" => "வருடங்களுக்கு முன்",
"Could not find category \"%s\"" => "பிரிவு \"%s\" ஐ கண்டுப்பிடிக்க முடியவில்லை"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/te.php b/lib/l10n/te.php
index 87c73d790e2..e7d9d921e5e 100644
--- a/lib/l10n/te.php
+++ b/lib/l10n/te.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "సహాయం",
"Settings" => "అమరికలు",
"Users" => "వాడుకరులు",
@@ -11,3 +12,4 @@
"last year" => "పోయిన సంవత్సరం",
"years ago" => "సంవత్సరాల క్రితం"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/th_TH.php b/lib/l10n/th_TH.php
index 4ec6ef55f4e..25c2d8f1f2a 100644
--- a/lib/l10n/th_TH.php
+++ b/lib/l10n/th_TH.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "ช่วยเหลือ",
"Personal" => "ส่วนตัว",
"Settings" => "ตั้งค่า",
@@ -31,3 +32,4 @@
"years ago" => "ปี ที่ผ่านมา",
"Could not find category \"%s\"" => "ไม่พบหมวดหมู่ \"%s\""
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/tr.php b/lib/l10n/tr.php
index 6325ad9886a..233b99e6373 100644
--- a/lib/l10n/tr.php
+++ b/lib/l10n/tr.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Yardım",
"Personal" => "Kişisel",
"Settings" => "Ayarlar",
@@ -51,3 +52,4 @@
"years ago" => "yıl önce",
"Could not find category \"%s\"" => "\"%s\" kategorisi bulunamadı"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n > 1);";
diff --git a/lib/l10n/ug.php b/lib/l10n/ug.php
index 62d91616c1d..cf460cd3024 100644
--- a/lib/l10n/ug.php
+++ b/lib/l10n/ug.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "ياردەم",
"Personal" => "شەخسىي",
"Settings" => "تەڭشەكلەر",
@@ -17,3 +18,4 @@
"%d days ago" => "%d كۈن ئىلگىرى",
"%d months ago" => "%d ئاي ئىلگىرى"
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/uk.php b/lib/l10n/uk.php
index 7ff7829e1a2..c52aa5dfc77 100644
--- a/lib/l10n/uk.php
+++ b/lib/l10n/uk.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Допомога",
"Personal" => "Особисте",
"Settings" => "Налаштування",
@@ -50,3 +51,4 @@
"years ago" => "роки тому",
"Could not find category \"%s\"" => "Не вдалося знайти категорію \"%s\""
);
+$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/ur_PK.php b/lib/l10n/ur_PK.php
index 21e711c6df5..57f77d46059 100644
--- a/lib/l10n/ur_PK.php
+++ b/lib/l10n/ur_PK.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "مدد",
"Personal" => "ذاتی",
"Settings" => "سیٹینگز",
@@ -7,3 +8,4 @@
"Admin" => "ایڈمن",
"web services under your control" => "آپ کے اختیار میں ویب سروسیز"
);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/vi.php b/lib/l10n/vi.php
index f2a7d669b8f..c3ec50b41f9 100644
--- a/lib/l10n/vi.php
+++ b/lib/l10n/vi.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "Giúp đỡ",
"Personal" => "Cá nhân",
"Settings" => "Cài đặt",
@@ -31,3 +32,4 @@
"years ago" => "năm trước",
"Could not find category \"%s\"" => "không thể tìm thấy mục \"%s\""
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/zh_CN.GB2312.php b/lib/l10n/zh_CN.GB2312.php
index 4780a69eb34..9d7237bd198 100644
--- a/lib/l10n/zh_CN.GB2312.php
+++ b/lib/l10n/zh_CN.GB2312.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "帮助",
"Personal" => "私人",
"Settings" => "设置",
@@ -29,3 +30,4 @@
"last year" => "去年",
"years ago" => "年前"
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/zh_CN.php b/lib/l10n/zh_CN.php
index 7630f885c4a..4469f0fb1e4 100644
--- a/lib/l10n/zh_CN.php
+++ b/lib/l10n/zh_CN.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "帮助",
"Personal" => "个人",
"Settings" => "设置",
@@ -51,3 +52,4 @@
"years ago" => "年前",
"Could not find category \"%s\"" => "无法找到分类 \"%s\""
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/zh_HK.php b/lib/l10n/zh_HK.php
index cfa33ec36f5..f5fc48366ff 100644
--- a/lib/l10n/zh_HK.php
+++ b/lib/l10n/zh_HK.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "幫助",
"Personal" => "個人",
"Settings" => "設定",
@@ -11,3 +12,4 @@
"yesterday" => "昨日",
"last month" => "前一月"
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/zh_TW.php b/lib/l10n/zh_TW.php
index afd196f7c82..81b66b93296 100644
--- a/lib/l10n/zh_TW.php
+++ b/lib/l10n/zh_TW.php
@@ -1,4 +1,5 @@
-<?php $TRANSLATIONS = array(
+<?php
+$TRANSLATIONS = array(
"Help" => "說明",
"Personal" => "個人",
"Settings" => "設定",
@@ -51,3 +52,4 @@
"years ago" => "幾年前",
"Could not find category \"%s\"" => "找不到分類:\"%s\""
);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/user.php b/lib/user.php
index ee20f2e0971..93c7c9d4cd5 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -137,7 +137,6 @@ class OC_User {
*/
public static function useBackend($backend = 'database') {
if ($backend instanceof OC_User_Interface) {
- OC_Log::write('core', 'Adding user backend instance of ' . get_class($backend) . '.', OC_Log::DEBUG);
self::$_usedBackends[get_class($backend)] = $backend;
self::getManager()->registerBackend($backend);
} else {