diff options
author | Robin Appelman <icewind@owncloud.com> | 2014-02-07 13:42:18 +0100 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2014-02-07 13:45:59 +0100 |
commit | b537d90e58913be203fd96f31b624559be00abeb (patch) | |
tree | 9af6c432b3b503303f1315f82f602844664f837d /lib/private | |
parent | b35b22977cfc9412278ae70b49c402a95efca19e (diff) | |
parent | b9e724d4ae7635435b3cc7793237c3ab9fe2a1c0 (diff) | |
download | nextcloud-server-b537d90e58913be203fd96f31b624559be00abeb.tar.gz nextcloud-server-b537d90e58913be203fd96f31b624559be00abeb.zip |
use the 'new' server container for appconfig
Diffstat (limited to 'lib/private')
214 files changed, 3653 insertions, 5212 deletions
diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php new file mode 100755 index 00000000000..7e7e2257874 --- /dev/null +++ b/lib/private/activitymanager.php @@ -0,0 +1,69 @@ +<?php +/** + * Copyright (c) 2013 Thomas Müller thomas.mueller@tmit.eu + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ +namespace OC; + + +use OCP\Activity\IConsumer; +use OCP\Activity\IManager; + +class ActivityManager implements IManager { + + private $consumers = array(); + + /** + * @param $app + * @param $subject + * @param $subjectParams + * @param $message + * @param $messageParams + * @param $file + * @param $link + * @param $affectedUser + * @param $type + * @param $priority + * @return mixed + */ + function publishActivity($app, $subject, $subjectParams, $message, $messageParams, $file, $link, $affectedUser, $type, $priority) { + foreach($this->consumers as $consumer) { + $c = $consumer(); + if ($c instanceof IConsumer) { + try { + $c->receive( + $app, + $subject, + $subjectParams, + $message, + $messageParams, + $file, + $link, + $affectedUser, + $type, + $priority); + } catch (\Exception $ex) { + // TODO: log the excepetion + } + } + + } + } + + /** + * In order to improve lazy loading a closure can be registered which will be called in case + * activity consumers are actually requested + * + * $callable has to return an instance of OCA\Activity\IConsumer + * + * @param string $key + * @param \Closure $callable + */ + function registerConsumer(\Closure $callable) { + array_push($this->consumers, $callable); + } + +} diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php index 72aabf60793..a4aa69d43fb 100644 --- a/lib/private/allconfig.php +++ b/lib/private/allconfig.php @@ -4,7 +4,7 @@ * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. - * + * */ namespace OC; @@ -15,6 +15,7 @@ namespace OC; class AllConfig implements \OCP\IConfig { /** * Sets a new system wide value + * * @param string $key the key of the value, under which will be saved * @param string $value the value that should be stored * @todo need a use case for this @@ -25,16 +26,19 @@ class AllConfig implements \OCP\IConfig { /** * Looks up a system wide defined value + * * @param string $key the key of the value, under which it was saved + * @param string $default the default value to be returned if the value isn't set * @return string the saved value */ - public function getSystemValue($key) { - return \OCP\Config::getSystemValue($key, ''); + public function getSystemValue($key, $default = '') { + return \OCP\Config::getSystemValue($key, $default); } /** * Writes a new app wide value + * * @param string $appName the appName that we want to store the value under * @param string $key the key of the value, under which will be saved * @param string $value the value that should be stored @@ -45,17 +49,20 @@ class AllConfig implements \OCP\IConfig { /** * Looks up an app wide defined value + * * @param string $appName the appName that we stored the value under * @param string $key the key of the value, under which it was saved + * @param string $default the default value to be returned if the value isn't set * @return string the saved value */ - public function getAppValue($appName, $key) { - return \OCP\Config::getAppValue($appName, $key, ''); + public function getAppValue($appName, $key, $default = '') { + return \OCP\Config::getAppValue($appName, $key, $default); } /** * Set a user defined value + * * @param string $userId the userId of the user that we want to store the value under * @param string $appName the appName that we want to store the value under * @param string $key the key under which the value is being stored @@ -67,11 +74,14 @@ class AllConfig implements \OCP\IConfig { /** * Shortcut for getting a user defined value + * * @param string $userId the userId of the user that we want to store the value under * @param string $appName the appName that we stored the value under * @param string $key the key under which the value is being stored + * @param string $default the default value to be returned if the value isn't set + * @return string */ - public function getUserValue($userId, $appName, $key){ - return \OCP\Config::getUserValue($userId, $appName, $key); + public function getUserValue($userId, $appName, $key, $default = '') { + return \OCP\Config::getUserValue($userId, $appName, $key, $default); } } diff --git a/lib/private/api.php b/lib/private/api.php index 31f3f968d9b..c713368125c 100644 --- a/lib/private/api.php +++ b/lib/private/api.php @@ -33,7 +33,7 @@ class OC_API { const USER_AUTH = 1; const SUBADMIN_AUTH = 2; const ADMIN_AUTH = 3; - + /** * API Response Codes */ @@ -41,12 +41,13 @@ class OC_API { const RESPOND_SERVER_ERROR = 996; const RESPOND_NOT_FOUND = 998; const RESPOND_UNKNOWN_ERROR = 999; - + /** * api actions */ protected static $actions = array(); - + private static $logoutRequired = false; + /** * registers an api call * @param string $method the http method @@ -57,7 +58,7 @@ class OC_API { * @param array $defaults * @param array $requirements */ - public static function register($method, $url, $action, $app, + public static function register($method, $url, $action, $app, $authLevel = OC_API::USER_AUTH, $defaults = array(), $requirements = array()) { @@ -74,7 +75,7 @@ class OC_API { } self::$actions[$name][] = array('app' => $app, 'action' => $action, 'authlevel' => $authLevel); } - + /** * handles an api call * @param array $parameters @@ -95,6 +96,7 @@ class OC_API { $responses[] = array( 'app' => $action['app'], 'response' => new OC_OCS_Result(null, OC_API::RESPOND_UNAUTHORISED, 'Unauthorised'), + 'shipped' => OC_App::isShipped($action['app']), ); continue; } @@ -102,6 +104,7 @@ class OC_API { $responses[] = array( 'app' => $action['app'], 'response' => new OC_OCS_Result(null, OC_API::RESPOND_NOT_FOUND, 'Api method not found'), + 'shipped' => OC_App::isShipped($action['app']), ); continue; } @@ -109,22 +112,25 @@ class OC_API { $responses[] = array( 'app' => $action['app'], 'response' => call_user_func($action['action'], $parameters), + 'shipped' => OC_App::isShipped($action['app']), ); } $response = self::mergeResponses($responses); $formats = array('json', 'xml'); $format = !empty($_GET['format']) && in_array($_GET['format'], $formats) ? $_GET['format'] : 'xml'; - OC_User::logout(); + if (self::$logoutRequired) { + OC_User::logout(); + } self::respond($response, $format); } - + /** * merge the returned result objects into one response * @param array $responses */ - private static function mergeResponses($responses) { + public static function mergeResponses($responses) { $response = array(); // Sort into shipped and thirdparty $shipped = array( @@ -137,53 +143,81 @@ class OC_API { ); foreach($responses as $response) { - if(OC_App::isShipped($response['app']) || ($response['app'] === 'core')) { + if($response['shipped'] || ($response['app'] === 'core')) { if($response['response']->succeeded()) { - $shipped['succeeded'][$response['app']] = $response['response']; + $shipped['succeeded'][$response['app']] = $response; } else { - $shipped['failed'][$response['app']] = $response['response']; + $shipped['failed'][$response['app']] = $response; } } else { if($response['response']->succeeded()) { - $thirdparty['succeeded'][$response['app']] = $response['response']; + $thirdparty['succeeded'][$response['app']] = $response; } else { - $thirdparty['failed'][$response['app']] = $response['response']; + $thirdparty['failed'][$response['app']] = $response; } } } // Remove any error responses if there is one shipped response that succeeded - if(!empty($shipped['succeeded'])) { - $responses = array_merge($shipped['succeeded'], $thirdparty['succeeded']); - } else if(!empty($shipped['failed'])) { + if(!empty($shipped['failed'])) { // Which shipped response do we use if they all failed? // They may have failed for different reasons (different status codes) // Which reponse code should we return? // Maybe any that are not OC_API::RESPOND_SERVER_ERROR - $response = reset($shipped['failed']); + // Merge failed responses if more than one + $data = array(); + foreach($shipped['failed'] as $failure) { + $data = array_merge_recursive($data, $failure['response']->getData()); + } + $picked = reset($shipped['failed']); + $code = $picked['response']->getStatusCode(); + $meta = $picked['response']->getMeta(); + $response = new OC_OCS_Result($data, $code, $meta['message']); return $response; + } elseif(!empty($shipped['succeeded'])) { + $responses = array_merge($shipped['succeeded'], $thirdparty['succeeded']); } elseif(!empty($thirdparty['failed'])) { - // Return the third party failure result - $response = reset($thirdparty['failed']); + // Merge failed responses if more than one + $data = array(); + foreach($thirdparty['failed'] as $failure) { + $data = array_merge_recursive($data, $failure['response']->getData()); + } + $picked = reset($thirdparty['failed']); + $code = $picked['response']->getStatusCode(); + $meta = $picked['response']->getMeta(); + $response = new OC_OCS_Result($data, $code, $meta['message']); return $response; } else { - $responses = array_merge($shipped['succeeded'], $thirdparty['succeeded']); + $responses = $thirdparty['succeeded']; } // Merge the successful responses - $meta = array(); $data = array(); foreach($responses as $app => $response) { - if(OC_App::isShipped($app)) { - $data = array_merge_recursive($response->getData(), $data); + if($response['shipped']) { + $data = array_merge_recursive($response['response']->getData(), $data); } else { - $data = array_merge_recursive($data, $response->getData()); + $data = array_merge_recursive($data, $response['response']->getData()); + } + $codes[] = array('code' => $response['response']->getStatusCode(), + 'meta' => $response['response']->getMeta()); + } + + // Use any non 100 status codes + $statusCode = 100; + $statusMessage = null; + foreach($codes as $code) { + if($code['code'] != 100) { + $statusCode = $code['code']; + $statusMessage = $code['meta']['message']; + break; } } - $result = new OC_OCS_Result($data, 100); + + $result = new OC_OCS_Result($data, $statusCode, $statusMessage); return $result; } - + /** * authenticate the api call * @param array $action the action details as supplied to OC_API::register() @@ -229,18 +263,40 @@ class OC_API { return false; break; } - } - + } + /** * http basic auth * @return string|false (username, or false on failure) */ - private static function loginUser(){ + private static function loginUser(){ + // basic auth $authUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : ''; $authPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : ''; - return OC_User::login($authUser, $authPw) ? $authUser : false; + $return = OC_User::login($authUser, $authPw); + if ($return === true) { + self::$logoutRequired = true; + + // initialize the user's filesystem + \OC_Util::setUpFS(\OC_User::getUser()); + + return $authUser; + } + + // reuse existing login + $loggedIn = OC_User::isLoggedIn(); + $ocsApiRequest = isset($_SERVER['HTTP_OCS_APIREQUEST']) ? $_SERVER['HTTP_OCS_APIREQUEST'] === 'true' : false; + if ($loggedIn === true && $ocsApiRequest) { + + // initialize the user's filesystem + \OC_Util::setUpFS(\OC_User::getUser()); + + return OC_User::getUser(); + } + + return false; } - + /** * respond to a call * @param OC_OCS_Result $result @@ -289,5 +345,5 @@ class OC_API { } } } - + } diff --git a/lib/private/app.php b/lib/private/app.php index 0ab1ee57f63..da09021cf3f 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -63,8 +63,8 @@ class OC_App{ ob_start(); foreach( $apps as $app ) { if((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) { - self::loadApp($app); self::$loadedApps[] = $app; + self::loadApp($app); } } ob_end_clean(); @@ -165,17 +165,23 @@ class OC_App{ /** * get all enabled apps */ - public static function getEnabledApps() { + private static $enabledAppsCache = array(); + public static function getEnabledApps($forceRefresh = false) { if(!OC_Config::getValue('installed', false)) { return array(); } + if(!$forceRefresh && !empty(self::$enabledAppsCache)) { + return self::$enabledAppsCache; + } $apps=array('files'); $sql = 'SELECT `appid` FROM `*PREFIX*appconfig`' - .' WHERE `configkey` = \'enabled\' AND `configvalue`=\'yes\''; + . ' WHERE `configkey` = \'enabled\' AND `configvalue`=\'yes\'' + . ' ORDER BY `appid`'; if (OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { //FIXME oracle hack: need to explicitly cast CLOB to CHAR for comparison $sql = 'SELECT `appid` FROM `*PREFIX*appconfig`' - .' WHERE `configkey` = \'enabled\' AND to_char(`configvalue`)=\'yes\''; + . ' WHERE `configkey` = \'enabled\' AND to_char(`configvalue`)=\'yes\'' + . ' ORDER BY `appid`'; } $query = OC_DB::prepare( $sql ); $result=$query->execute(); @@ -187,6 +193,7 @@ class OC_App{ $apps[]=$row['appid']; } } + self::$enabledAppsCache = $apps; return $apps; } @@ -198,11 +205,11 @@ class OC_App{ * This function checks whether or not an app is enabled. */ public static function isEnabled( $app ) { - if( 'files'==$app or ('yes' == OC_Appconfig::getValue( $app, 'enabled' ))) { + if('files' == $app) { return true; } - - return false; + $enabledApps = self::getEnabledApps(); + return in_array($app, $enabledApps); } /** @@ -214,6 +221,7 @@ class OC_App{ * This function set an app as enabled in appconfig. */ public static function enable( $app ) { + self::$enabledAppsCache = array(); // flush if(!OC_Installer::isInstalled($app)) { // check if app is a shipped app or not. OCS apps have an integer as id, shipped apps use a string if(!is_numeric($app)) { @@ -243,6 +251,7 @@ class OC_App{ if(isset($appdata['id'])) { OC_Appconfig::setValue( $app, 'ocsid', $appdata['id'] ); } + \OC_Hook::emit('OC_App', 'post_enable', array('app' => $app)); } }else{ throw new \Exception($l->t("No app name specified")); @@ -257,6 +266,7 @@ class OC_App{ * This function set an app as disabled in appconfig. */ public static function disable( $app ) { + self::$enabledAppsCache = array(); // flush // check if app is a shipped app or not. if not delete \OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app)); OC_Appconfig::setValue( $app, 'enabled', 'no' ); @@ -545,6 +555,10 @@ class OC_App{ }elseif($child->getName()=='description') { $xml=(string)$child->asXML(); $data[$child->getName()]=substr($xml, 13, -14);//script <description> tags + }elseif($child->getName()=='documentation') { + foreach($child as $subchild) { + $data["documentation"][$subchild->getName()] = (string)$subchild; + } }else{ $data[$child->getName()]=(string)$child; } @@ -745,10 +759,43 @@ class OC_App{ } else { $combinedApps = $appList; } + // bring the apps into the right order with a custom sort funtion + usort( $combinedApps, '\OC_App::customSort' ); + return $combinedApps; } /** + * @brief: Internal custom sort funtion to bring the app into the right order. Should only be called by listAllApps + * @return array + */ + private static function customSort($a, $b) { + + // prio 1: active + if ($a['active'] != $b['active']) { + return $b['active'] - $a['active']; + } + + // prio 2: shipped + $ashipped = (array_key_exists('shipped', $a) && $a['shipped'] === 'true') ? 1 : 0; + $bshipped = (array_key_exists('shipped', $b) && $b['shipped'] === 'true') ? 1 : 0; + if ($ashipped !== $bshipped) { + return ($bshipped - $ashipped); + } + + // prio 3: recommended + if ($a['internalclass'] != $b['internalclass']) { + $atemp = ($a['internalclass'] == 'recommendedapp' ? 1 : 0); + $btemp = ($b['internalclass'] == 'recommendedapp' ? 1 : 0); + return ($btemp - $atemp); + } + + // prio 4: alphabetical + return strcasecmp($a['name'], $b['name']); + + } + + /** * @brief: get a list of all apps on apps.owncloud.com * @return array, multi-dimensional array of apps. * Keys: id, name, type, typename, personid, license, detailpage, preview, changed, description diff --git a/lib/private/appconfig.php b/lib/private/appconfig.php index 7c84faf7f16..ff47f08d485 100644 --- a/lib/private/appconfig.php +++ b/lib/private/appconfig.php @@ -41,7 +41,7 @@ use \OC\DB\Connection; * This class provides an easy way for apps to store config values in the * database. */ -class AppConfig { +class AppConfig implements \OCP\IAppConfig { /** * @var \OC\DB\Connection $conn */ @@ -104,7 +104,7 @@ class AppConfig { */ public function getValue($app, $key, $default = null) { $query = 'SELECT `configvalue` FROM `*PREFIX*appconfig`' - .' WHERE `appid` = ? AND `configkey` = ?'; + . ' WHERE `appid` = ? AND `configkey` = ?'; $row = $this->conn->fetchAssoc($query, array($app, $key)); if ($row) { return $row['configvalue']; @@ -185,6 +185,7 @@ class AppConfig { /** * get multiply values, either the app or key can be used as wildcard by setting it to false + * * @param app * @param key * @return array @@ -208,8 +209,8 @@ class AppConfig { $params[] = $key; $key = 'appid'; } - $query = 'SELECT '.$fields.' FROM `*PREFIX*appconfig` '.$where; - $result = $this->conn->executeQuery( $query, $params ); + $query = 'SELECT ' . $fields . ' FROM `*PREFIX*appconfig` ' . $where; + $result = $this->conn->executeQuery($query, $params); $values = array(); while ($row = $result->fetch((\PDO::FETCH_ASSOC))) { @@ -218,4 +219,4 @@ class AppConfig { return $values; } -}
\ No newline at end of file +} diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php index 7ff55bb809d..b835188661a 100644 --- a/lib/private/appframework/app.php +++ b/lib/private/appframework/app.php @@ -42,12 +42,13 @@ class App { * @param string $controllerName the name of the controller under which it is * stored in the DI container * @param string $methodName the method that you want to call - * @param array $urlParams an array with variables extracted from the routes * @param DIContainer $container an instance of a pimple container. + * @param array $urlParams list of URL parameters (optional) */ - public static function main($controllerName, $methodName, array $urlParams, - IAppContainer $container) { - $container['urlParams'] = $urlParams; + public static function main($controllerName, $methodName, DIContainer $container, array $urlParams = null) { + if (!is_null($urlParams)) { + $container['urlParams'] = $urlParams; + } $controller = $container[$controllerName]; // initialize the dispatcher and run all the middleware before the controller diff --git a/lib/private/appframework/controller/controller.php b/lib/private/appframework/controller/controller.php deleted file mode 100644 index 0ea0a38cc09..00000000000 --- a/lib/private/appframework/controller/controller.php +++ /dev/null @@ -1,142 +0,0 @@ -<?php - -/** - * ownCloud - App Framework - * - * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -namespace OC\AppFramework\Controller; - -use OC\AppFramework\Http\Request; -use OC\AppFramework\Core\API; -use OCP\AppFramework\Http\TemplateResponse; - - -/** - * Base class to inherit your controllers from - */ -abstract class Controller { - - /** - * @var API instance of the api layer - */ - protected $api; - - protected $request; - - /** - * @param API $api an api wrapper instance - * @param Request $request an instance of the request - */ - public function __construct(API $api, Request $request){ - $this->api = $api; - $this->request = $request; - } - - - /** - * Lets you access post and get parameters by the index - * @param string $key the key which you want to access in the URL Parameter - * placeholder, $_POST or $_GET array. - * The priority how they're returned is the following: - * 1. URL parameters - * 2. POST parameters - * 3. GET parameters - * @param mixed $default If the key is not found, this value will be returned - * @return mixed the content of the array - */ - public function params($key, $default=null){ - return $this->request->getParam($key, $default); - } - - - /** - * Returns all params that were received, be it from the request - * (as GET or POST) or throuh the URL by the route - * @return array the array with all parameters - */ - public function getParams() { - return $this->request->getParams(); - } - - - /** - * Returns the method of the request - * @return string the method of the request (POST, GET, etc) - */ - public function method() { - return $this->request->getMethod(); - } - - - /** - * Shortcut for accessing an uploaded file through the $_FILES array - * @param string $key the key that will be taken from the $_FILES array - * @return array the file in the $_FILES element - */ - public function getUploadedFile($key) { - return $this->request->getUploadedFile($key); - } - - - /** - * Shortcut for getting env variables - * @param string $key the key that will be taken from the $_ENV array - * @return array the value in the $_ENV element - */ - public function env($key) { - return $this->request->getEnv($key); - } - - - /** - * Shortcut for getting cookie variables - * @param string $key the key that will be taken from the $_COOKIE array - * @return array the value in the $_COOKIE element - */ - public function cookie($key) { - return $this->request->getCookie($key); - } - - - /** - * Shortcut for rendering a template - * @param string $templateName the name of the template - * @param array $params the template parameters in key => value structure - * @param string $renderAs user renders a full page, blank only your template - * admin an entry in the admin settings - * @param array $headers set additional headers in name/value pairs - * @return \OCP\AppFramework\Http\TemplateResponse containing the page - */ - public function render($templateName, array $params=array(), - $renderAs='user', array $headers=array()){ - $response = new TemplateResponse($this->api, $templateName); - $response->setParams($params); - $response->renderAs($renderAs); - - foreach($headers as $name => $value){ - $response->addHeader($name, $value); - } - - return $response; - } - - -} diff --git a/lib/private/appframework/core/api.php b/lib/private/appframework/core/api.php index 39522ee3dd5..e7269373bb0 100644 --- a/lib/private/appframework/core/api.php +++ b/lib/private/appframework/core/api.php @@ -100,89 +100,6 @@ class API implements IApi{ /** - * Returns the translation object - * @return \OC_L10N the translation object - */ - public function getTrans(){ - # TODO: use public api - return \OC_L10N::get($this->appName); - } - - - /** - * Returns the URL for a route - * @param string $routeName the name of the route - * @param array $arguments an array with arguments which will be filled into the url - * @return string the url - */ - public function linkToRoute($routeName, $arguments=array()){ - return \OCP\Util::linkToRoute($routeName, $arguments); - } - - - /** - * Returns an URL for an image or file - * @param string $file the name of the file - * @param string $appName the name of the app, defaults to the current one - */ - public function linkTo($file, $appName=null){ - if($appName === null){ - $appName = $this->appName; - } - return \OCP\Util::linkTo($appName, $file); - } - - - /** - * Returns the link to an image, like link to but only with prepending img/ - * @param string $file the name of the file - * @param string $appName the name of the app, defaults to the current one - */ - public function imagePath($file, $appName=null){ - if($appName === null){ - $appName = $this->appName; - } - return \OCP\Util::imagePath($appName, $file); - } - - - /** - * Makes an URL absolute - * @param string $url the url - * @return string the absolute url - */ - public function getAbsoluteURL($url){ - # TODO: use public api - return \OC_Helper::makeURLAbsolute($url); - } - - - /** - * links to a file - * @param string $file the name of the file - * @param string $appName the name of the app, defaults to the current one - * @deprecated replaced with linkToRoute() - * @return string the url - */ - public function linkToAbsolute($file, $appName=null){ - if($appName === null){ - $appName = $this->appName; - } - return \OCP\Util::linkToAbsolute($appName, $file); - } - - - /** - * Checks if the CSRF check was correct - * @return bool true if CSRF check passed - */ - public function passesCSRFCheck(){ - # TODO: use public api - return \OC_Util::isCallRegistered(); - } - - - /** * Checks if an app is enabled * @param string $appName the name of an app * @return bool true if app is enabled @@ -193,44 +110,6 @@ class API implements IApi{ /** - * Writes a function into the error log - * @param string $msg the error message to be logged - * @param int $level the error level - */ - public function log($msg, $level=null){ - switch($level){ - case 'debug': - $level = \OCP\Util::DEBUG; - break; - case 'info': - $level = \OCP\Util::INFO; - break; - case 'warn': - $level = \OCP\Util::WARN; - break; - case 'fatal': - $level = \OCP\Util::FATAL; - break; - default: - $level = \OCP\Util::ERROR; - break; - } - \OCP\Util::writeLog($this->appName, $msg, $level); - } - - - /** - * turns an owncloud path into a path on the filesystem - * @param string path the path to the file on the oc filesystem - * @return string the filepath in the filesystem - */ - public function getLocalFilePath($path){ - # TODO: use public api - return \OC_Filesystem::getLocalFile($path); - } - - - /** * used to return and open a new eventsource * @return \OC_EventSource a new open EventSource class */ @@ -275,15 +154,6 @@ class API implements IApi{ } } - /** - * Gets the content of an URL by using CURL or a fallback if it is not - * installed - * @param string $url the url that should be fetched - * @return string the content of the webpage - */ - public function getUrlContent($url) { - return \OC_Util::getUrlContent($url); - } /** * Register a backgroundjob task @@ -295,25 +165,6 @@ class API implements IApi{ \OCP\Backgroundjob::addRegularTask($className, $methodName); } - /** - * Returns a template - * @param string $templateName the name of the template - * @param string $renderAs how it should be rendered - * @param string $appName the name of the app - * @return \OCP\Template a new template - */ - public function getTemplate($templateName, $renderAs='user', $appName=null){ - if($appName === null){ - $appName = $this->appName; - } - - if($renderAs === 'blank'){ - return new \OCP\Template($appName, $templateName); - } else { - return new \OCP\Template($appName, $templateName, $renderAs); - } - } - /** * Tells ownCloud to include a template in the admin overview @@ -330,19 +181,4 @@ class API implements IApi{ } - /** - * get the filesystem info - * - * @param string $path - * @return array with the following keys: - * - size - * - mtime - * - mimetype - * - encrypted - * - versioned - */ - public function getFileInfo($path) { - return \OC\Files\Filesystem::getFileInfo($path); - } - } diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php index 3755d45fa09..e2ea974e104 100644 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ b/lib/private/appframework/dependencyinjection/dicontainer.php @@ -24,7 +24,7 @@ namespace OC\AppFramework\DependencyInjection; -use OC\AppFramework\Http\Http; +use OC\AppFramework\Http; use OC\AppFramework\Http\Request; use OC\AppFramework\Http\Dispatcher; use OC\AppFramework\Core\API; @@ -35,6 +35,7 @@ use OC\AppFramework\Utility\TimeFactory; use OCP\AppFramework\IApi; use OCP\AppFramework\IAppContainer; use OCP\AppFramework\IMiddleWare; +use OCP\AppFramework\Middleware; use OCP\IServerContainer; @@ -49,9 +50,10 @@ class DIContainer extends SimpleContainer implements IAppContainer{ * Put your class dependencies in here * @param string $appName the name of the app */ - public function __construct($appName){ + public function __construct($appName, $urlParams = array()){ $this['AppName'] = $appName; + $this['urlParams'] = $urlParams; $this->registerParameter('ServerContainer', \OC::$server); @@ -66,6 +68,7 @@ class DIContainer extends SimpleContainer implements IAppContainer{ /** @var $c SimpleContainer */ /** @var $server IServerContainer */ $server = $c->query('ServerContainer'); + $server->registerParameter('urlParams', $c['urlParams']); return $server->getRequest(); }); @@ -85,15 +88,17 @@ class DIContainer extends SimpleContainer implements IAppContainer{ /** * Middleware */ - $this['SecurityMiddleware'] = $this->share(function($c){ - return new SecurityMiddleware($c['API'], $c['Request']); + $app = $this; + $this['SecurityMiddleware'] = $this->share(function($c) use ($app){ + return new SecurityMiddleware($app, $c['Request']); }); - $this['MiddlewareDispatcher'] = $this->share(function($c){ + $middleWares = $this->middleWares; + $this['MiddlewareDispatcher'] = $this->share(function($c) use ($middleWares) { $dispatcher = new MiddlewareDispatcher(); $dispatcher->registerMiddleware($c['SecurityMiddleware']); - foreach($this->middleWares as $middleWare) { + foreach($middleWares as $middleWare) { $dispatcher->registerMiddleware($middleWare); } @@ -129,10 +134,10 @@ class DIContainer extends SimpleContainer implements IAppContainer{ } /** - * @param IMiddleWare $middleWare + * @param Middleware $middleWare * @return boolean */ - function registerMiddleWare(IMiddleWare $middleWare) { + function registerMiddleWare(Middleware $middleWare) { array_push($this->middleWares, $middleWare); } @@ -143,4 +148,49 @@ class DIContainer extends SimpleContainer implements IAppContainer{ function getAppName() { return $this->query('AppName'); } + + /** + * @return boolean + */ + function isLoggedIn() { + return \OC_User::isLoggedIn(); + } + + /** + * @return boolean + */ + function isAdminUser() { + $uid = $this->getUserId(); + return \OC_User::isAdminUser($uid); + } + + private function getUserId() { + return \OC::$session->get('user_id'); + } + + /** + * @param $message + * @param $level + * @return mixed + */ + function log($message, $level) { + switch($level){ + case 'debug': + $level = \OCP\Util::DEBUG; + break; + case 'info': + $level = \OCP\Util::INFO; + break; + case 'warn': + $level = \OCP\Util::WARN; + break; + case 'fatal': + $level = \OCP\Util::FATAL; + break; + default: + $level = \OCP\Util::ERROR; + break; + } + \OCP\Util::writeLog($this->getAppName(), $message, $level); + } } diff --git a/lib/private/appframework/http/http.php b/lib/private/appframework/http.php index e00dc9cdc4a..41fc0db6b38 100644 --- a/lib/private/appframework/http/http.php +++ b/lib/private/appframework/http.php @@ -22,10 +22,11 @@ */ -namespace OC\AppFramework\Http; +namespace OC\AppFramework; +use OCP\AppFramework\Http as BaseHttp; -class Http extends \OCP\AppFramework\Http\Http{ +class Http extends BaseHttp { private $server; private $protocolVersion; diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/appframework/http/dispatcher.php index ea57a6860cc..a2afb53f0fa 100644 --- a/lib/private/appframework/http/dispatcher.php +++ b/lib/private/appframework/http/dispatcher.php @@ -24,8 +24,9 @@ namespace OC\AppFramework\Http; -use \OC\AppFramework\Controller\Controller; use \OC\AppFramework\Middleware\MiddlewareDispatcher; +use \OC\AppFramework\Http; +use OCP\AppFramework\Controller; /** diff --git a/lib/private/appframework/http/redirectresponse.php b/lib/private/appframework/http/redirectresponse.php index 688447f1618..c4e21059480 100644 --- a/lib/private/appframework/http/redirectresponse.php +++ b/lib/private/appframework/http/redirectresponse.php @@ -24,7 +24,8 @@ namespace OC\AppFramework\Http; -use OCP\AppFramework\Http\Response; +use OCP\AppFramework\Http\Response, + OCP\AppFramework\Http; /** diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index 34605acdfea..3e1f4ff87ed 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -31,6 +31,8 @@ use OCP\IRequest; class Request implements \ArrayAccess, \Countable, IRequest { + protected $inputStream; + protected $content; protected $items = array(); protected $allowedKeys = array( 'get', @@ -40,35 +42,48 @@ class Request implements \ArrayAccess, \Countable, IRequest { 'env', 'cookies', 'urlParams', - 'params', 'parameters', - 'method' + 'method', + 'requesttoken', ); /** * @param array $vars An associative array with the following optional values: - * @param array 'params' the parsed json array * @param array 'urlParams' the parameters which were matched from the URL * @param array 'get' the $_GET array - * @param array 'post' the $_POST array + * @param array|string 'post' the $_POST array or JSON string * @param array 'files' the $_FILES array * @param array 'server' the $_SERVER array * @param array 'env' the $_ENV array - * @param array 'session' the $_SESSION array * @param array 'cookies' the $_COOKIE array * @param string 'method' the request method (GET, POST etc) + * @param string|false 'requesttoken' the requesttoken or false when not available * @see http://www.php.net/manual/en/reserved.variables.php */ public function __construct(array $vars=array()) { foreach($this->allowedKeys as $name) { - $this->items[$name] = isset($vars[$name]) + $this->items[$name] = isset($vars[$name]) ? $vars[$name] : array(); } + if (defined('PHPUNIT_RUN') && PHPUNIT_RUN + && in_array('fakeinput', stream_get_wrappers())) { + $this->inputStream = 'fakeinput://data'; + } else { + $this->inputStream = 'php://input'; + } + + // Only 'application/x-www-form-urlencoded' requests are automatically + // transformed by PHP, 'application/json' must be decoded manually. + if ($this->method === 'POST' + && strpos($this->getHeader('Content-Type'), 'application/json') !== false + ) { + $this->items['params'] = $this->items['post'] = json_decode(file_get_contents($this->inputStream), true); + } + $this->items['parameters'] = array_merge( - $this->items['params'], $this->items['get'], $this->items['post'], $this->items['urlParams'] @@ -141,17 +156,22 @@ class Request implements \ArrayAccess, \Countable, IRequest { * $request->myvar; or $request->{'myvar'}; or $request->{$myvar} * Looks in the combined GET, POST and urlParams array. * - * if($request->method !== 'POST') { - * throw new Exception('This function can only be invoked using POST'); - * } + * If you access e.g. ->post but the current HTTP request method + * is GET a \LogicException will be thrown. * * @param string $name The key to look for. + * @throws \LogicException * @return mixed|null */ public function __get($name) { switch($name) { + case 'put': + case 'patch': case 'get': case 'post': + if($this->method !== strtoupper($name)) { + throw new \LogicException(sprintf('%s cannot be accessed in a %s request.', $name, $this->method)); + } case 'files': case 'server': case 'env': @@ -159,9 +179,13 @@ class Request implements \ArrayAccess, \Countable, IRequest { case 'parameters': case 'params': case 'urlParams': - return isset($this->items[$name]) - ? $this->items[$name] - : null; + if(in_array($name, array('put', 'patch'))) { + return $this->getContent($name); + } else { + return isset($this->items[$name]) + ? $this->items[$name] + : null; + } break; case 'method': return $this->items['method']; @@ -280,28 +304,86 @@ class Request implements \ArrayAccess, \Countable, IRequest { /** * Returns the request body content. * - * @param Boolean $asResource If true, a resource will be returned + * If the HTTP request method is PUT and the body + * not application/x-www-form-urlencoded or application/json a stream + * resource is returned, otherwise an array. * - * @return string|resource The request body content or a resource to read the body stream. + * @return array|string|resource The request body content or a resource to read the body stream. * * @throws \LogicException */ - function getContent($asResource = false) { - return null; -// if (false === $this->content || (true === $asResource && null !== $this->content)) { -// throw new \LogicException('getContent() can only be called once when using the resource return type.'); -// } -// -// if (true === $asResource) { -// $this->content = false; -// -// return fopen('php://input', 'rb'); -// } -// -// if (null === $this->content) { -// $this->content = file_get_contents('php://input'); -// } -// -// return $this->content; + protected function getContent() { + if ($this->content === false && $this->method === 'PUT') { + throw new \LogicException( + '"put" can only be accessed once if not ' + . 'application/x-www-form-urlencoded or application/json.' + ); + } + + // If the content can't be parsed into an array then return a stream resource. + if ($this->method === 'PUT' + && strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === false + && strpos($this->getHeader('Content-Type'), 'application/json') === false + ) { + $this->content = false; + return fopen($this->inputStream, 'rb'); + } + + if (is_null($this->content)) { + $this->content = file_get_contents($this->inputStream); + + /* + * Normal jquery ajax requests are sent as application/x-www-form-urlencoded + * and in $_GET and $_POST PHP transformes the data into an array. + * The first condition mimics this. + * The second condition allows for sending raw application/json data while + * still getting the result as an array. + * + */ + if (strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) { + parse_str($this->content, $content); + if(is_array($content)) { + $this->content = $content; + } + } elseif (strpos($this->getHeader('Content-Type'), 'application/json') !== false) { + $content = json_decode($this->content, true); + if(is_array($content)) { + $this->content = $content; + } + } + } + + return $this->content; } -} + + /** + * Checks if the CSRF check was correct + * @return bool true if CSRF check passed + * @see OC_Util::$callLifespan + * @see OC_Util::callRegister() + */ + public function passesCSRFCheck() { + if($this->items['requesttoken'] === false) { + return false; + } + + if (isset($this->items['get']['requesttoken'])) { + $token = $this->items['get']['requesttoken']; + } elseif (isset($this->items['post']['requesttoken'])) { + $token = $this->items['post']['requesttoken']; + } elseif (isset($this->items['server']['HTTP_REQUESTTOKEN'])) { + $token = $this->items['server']['HTTP_REQUESTTOKEN']; + } else { + //no token found. + return false; + } + + // Check if the token is valid + if($token !== $this->items['requesttoken']) { + // Not valid + return false; + } else { + // Valid token + return true; + } + }} diff --git a/lib/private/appframework/middleware/middleware.php b/lib/private/appframework/middleware/middleware.php deleted file mode 100644 index b12c03c3eb8..00000000000 --- a/lib/private/appframework/middleware/middleware.php +++ /dev/null @@ -1,100 +0,0 @@ -<?php - -/** - * ownCloud - App Framework - * - * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -namespace OC\AppFramework\Middleware; - -use OCP\AppFramework\Http\Response; - - -/** - * Middleware is used to provide hooks before or after controller methods and - * deal with possible exceptions raised in the controller methods. - * They're modeled after Django's middleware system: - * https://docs.djangoproject.com/en/dev/topics/http/middleware/ - */ -abstract class Middleware { - - - /** - * This is being run in normal order before the controller is being - * called which allows several modifications and checks - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - */ - public function beforeController($controller, $methodName){ - - } - - - /** - * This is being run when either the beforeController method or the - * controller method itself is throwing an exception. The middleware is - * asked in reverse order to handle the exception and to return a response. - * If the response is null, it is assumed that the exception could not be - * handled and the error will be thrown again - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @param \Exception $exception the thrown exception - * @throws \Exception the passed in exception if it cant handle it - * @return Response a Response object in case that the exception was handled - */ - public function afterException($controller, $methodName, \Exception $exception){ - throw $exception; - } - - - /** - * This is being run after a successful controllermethod call and allows - * the manipulation of a Response object. The middleware is run in reverse order - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @param Response $response the generated response from the controller - * @return Response a Response object - */ - public function afterController($controller, $methodName, Response $response){ - return $response; - } - - - /** - * This is being run after the response object has been rendered and - * allows the manipulation of the output. The middleware is run in reverse order - * - * @param Controller $controller the controller that is being called - * @param string $methodName the name of the method that will be called on - * the controller - * @param string $output the generated output from a response - * @return string the output that should be printed - */ - public function beforeOutput($controller, $methodName, $output){ - return $output; - } - -} diff --git a/lib/private/appframework/middleware/middlewaredispatcher.php b/lib/private/appframework/middleware/middlewaredispatcher.php index 70ab108e6b8..681140c2242 100644 --- a/lib/private/appframework/middleware/middlewaredispatcher.php +++ b/lib/private/appframework/middleware/middlewaredispatcher.php @@ -24,9 +24,9 @@ namespace OC\AppFramework\Middleware; -use OC\AppFramework\Controller\Controller; +use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Response; - +use OCP\AppFramework\MiddleWare; /** * This class is used to store and run all the middleware in correct order diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php index 4f1447e1afb..c3143754823 100644 --- a/lib/private/appframework/middleware/security/securitymiddleware.php +++ b/lib/private/appframework/middleware/security/securitymiddleware.php @@ -24,15 +24,14 @@ namespace OC\AppFramework\Middleware\Security; -use OC\AppFramework\Controller\Controller; -use OC\AppFramework\Http\Http; -use OC\AppFramework\Http\Request; +use OC\AppFramework\Http; use OC\AppFramework\Http\RedirectResponse; use OC\AppFramework\Utility\MethodAnnotationReader; -use OC\AppFramework\Middleware\Middleware; -use OC\AppFramework\Core\API; +use OCP\AppFramework\Middleware; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\IAppContainer; +use OCP\IRequest; /** @@ -43,18 +42,22 @@ use OCP\AppFramework\Http\JSONResponse; */ class SecurityMiddleware extends Middleware { - private $api; + /** + * @var \OCP\AppFramework\IAppContainer + */ + private $app; /** - * @var \OC\AppFramework\Http\Request + * @var \OCP\IRequest */ private $request; /** - * @param API $api an instance of the api + * @param IAppContainer $app + * @param IRequest $request */ - public function __construct(API $api, Request $request){ - $this->api = $api; + public function __construct(IAppContainer $app, IRequest $request){ + $this->app = $app; $this->request = $request; } @@ -74,24 +77,24 @@ class SecurityMiddleware extends Middleware { // this will set the current navigation entry of the app, use this only // for normal HTML requests and not for AJAX requests - $this->api->activateNavigationEntry(); + $this->app->getServer()->getNavigationManager()->setActiveEntry($this->app->getAppName()); // security checks $isPublicPage = $annotationReader->hasAnnotation('PublicPage'); if(!$isPublicPage) { - if(!$this->api->isLoggedIn()) { + if(!$this->app->isLoggedIn()) { throw new SecurityException('Current user is not logged in', Http::STATUS_UNAUTHORIZED); } if(!$annotationReader->hasAnnotation('NoAdminRequired')) { - if(!$this->api->isAdminUser($this->api->getUserId())) { + if(!$this->app->isAdminUser()) { throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN); } } } if(!$annotationReader->hasAnnotation('NoCSRFRequired')) { - if(!$this->api->passesCSRFCheck()) { + if(!$this->request->passesCSRFCheck()) { throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED); } } @@ -118,12 +121,13 @@ class SecurityMiddleware extends Middleware { array('message' => $exception->getMessage()), $exception->getCode() ); - $this->api->log($exception->getMessage(), 'debug'); + $this->app->log($exception->getMessage(), 'debug'); } else { - $url = $this->api->linkToAbsolute('index.php', ''); // TODO: replace with link to route + // TODO: replace with link to route + $url = $this->app->getServer()->getURLGenerator()->getAbsoluteURL('index.php'); $response = new RedirectResponse($url); - $this->api->log($exception->getMessage(), 'debug'); + $this->app->log($exception->getMessage(), 'debug'); } return $response; diff --git a/lib/private/appframework/routing/routeactionhandler.php b/lib/private/appframework/routing/routeactionhandler.php index 7fb56f14eab..2b9dc38dc43 100644 --- a/lib/private/appframework/routing/routeactionhandler.php +++ b/lib/private/appframework/routing/routeactionhandler.php @@ -37,6 +37,6 @@ class RouteActionHandler { } public function __invoke($params) { - App::main($this->controllerName, $this->actionName, $params, $this->container); + App::main($this->controllerName, $this->actionName, $this->container, $params); } } diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/appframework/utility/simplecontainer.php index 7e4db63bde5..e631e657756 100644 --- a/lib/private/appframework/utility/simplecontainer.php +++ b/lib/private/appframework/utility/simplecontainer.php @@ -3,7 +3,7 @@ namespace OC\AppFramework\Utility; // register 3rdparty autoloaders -require_once __DIR__ . '/../../../../3rdparty/Pimple/Pimple.php'; +require_once 'Pimple/Pimple.php'; /** * Class SimpleContainer diff --git a/lib/private/apphelper.php b/lib/private/apphelper.php new file mode 100644 index 00000000000..bd02f3aabfa --- /dev/null +++ b/lib/private/apphelper.php @@ -0,0 +1,25 @@ +<?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; + +/** + * TODO: Description + */ +class AppHelper implements \OCP\IHelper { + /** + * Gets the content of an URL by using CURL or a fallback if it is not + * installed + * @param string $url the url that should be fetched + * @return string the content of the webpage + */ + public function getUrlContent($url) { + return \OC_Util::getUrlContent($url); + } +} diff --git a/lib/private/avatar.php b/lib/private/avatar.php index f20980c364b..e97f55eecaf 100644 --- a/lib/private/avatar.php +++ b/lib/private/avatar.php @@ -10,7 +10,7 @@ * This class gets and sets users avatars. */ -class OC_Avatar { +class OC_Avatar implements \OCP\IAvatar { private $view; @@ -24,7 +24,7 @@ class OC_Avatar { /** * @brief get the users avatar - * @param $size integer size in px of the avatar, defaults to 64 + * @param $size integer size in px of the avatar, avatars are square, defaults to 64 * @return boolean|\OC_Image containing the avatar or false if there's no image */ public function get ($size = 64) { @@ -44,21 +44,23 @@ class OC_Avatar { /** * @brief sets the users avatar - * @param $data mixed imagedata or path to set a new avatar + * @param $data mixed OC_Image, imagedata or path to set a new avatar * @throws Exception if the provided file is not a jpg or png image * @throws Exception if the provided image is not valid * @throws \OC\NotSquareException if the image is not square * @return void */ public function set ($data) { - if (\OC_App::isEnabled('files_encryption')) { - $l = \OC_L10N::get('lib'); - throw new \Exception($l->t("Custom profile pictures don't work with encryption yet")); + if($data instanceOf OC_Image) { + $img = $data; + $data = $img->data(); + } else { + $img = new OC_Image($data); } - - $img = new OC_Image($data); $type = substr($img->mimeType(), -3); - if ($type === 'peg') { $type = 'jpg'; } + if ($type === 'peg') { + $type = 'jpg'; + } if ($type !== 'jpg' && $type !== 'png') { $l = \OC_L10N::get('lib'); throw new \Exception($l->t("Unknown filetype")); diff --git a/lib/private/avatarmanager.php b/lib/private/avatarmanager.php new file mode 100644 index 00000000000..3ca46868ea6 --- /dev/null +++ b/lib/private/avatarmanager.php @@ -0,0 +1,26 @@ +<?php +/** + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC; + +use OCP\IAvatarManager; + +/* + * This class implements methods to access Avatar functionality + */ +class AvatarManager implements IAvatarManager { + + /** + * @brief return a user specific instance of \OCP\IAvatar + * @see \OCP\IAvatar + * @param $user string the ownCloud user id + * @return \OCP\IAvatar + */ + function getAvatar($user) { + return new \OC_Avatar($user); + } +} diff --git a/lib/private/backgroundjob/job.php b/lib/private/backgroundjob/job.php index 49fbffbd684..92bd0f8fdbd 100644 --- a/lib/private/backgroundjob/job.php +++ b/lib/private/backgroundjob/job.php @@ -9,16 +9,35 @@ namespace OC\BackgroundJob; abstract class Job { + /** + * @var int $id + */ protected $id; + + /** + * @var int $lastRun + */ protected $lastRun; + + /** + * @var mixed $argument + */ protected $argument; /** * @param JobList $jobList + * @param \OC\Log $logger */ - public function execute($jobList) { + public function execute($jobList, $logger = null) { $jobList->setLastRun($this); - $this->run($this->argument); + try { + $this->run($this->argument); + } catch (\Exception $e) { + if ($logger) { + $logger->error('Error while running background job: ' . $e->getMessage()); + } + $jobList->remove($this, $this->argument); + } } abstract protected function run($argument); diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php index cc803dd9b5f..99743a70c77 100644 --- a/lib/private/backgroundjob/joblist.php +++ b/lib/private/backgroundjob/joblist.php @@ -138,7 +138,7 @@ class JobList { $job = new $class(); $job->setId($row['id']); $job->setLastRun($row['last_run']); - $job->setArgument(json_decode($row['argument'])); + $job->setArgument(json_decode($row['argument'], true)); return $job; } diff --git a/lib/private/backgroundjob/queuedjob.php b/lib/private/backgroundjob/queuedjob.php index 1714182820d..799eac47848 100644 --- a/lib/private/backgroundjob/queuedjob.php +++ b/lib/private/backgroundjob/queuedjob.php @@ -20,9 +20,10 @@ abstract class QueuedJob extends Job { * run the job, then remove it from the joblist * * @param JobList $jobList + * @param \OC\Log $logger */ - public function execute($jobList) { + public function execute($jobList, $logger = null) { $jobList->remove($this); - $this->run($this->argument); + parent::execute($jobList, $logger); } } diff --git a/lib/private/backgroundjob/timedjob.php b/lib/private/backgroundjob/timedjob.php index ae9f33505ab..09e05f1d846 100644 --- a/lib/private/backgroundjob/timedjob.php +++ b/lib/private/backgroundjob/timedjob.php @@ -31,11 +31,11 @@ abstract class TimedJob extends Job { * run the job if * * @param JobList $jobList + * @param \OC\Log $logger */ - public function execute($jobList) { + public function execute($jobList, $logger = null) { if ((time() - $this->lastRun) > $this->interval) { - $jobList->setLastRun($this); - $this->run($this->argument); + parent::execute($jobList, $logger); } } } diff --git a/lib/private/cache/file.php b/lib/private/cache/file.php index 2ab914d17b8..b0738d2a92b 100644 --- a/lib/private/cache/file.php +++ b/lib/private/cache/file.php @@ -41,6 +41,24 @@ class File { return $result; } + /** + * Returns the size of the stored/cached data + * + * @param $key + * @return int + */ + public function size($key) { + $result = 0; + $proxyStatus = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; + if ($this->hasKey($key)) { + $storage = $this->getStorage(); + $result = $storage->filesize($key); + } + \OC_FileProxy::$enabled = $proxyStatus; + return $result; + } + public function set($key, $value, $ttl=0) { $storage = $this->getStorage(); $result = false; diff --git a/lib/private/config.php b/lib/private/config.php index e773e6e2eb0..8a9d5ca6158 100644 --- a/lib/private/config.php +++ b/lib/private/config.php @@ -50,7 +50,7 @@ class Config { protected $debugMode; /** - * @param $configDir path to the config dir, needs to end with '/' + * @param string $configDir path to the config dir, needs to end with '/' */ public function __construct($configDir) { $this->configDir = $configDir; @@ -160,7 +160,6 @@ class Config { */ private function writeData() { // Create a php file ... - $defaults = new \OC_Defaults; $content = "<?php\n"; if ($this->debugMode) { $content .= "define('DEBUG',true);\n"; @@ -172,7 +171,8 @@ class Config { // Write the file $result = @file_put_contents($this->configFilename, $content); if (!$result) { - $url = $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html#set-the-directory-permissions'; + $defaults = new \OC_Defaults; + $url = \OC_Helper::linkToDocs('admin-dir-permissions'); throw new HintException( "Can't write into config directory!", 'This can usually be fixed by ' diff --git a/lib/private/connector/sabre/aborteduploaddetectionplugin.php b/lib/private/connector/sabre/aborteduploaddetectionplugin.php index 15dca3a6809..10cca647e8d 100644 --- a/lib/private/connector/sabre/aborteduploaddetectionplugin.php +++ b/lib/private/connector/sabre/aborteduploaddetectionplugin.php @@ -53,6 +53,12 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl */ public function verifyContentLength($filePath, Sabre_DAV_INode $node = null) { + // we should only react on PUT which is used for upload + // e.g. with LOCK this will not work, but LOCK uses createFile() as well + if ($this->server->httpRequest->getMethod() !== 'PUT' ) { + return; + } + // ownCloud chunked upload will be handled in its own plugin $chunkHeader = $this->server->httpRequest->getHeader('OC-Chunked'); if ($chunkHeader) { diff --git a/lib/private/connector/sabre/auth.php b/lib/private/connector/sabre/auth.php index bf3a49593cb..0c84fa6b757 100644 --- a/lib/private/connector/sabre/auth.php +++ b/lib/private/connector/sabre/auth.php @@ -72,7 +72,8 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic { * @return bool */ public function authenticate(Sabre_DAV_Server $server, $realm) { - if (OC_User::isLoggedIn()) { + + if (OC_User::handleApacheAuth() || OC_User::isLoggedIn()) { $user = OC_User::getUser(); OC_Util::setupFS($user); $this->currentUser = $user; diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php index 382bdf06df1..02d1a9f4ba2 100644 --- a/lib/private/connector/sabre/directory.php +++ b/lib/private/connector/sabre/directory.php @@ -50,51 +50,31 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function createFile($name, $data = null) { - if (!\OC\Files\Filesystem::isCreatable($this->path)) { + if ($name === 'Shared' && empty($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } + // for chunked upload also updating a existing file is a "createFile" + // because we create all the chunks before reasamble them to the existing file. if (isset($_SERVER['HTTP_OC_CHUNKED'])) { - $info = OC_FileChunking::decodeName($name); - if (empty($info)) { - throw new Sabre_DAV_Exception_NotImplemented(); - } - $chunk_handler = new OC_FileChunking($info); - $chunk_handler->store($info['index'], $data); - if ($chunk_handler->isComplete()) { - $newPath = $this->path . '/' . $info['name']; - $chunk_handler->file_assemble($newPath); - return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); - } - } else { - $newPath = $this->path . '/' . $name; - - // mark file as partial while uploading (ignored by the scanner) - $partpath = $newPath . '.part'; - \OC\Files\Filesystem::file_put_contents($partpath, $data); - - // rename to correct path - $renameOkay = \OC\Files\Filesystem::rename($partpath, $newPath); - $fileExists = \OC\Files\Filesystem::file_exists($newPath); - if ($renameOkay === false || $fileExists === false) { - \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); - \OC\Files\Filesystem::unlink($partpath); - throw new Sabre_DAV_Exception(); + // exit if we can't create a new file and we don't updatable existing file + $info = OC_FileChunking::decodeName($name); + if (!\OC\Files\Filesystem::isCreatable($this->path) && + !\OC\Files\Filesystem::isUpdatable($this->path . '/' . $info['name'])) { + throw new \Sabre_DAV_Exception_Forbidden(); } - // allow sync clients to send the mtime along in a header - $mtime = OC_Request::hasModificationTime(); - if ($mtime !== false) { - if(\OC\Files\Filesystem::touch($newPath, $mtime)) { - header('X-OC-MTime: accepted'); - } + } else { + // For non-chunked upload it is enough to check if we can create a new file + if (!\OC\Files\Filesystem::isCreatable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); } - - return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); } - return null; + $path = $this->path . '/' . $name; + $node = new OC_Connector_Sabre_File($path); + return $node->put($data); } /** @@ -106,6 +86,10 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function createDirectory($name) { + if ($name === 'Shared' && empty($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + if (!\OC\Files\Filesystem::isCreatable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } @@ -211,13 +195,16 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function delete() { - if (!\OC\Files\Filesystem::isDeletable($this->path)) { + if ($this->path === 'Shared') { throw new \Sabre_DAV_Exception_Forbidden(); } - if ($this->path != "/Shared") { - \OC\Files\Filesystem::rmdir($this->path); + + if (!\OC\Files\Filesystem::isDeletable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); } + \OC\Files\Filesystem::rmdir($this->path); + } /** @@ -243,14 +230,14 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * If the array is empty, all properties should be returned * * @param array $properties - * @return void + * @return array */ public function getProperties($properties) { $props = parent::getProperties($properties); if (in_array(self::GETETAG_PROPERTYNAME, $properties) && !isset($props[self::GETETAG_PROPERTYNAME])) { - $props[self::GETETAG_PROPERTYNAME] - = OC_Connector_Sabre_Node::getETagPropertyForPath($this->path); + $props[self::GETETAG_PROPERTYNAME] = $this->getETagPropertyForPath($this->path); } return $props; } + } diff --git a/lib/private/connector/sabre/exception/entitytoolarge.php b/lib/private/connector/sabre/exception/entitytoolarge.php new file mode 100644 index 00000000000..2bda51f2f3e --- /dev/null +++ b/lib/private/connector/sabre/exception/entitytoolarge.php @@ -0,0 +1,22 @@ +<?php + +/** + * Entity Too Large + * + * This exception is thrown whenever a user tries to upload a file which exceeds hard limitations + * + */ +class OC_Connector_Sabre_Exception_EntityTooLarge extends Sabre_DAV_Exception { + + /** + * Returns the HTTP status code for this exception + * + * @return int + */ + public function getHTTPCode() { + + return 413; + + } + +} diff --git a/lib/private/connector/sabre/exception/unsupportedmediatype.php b/lib/private/connector/sabre/exception/unsupportedmediatype.php new file mode 100644 index 00000000000..95d6a8cc651 --- /dev/null +++ b/lib/private/connector/sabre/exception/unsupportedmediatype.php @@ -0,0 +1,22 @@ +<?php + +/** + * Unsupported Media Type + * + * This exception is thrown whenever a user tries to upload a file which holds content which is not allowed + * + */ +class OC_Connector_Sabre_Exception_UnsupportedMediaType extends Sabre_DAV_Exception { + + /** + * Returns the HTTP status code for this exception + * + * @return int + */ + public function getHTTPCode() { + + return 415; + + } + +} diff --git a/lib/private/connector/sabre/exceptionloggerplugin.php b/lib/private/connector/sabre/exceptionloggerplugin.php new file mode 100644 index 00000000000..8e77afaf207 --- /dev/null +++ b/lib/private/connector/sabre/exceptionloggerplugin.php @@ -0,0 +1,50 @@ +<?php + +/** + * ownCloud + * + * @author Vincent Petry + * @copyright 2014 Vincent Petry <pvince81@owncloud.com> + * + * @license AGPL3 + */ + +class OC_Connector_Sabre_ExceptionLoggerPlugin extends Sabre_DAV_ServerPlugin +{ + private $appName; + + /** + * @param string $loggerAppName app name to use when logging + */ + public function __construct($loggerAppName = 'webdav') { + $this->appName = $loggerAppName; + } + + /** + * This initializes the plugin. + * + * This function is called by Sabre_DAV_Server, after + * addPlugin is called. + * + * This method should set up the required event subscriptions. + * + * @param Sabre_DAV_Server $server + * @return void + */ + public function initialize(Sabre_DAV_Server $server) { + + $server->subscribeEvent('exception', array($this, 'logException'), 10); + } + + /** + * Log exception + * + * @internal param Exception $e exception + */ + public function logException($e) { + $exceptionClass = get_class($e); + if ($exceptionClass !== 'Sabre_DAV_Exception_NotAuthenticated') { + \OCP\Util::logException($this->appName, $e); + } + } +} diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 433b1148552..ed27cef440d 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -28,7 +28,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * * The data argument is a readable stream resource. * - * After a succesful put operation, you may choose to return an ETag. The + * After a successful put operation, you may choose to return an ETag. The * etag must always be surrounded by double-quotes. These quotes must * appear in the actual string you're returning. * @@ -46,7 +46,10 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function put($data) { - if (!\OC\Files\Filesystem::isUpdatable($this->path)) { + $fs = $this->getFS(); + + if ($fs->file_exists($this->path) && + !$fs->isUpdatable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } @@ -54,44 +57,66 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D if (\OC_Util::encryptedFiles()) { throw new \Sabre_DAV_Exception_ServiceUnavailable(); } - + + // chunked handling + if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + return $this->createFileChunked($data); + } + // mark file as partial while uploading (ignored by the scanner) - $partpath = $this->path . '.part'; + $partpath = $this->path . '.ocTransferId' . rand() . '.part'; - \OC\Files\Filesystem::file_put_contents($partpath, $data); + // if file is located in /Shared we write the part file to the users + // root folder because we can't create new files in /shared + // we extend the name with a random number to avoid overwriting a existing file + if (dirname($partpath) === 'Shared') { + $partpath = pathinfo($partpath, PATHINFO_FILENAME) . rand() . '.part'; + } - //detect aborted upload - if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT') { - if (isset($_SERVER['CONTENT_LENGTH'])) { - $expected = $_SERVER['CONTENT_LENGTH']; - $actual = \OC\Files\Filesystem::filesize($partpath); - if ($actual != $expected) { - \OC\Files\Filesystem::unlink($partpath); - throw new Sabre_DAV_Exception_BadRequest( - 'expected filesize ' . $expected . ' got ' . $actual); - } + try { + $putOkay = $fs->file_put_contents($partpath, $data); + if ($putOkay === false) { + \OC_Log::write('webdav', '\OC\Files\Filesystem::file_put_contents() failed', \OC_Log::ERROR); + $fs->unlink($partpath); + // because we have no clue about the cause we can only throw back a 500/Internal Server Error + throw new Sabre_DAV_Exception('Could not write file contents'); } + } catch (\OCP\Files\NotPermittedException $e) { + // a more general case - due to whatever reason the content could not be written + throw new Sabre_DAV_Exception_Forbidden($e->getMessage()); + + } catch (\OCP\Files\EntityTooLargeException $e) { + // the file is too big to be stored + throw new OC_Connector_Sabre_Exception_EntityTooLarge($e->getMessage()); + + } catch (\OCP\Files\InvalidContentException $e) { + // the file content is not permitted + throw new OC_Connector_Sabre_Exception_UnsupportedMediaType($e->getMessage()); + + } catch (\OCP\Files\InvalidPathException $e) { + // the path for the file was not valid + // TODO: find proper http status code for this case + throw new Sabre_DAV_Exception_Forbidden($e->getMessage()); } // rename to correct path - $renameOkay = \OC\Files\Filesystem::rename($partpath, $this->path); - $fileExists = \OC\Files\Filesystem::file_exists($this->path); + $renameOkay = $fs->rename($partpath, $this->path); + $fileExists = $fs->file_exists($this->path); if ($renameOkay === false || $fileExists === false) { \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); - \OC\Files\Filesystem::unlink($partpath); - throw new Sabre_DAV_Exception(); + $fs->unlink($partpath); + throw new Sabre_DAV_Exception('Could not rename part file to final file'); } - - //allow sync clients to send the mtime along in a header + // allow sync clients to send the mtime along in a header $mtime = OC_Request::hasModificationTime(); if ($mtime !== false) { - if (\OC\Files\Filesystem::touch($this->path, $mtime)) { + if($fs->touch($this->path, $mtime)) { header('X-OC-MTime: accepted'); } } - return OC_Connector_Sabre_Node::getETagPropertyForPath($this->path); + return $this->getETagPropertyForPath($this->path); } /** @@ -101,7 +126,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function get() { - //throw execption if encryption is disabled but files are still encrypted + //throw exception if encryption is disabled but files are still encrypted if (\OC_Util::encryptedFiles()) { throw new \Sabre_DAV_Exception_ServiceUnavailable(); } else { @@ -118,11 +143,18 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function delete() { + if ($this->path === 'Shared') { + throw new \Sabre_DAV_Exception_Forbidden(); + } + if (!\OC\Files\Filesystem::isDeletable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } \OC\Files\Filesystem::unlink($this->path); + // remove properties + $this->removeProperties(); + } /** @@ -144,7 +176,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * * An ETag is a unique identifier representing the current version of the * file. If the file changes, the ETag MUST change. The ETag is an - * arbritrary string, but MUST be surrounded by double-quotes. + * arbitrary string, but MUST be surrounded by double-quotes. * * Return null if the ETag can not effectively be determined * @@ -173,4 +205,62 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D return \OC\Files\Filesystem::getMimeType($this->path); } + + private function createFileChunked($data) + { + list($path, $name) = \Sabre_DAV_URLUtil::splitPath($this->path); + + $info = OC_FileChunking::decodeName($name); + if (empty($info)) { + throw new Sabre_DAV_Exception_NotImplemented(); + } + $chunk_handler = new OC_FileChunking($info); + $bytesWritten = $chunk_handler->store($info['index'], $data); + + //detect aborted upload + if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT' ) { + if (isset($_SERVER['CONTENT_LENGTH'])) { + $expected = $_SERVER['CONTENT_LENGTH']; + if ($bytesWritten != $expected) { + $chunk_handler->remove($info['index']); + throw new Sabre_DAV_Exception_BadRequest( + 'expected filesize ' . $expected . ' got ' . $bytesWritten); + } + } + } + + if ($chunk_handler->isComplete()) { + + // we first assembly the target file as a part file + $partFile = $path . '/' . $info['name'] . '.ocTransferId' . $info['transferid'] . '.part'; + $chunk_handler->file_assemble($partFile); + + // here is the final atomic rename + $fs = $this->getFS(); + $targetPath = $path . '/' . $info['name']; + $renameOkay = $fs->rename($partFile, $targetPath); + $fileExists = $fs->file_exists($targetPath); + if ($renameOkay === false || $fileExists === false) { + \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); + // only delete if an error occurred and the target file was already created + if ($fileExists) { + $fs->unlink($targetPath); + } + throw new Sabre_DAV_Exception('Could not rename part file assembled from chunks'); + } + + // allow sync clients to send the mtime along in a header + $mtime = OC_Request::hasModificationTime(); + if ($mtime !== false) { + if($fs->touch($targetPath, $mtime)) { + header('X-OC-MTime: accepted'); + } + } + + return OC_Connector_Sabre_Node::getETagPropertyForPath($targetPath); + } + + return null; + } + } diff --git a/lib/private/connector/sabre/filesplugin.php b/lib/private/connector/sabre/filesplugin.php new file mode 100644 index 00000000000..65231040fb5 --- /dev/null +++ b/lib/private/connector/sabre/filesplugin.php @@ -0,0 +1,103 @@ +<?php + +/** + * ownCloud + * + * @author Thomas Müller + * @copyright 2013 Thomas Müller <thomas.mueller@tmit.eu> + * + * @license AGPL3 + */ + +class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin +{ + + // namespace + const NS_OWNCLOUD = 'http://owncloud.org/ns'; + + /** + * Reference to main server object + * + * @var Sabre_DAV_Server + */ + private $server; + + /** + * This initializes the plugin. + * + * This function is called by Sabre_DAV_Server, after + * addPlugin is called. + * + * This method should set up the required event subscriptions. + * + * @param Sabre_DAV_Server $server + * @return void + */ + public function initialize(Sabre_DAV_Server $server) { + + $server->xmlNamespaces[self::NS_OWNCLOUD] = 'oc'; + $server->protectedProperties[] = '{' . self::NS_OWNCLOUD . '}id'; + + $this->server = $server; + $this->server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties')); + $this->server->subscribeEvent('afterCreateFile', array($this, 'sendFileIdHeader')); + $this->server->subscribeEvent('afterWriteContent', array($this, 'sendFileIdHeader')); + } + + /** + * Adds all ownCloud-specific properties + * + * @param string $path + * @param Sabre_DAV_INode $node + * @param array $requestedProperties + * @param array $returnedProperties + * @return void + */ + public function beforeGetProperties($path, Sabre_DAV_INode $node, array &$requestedProperties, array &$returnedProperties) { + + if ($node instanceof OC_Connector_Sabre_Node) { + + $fileid_propertyname = '{' . self::NS_OWNCLOUD . '}id'; + if (array_search($fileid_propertyname, $requestedProperties)) { + unset($requestedProperties[array_search($fileid_propertyname, $requestedProperties)]); + } + + /** @var $node OC_Connector_Sabre_Node */ + $fileId = $node->getFileId(); + if (!is_null($fileId)) { + $returnedProperties[200][$fileid_propertyname] = $fileId; + } + + } + + } + + /** + * @param $filePath + * @param Sabre_DAV_INode $node + * @throws Sabre_DAV_Exception_BadRequest + */ + public function sendFileIdHeader($filePath, Sabre_DAV_INode $node = null) { + // chunked upload handling + if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + list($path, $name) = \Sabre_DAV_URLUtil::splitPath($filePath); + $info = OC_FileChunking::decodeName($name); + if (!empty($info)) { + $filePath = $path . '/' . $info['name']; + } + } + + // we get the node for the given $filePath here because in case of afterCreateFile $node is the parent folder + if (!$this->server->tree->nodeExists($filePath)) { + return; + } + $node = $this->server->tree->getNodeForPath($filePath); + if ($node instanceof OC_Connector_Sabre_Node) { + $fileId = $node->getFileId(); + if (!is_null($fileId)) { + $this->server->httpResponse->setHeader('OC-FileId', $fileId); + } + } + } + +} diff --git a/lib/private/connector/sabre/node.php b/lib/private/connector/sabre/node.php index 29b7f9e53a5..993aa73faeb 100644 --- a/lib/private/connector/sabre/node.php +++ b/lib/private/connector/sabre/node.php @@ -33,11 +33,19 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr public static $ETagFunction = null; /** + * is kept public to allow overwrite for unit testing + * + * @var \OC\Files\View + */ + public $fileView; + + /** * The path to the current node * * @var string */ protected $path; + /** * node fileinfo cache * @var array @@ -140,12 +148,6 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * Even if the modification time is set to a custom value the access time is set to now. */ public function touch($mtime) { - - // touch is only allowed if the update privilege is granted - if (!\OC\Files\Filesystem::isUpdatable($this->path)) { - throw new \Sabre_DAV_Exception_Forbidden(); - } - \OC\Files\Filesystem::touch($this->path, $mtime); } @@ -190,6 +192,17 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } /** + * removes all properties for this node and user + */ + public function removeProperties() { + $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`' + .' WHERE `userid` = ? AND `propertypath` = ?' ); + $query->execute( array( OC_User::getUser(), $this->path)); + + $this->setPropertyCache(null); + } + + /** * @brief Returns a list of properties for this nodes.; * @param array $properties * @return array @@ -199,6 +212,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * properties should be returned */ public function getProperties($properties) { + if (is_null($this->property_cache)) { $sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?'; $result = OC_DB::executeAudited( $sql, array( OC_User::getUser(), $this->path ) ); @@ -207,7 +221,14 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr while( $row = $result->fetchRow()) { $this->property_cache[$row['propertyname']] = $row['propertyvalue']; } - $this->property_cache[self::GETETAG_PROPERTYNAME] = $this->getETagPropertyForPath($this->path); + + // Don't call the static getETagPropertyForPath, its result is not cached + $this->getFileinfoCache(); + if ($this->fileinfo_cache['etag']) { + $this->property_cache[self::GETETAG_PROPERTYNAME] = '"'.$this->fileinfo_cache['etag'].'"'; + } else { + $this->property_cache[self::GETETAG_PROPERTYNAME] = null; + } } // if the array was empty, we need to return everything @@ -217,8 +238,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr $props = array(); foreach($properties as $property) { - if (isset($this->property_cache[$property])) $props[$property] = $this->property_cache[$property]; + if (isset($this->property_cache[$property])) { + $props[$property] = $this->property_cache[$property]; + } } + return $props; } @@ -227,12 +251,34 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * @param string $path Path of the file * @return string|null Returns null if the ETag can not effectively be determined */ - static public function getETagPropertyForPath($path) { - $data = \OC\Files\Filesystem::getFileInfo($path); + protected function getETagPropertyForPath($path) { + $data = $this->getFS()->getFileInfo($path); if (isset($data['etag'])) { return '"'.$data['etag'].'"'; } return null; } + protected function getFS() { + if (is_null($this->fileView)) { + $this->fileView = \OC\Files\Filesystem::getView(); + } + return $this->fileView; + } + + /** + * @return mixed + */ + public function getFileId() + { + $this->getFileinfoCache(); + + if (isset($this->fileinfo_cache['fileid'])) { + $instanceId = OC_Util::getInstanceId(); + $id = sprintf('%08d', $this->fileinfo_cache['fileid']); + return $id . $instanceId; + } + + return null; + } } diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php index 80c3840b99d..d1e179af2ec 100644 --- a/lib/private/connector/sabre/objecttree.php +++ b/lib/private/connector/sabre/objecttree.php @@ -38,7 +38,20 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { return $this->rootNode; } - $info = $this->getFileView()->getFileInfo($path); + if (pathinfo($path, PATHINFO_EXTENSION) === 'part') { + // read from storage + $absPath = $this->getFileView()->getAbsolutePath($path); + list($storage, $internalPath) = Filesystem::resolvePath('/' . $absPath); + if ($storage) { + $scanner = $storage->getScanner($internalPath); + // get data directly + $info = $scanner->getData($internalPath); + } + } + else { + // read from cache + $info = $this->getFileView()->getFileInfo($path); + } if (!$info) { throw new \Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located'); @@ -87,6 +100,9 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { if (!$fs->isUpdatable($destinationDir)) { throw new \Sabre_DAV_Exception_Forbidden(); } + if (!$fs->isDeletable($sourcePath)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } } $renameOkay = $fs->rename($sourcePath, $destinationPath); @@ -94,6 +110,11 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { throw new \Sabre_DAV_Exception_Forbidden(''); } + // update properties + $query = \OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertypath` = ?' + .' WHERE `userid` = ? AND `propertypath` = ?' ); + $query->execute( array( $destinationPath, \OC_User::getUser(), $sourcePath )); + $this->markDirty($sourceDir); $this->markDirty($destinationDir); diff --git a/lib/private/connector/sabre/server.php b/lib/private/connector/sabre/server.php new file mode 100644 index 00000000000..41e8885917a --- /dev/null +++ b/lib/private/connector/sabre/server.php @@ -0,0 +1,235 @@ +<?php +/** + * ownCloud / SabreDAV + * + * @author Markus Goetz + * + * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License + */ + +/** + * Class OC_Connector_Sabre_Server + * + * This class reimplements some methods from @see Sabre_DAV_Server. + * + * Basically we add handling of depth: infinity. + * + * The right way to handle this would have been to submit a patch to the upstream project + * and grab the corresponding version one merged. + * + * Due to time constrains and the limitations where we don't want to upgrade 3rdparty code in + * this stage of the release cycle we did choose this approach. + * + * For ownCloud 7 we will upgrade SabreDAV and submit the patch - if needed. + * + * @see Sabre_DAV_Server + */ +class OC_Connector_Sabre_Server extends Sabre_DAV_Server { + + /** + * @see Sabre_DAV_Server + */ + protected function httpPropfind($uri) { + + // $xml = new Sabre_DAV_XMLReader(file_get_contents('php://input')); + $requestedProperties = $this->parsePropFindRequest($this->httpRequest->getBody(true)); + + $depth = $this->getHTTPDepth(1); + // The only two options for the depth of a propfind is 0 or 1 + // if ($depth!=0) $depth = 1; + + $newProperties = $this->getPropertiesForPath($uri,$requestedProperties,$depth); + + // This is a multi-status response + $this->httpResponse->sendStatus(207); + $this->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8'); + $this->httpResponse->setHeader('Vary','Brief,Prefer'); + + // Normally this header is only needed for OPTIONS responses, however.. + // iCal seems to also depend on these being set for PROPFIND. Since + // this is not harmful, we'll add it. + $features = array('1','3', 'extended-mkcol'); + foreach($this->plugins as $plugin) { + $features = array_merge($features,$plugin->getFeatures()); + } + + $this->httpResponse->setHeader('DAV',implode(', ',$features)); + + $prefer = $this->getHTTPPrefer(); + $minimal = $prefer['return-minimal']; + + $data = $this->generateMultiStatus($newProperties, $minimal); + $this->httpResponse->sendBody($data); + + } + + /** + * Small helper to support PROPFIND with DEPTH_INFINITY. + */ + private function addPathNodesRecursively(&$nodes, $path) { + foreach($this->tree->getChildren($path) as $childNode) { + $nodes[$path . '/' . $childNode->getName()] = $childNode; + if ($childNode instanceof Sabre_DAV_ICollection) + $this->addPathNodesRecursively($nodes, $path . '/' . $childNode->getName()); + } + } + + public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0) { + + // if ($depth!=0) $depth = 1; + + $path = rtrim($path,'/'); + + $returnPropertyList = array(); + + $parentNode = $this->tree->getNodeForPath($path); + $nodes = array( + $path => $parentNode + ); + if ($depth==1 && $parentNode instanceof Sabre_DAV_ICollection) { + foreach($this->tree->getChildren($path) as $childNode) + $nodes[$path . '/' . $childNode->getName()] = $childNode; + } else if ($depth == self::DEPTH_INFINITY && $parentNode instanceof Sabre_DAV_ICollection) { + $this->addPathNodesRecursively($nodes, $path); + } + + // If the propertyNames array is empty, it means all properties are requested. + // We shouldn't actually return everything we know though, and only return a + // sensible list. + $allProperties = count($propertyNames)==0; + + foreach($nodes as $myPath=>$node) { + + $currentPropertyNames = $propertyNames; + + $newProperties = array( + '200' => array(), + '404' => array(), + ); + + if ($allProperties) { + // Default list of propertyNames, when all properties were requested. + $currentPropertyNames = array( + '{DAV:}getlastmodified', + '{DAV:}getcontentlength', + '{DAV:}resourcetype', + '{DAV:}quota-used-bytes', + '{DAV:}quota-available-bytes', + '{DAV:}getetag', + '{DAV:}getcontenttype', + ); + } + + // If the resourceType was not part of the list, we manually add it + // and mark it for removal. We need to know the resourcetype in order + // to make certain decisions about the entry. + // WebDAV dictates we should add a / and the end of href's for collections + $removeRT = false; + if (!in_array('{DAV:}resourcetype',$currentPropertyNames)) { + $currentPropertyNames[] = '{DAV:}resourcetype'; + $removeRT = true; + } + + $result = $this->broadcastEvent('beforeGetProperties',array($myPath, $node, &$currentPropertyNames, &$newProperties)); + // If this method explicitly returned false, we must ignore this + // node as it is inaccessible. + if ($result===false) continue; + + if (count($currentPropertyNames) > 0) { + + if ($node instanceof Sabre_DAV_IProperties) { + $nodeProperties = $node->getProperties($currentPropertyNames); + + // The getProperties method may give us too much, + // properties, in case the implementor was lazy. + // + // So as we loop through this list, we will only take the + // properties that were actually requested and discard the + // rest. + foreach($currentPropertyNames as $k=>$currentPropertyName) { + if (isset($nodeProperties[$currentPropertyName])) { + unset($currentPropertyNames[$k]); + $newProperties[200][$currentPropertyName] = $nodeProperties[$currentPropertyName]; + } + } + + } + + } + + foreach($currentPropertyNames as $prop) { + + if (isset($newProperties[200][$prop])) continue; + + switch($prop) { + case '{DAV:}getlastmodified' : if ($node->getLastModified()) $newProperties[200][$prop] = new Sabre_DAV_Property_GetLastModified($node->getLastModified()); break; + case '{DAV:}getcontentlength' : + if ($node instanceof Sabre_DAV_IFile) { + $size = $node->getSize(); + if (!is_null($size)) { + $newProperties[200][$prop] = (int)$node->getSize(); + } + } + break; + case '{DAV:}quota-used-bytes' : + if ($node instanceof Sabre_DAV_IQuota) { + $quotaInfo = $node->getQuotaInfo(); + $newProperties[200][$prop] = $quotaInfo[0]; + } + break; + case '{DAV:}quota-available-bytes' : + if ($node instanceof Sabre_DAV_IQuota) { + $quotaInfo = $node->getQuotaInfo(); + $newProperties[200][$prop] = $quotaInfo[1]; + } + break; + case '{DAV:}getetag' : if ($node instanceof Sabre_DAV_IFile && $etag = $node->getETag()) $newProperties[200][$prop] = $etag; break; + case '{DAV:}getcontenttype' : if ($node instanceof Sabre_DAV_IFile && $ct = $node->getContentType()) $newProperties[200][$prop] = $ct; break; + case '{DAV:}supported-report-set' : + $reports = array(); + foreach($this->plugins as $plugin) { + $reports = array_merge($reports, $plugin->getSupportedReportSet($myPath)); + } + $newProperties[200][$prop] = new Sabre_DAV_Property_SupportedReportSet($reports); + break; + case '{DAV:}resourcetype' : + $newProperties[200]['{DAV:}resourcetype'] = new Sabre_DAV_Property_ResourceType(); + foreach($this->resourceTypeMapping as $className => $resourceType) { + if ($node instanceof $className) $newProperties[200]['{DAV:}resourcetype']->add($resourceType); + } + break; + + } + + // If we were unable to find the property, we will list it as 404. + if (!$allProperties && !isset($newProperties[200][$prop])) $newProperties[404][$prop] = null; + + } + + $this->broadcastEvent('afterGetProperties',array(trim($myPath,'/'),&$newProperties, $node)); + + $newProperties['href'] = trim($myPath,'/'); + + // Its is a WebDAV recommendation to add a trailing slash to collectionnames. + // Apple's iCal also requires a trailing slash for principals (rfc 3744), though this is non-standard. + if ($myPath!='' && isset($newProperties[200]['{DAV:}resourcetype'])) { + $rt = $newProperties[200]['{DAV:}resourcetype']; + if ($rt->is('{DAV:}collection') || $rt->is('{DAV:}principal')) { + $newProperties['href'] .='/'; + } + } + + // If the resourcetype property was manually added to the requested property list, + // we will remove it again. + if ($removeRT) unset($newProperties[200]['{DAV:}resourcetype']); + + $returnPropertyList[] = $newProperties; + + } + + return $returnPropertyList; + + } +} diff --git a/lib/private/davclient.php b/lib/private/davclient.php new file mode 100644 index 00000000000..28f48f3b921 --- /dev/null +++ b/lib/private/davclient.php @@ -0,0 +1,46 @@ +<?php +/** + * ownCloud + * + * @author Vincent Petry + * @copyright 2013 Vincent Petry <pvince81@owncloud.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/** + * This class extends the SabreDAV client with additional functionality + * like request timeout. + */ + +class OC_DAVClient extends \Sabre_DAV_Client { + + protected $requestTimeout; + + /** + * @brief Sets the request timeout or 0 to disable timeout. + * @param int timeout in seconds or 0 to disable + */ + public function setRequestTimeout($timeout) { + $this->requestTimeout = (int)$timeout; + } + + protected function curlRequest($url, $settings) { + if ($this->requestTimeout > 0) { + $settings[CURLOPT_TIMEOUT] = $this->requestTimeout; + } + return parent::curlRequest($url, $settings); + } +} diff --git a/lib/private/db.php b/lib/private/db.php index 1e5d12649df..562065259fa 100644 --- a/lib/private/db.php +++ b/lib/private/db.php @@ -101,6 +101,9 @@ class OC_DB { ); $connectionParams['adapter'] = '\OC\DB\Adapter'; $connectionParams['wrapperClass'] = 'OC\DB\Connection'; + // Send "SET NAMES utf8". Only required on PHP 5.3 below 5.3.6. + // See http://stackoverflow.com/questions/4361459/php-pdo-charset-set-names#4361485 + $eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\MysqlSessionInit); break; case 'pgsql': $connectionParams = array( diff --git a/lib/private/db/adaptersqlsrv.php b/lib/private/db/adaptersqlsrv.php index d0a67af28a7..a6bc0e21052 100644 --- a/lib/private/db/adaptersqlsrv.php +++ b/lib/private/db/adaptersqlsrv.php @@ -10,13 +10,6 @@ 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 ); diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php index 2d3193a148a..2581969dbd0 100644 --- a/lib/private/db/connection.php +++ b/lib/private/db/connection.php @@ -12,7 +12,7 @@ use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\Common\EventManager; -class Connection extends \Doctrine\DBAL\Connection implements \OCP\IDBConnection { +class Connection extends \Doctrine\DBAL\Connection { /** * @var string $tablePrefix */ diff --git a/lib/private/db/connectionwrapper.php b/lib/private/db/connectionwrapper.php new file mode 100644 index 00000000000..93d4fb57f74 --- /dev/null +++ b/lib/private/db/connectionwrapper.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright (c) 2013 Thomas Müller <deepdiver@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + + +class ConnectionWrapper implements \OCP\IDBConnection { + + private $connection; + + public function __construct(Connection $conn) { + $this->connection = $conn; + } + + /** + * Used to the owncloud database access away + * @param string $sql the sql query with ? placeholder for params + * @param int $limit the maximum number of rows + * @param int $offset from which row we want to start + * @return \Doctrine\DBAL\Driver\Statement The prepared statement. + */ + public function prepare($sql, $limit = null, $offset = null) + { + return $this->connection->prepare($sql, $limit, $offset); + } + + /** + * Used to get the id of the just inserted element + * @param string $tableName the name of the table where we inserted the item + * @return int the id of the inserted element + */ + public function lastInsertId($table = null) + { + return $this->connection->lastInsertId($table); + } + + /** + * Insert a row if a matching row doesn't exists. + * @param string The table name (will replace *PREFIX*) to perform the replace on. + * @param array + * + * The input array if in the form: + * + * array ( 'id' => array ( 'value' => 6, + * 'key' => true + * ), + * 'name' => array ('value' => 'Stoyan'), + * 'family' => array ('value' => 'Stefanov'), + * 'birth_date' => array ('value' => '1975-06-20') + * ); + * @return bool + * + */ + public function insertIfNotExist($table, $input) + { + return $this->connection->insertIfNotExist($table, $input); + } + + /** + * Start a transaction + * @return bool TRUE on success or FALSE on failure + */ + public function beginTransaction() + { + return $this->connection->beginTransaction(); + } + + /** + * Commit the database changes done during a transaction that is in progress + * @return bool TRUE on success or FALSE on failure + */ + public function commit() + { + return $this->connection->commit(); + } + + /** + * Rollback the database changes done during a transaction that is in progress + * @return bool TRUE on success or FALSE on failure + */ + public function rollBack() + { + return $this->connection->rollBack(); + } + + /** + * Gets the error code and message as a string for logging + * @return string + */ + public function getError() + { + return $this->connection->getError(); + } +} diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php index 8e76f46c78f..6378c769055 100644 --- a/lib/private/db/mdb2schemamanager.php +++ b/lib/private/db/mdb2schemamanager.php @@ -19,6 +19,8 @@ class MDB2SchemaManager { */ public function __construct($conn) { $this->conn = $conn; + $this->conn->close(); + $this->conn->connect(); } /** @@ -53,7 +55,7 @@ class MDB2SchemaManager { * @param string $file file to read structure from * @return bool */ - public function updateDbFromStructure($file) { + public function updateDbFromStructure($file, $generateSql = false) { $sm = $this->conn->getSchemaManager(); $fromSchema = $sm->createSchema(); @@ -61,6 +63,7 @@ class MDB2SchemaManager { $toSchema = $schemaReader->loadSchemaFromFile($file); // remove tables we don't know about + /** @var $table \Doctrine\DBAL\Schema\Table */ foreach($fromSchema->getTables() as $table) { if (!$toSchema->hasTable($table->getName())) { $fromSchema->dropTable($table->getName()); @@ -77,10 +80,13 @@ class MDB2SchemaManager { $schemaDiff = $comparator->compare($fromSchema, $toSchema); $platform = $this->conn->getDatabasePlatform(); - $tables = $schemaDiff->newTables + $schemaDiff->changedTables + $schemaDiff->removedTables; - foreach($tables as $tableDiff) { + foreach($schemaDiff->changedTables as $tableDiff) { $tableDiff->name = $platform->quoteIdentifier($tableDiff->name); } + + if ($generateSql) { + return $this->generateChangeScript($schemaDiff); + } return $this->executeSchemaChange($schemaDiff); } @@ -106,6 +112,7 @@ class MDB2SchemaManager { $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform()); $fromSchema = $schemaReader->loadSchemaFromFile($file); $toSchema = clone $fromSchema; + /** @var $table \Doctrine\DBAL\Schema\Table */ foreach($toSchema->getTables() as $table) { $toSchema->dropTable($table->getName()); } @@ -147,4 +154,20 @@ class MDB2SchemaManager { $this->conn->commit(); return true; } + + /** + * @param \Doctrine\DBAL\Schema\Schema $schema + * @return string + */ + public function generateChangeScript($schema) { + + $script = ''; + $sqls = $schema->toSql($this->conn->getDatabasePlatform()); + foreach($sqls as $sql) { + $script .= $sql . ';'; + $script .= PHP_EOL; + } + + return $script; + } } diff --git a/lib/private/db/mdb2schemareader.php b/lib/private/db/mdb2schemareader.php index b7128a2f176..b1fd2454cb0 100644 --- a/lib/private/db/mdb2schemareader.php +++ b/lib/private/db/mdb2schemareader.php @@ -150,6 +150,9 @@ class MDB2SchemaReader { case 'timestamp': $type = 'datetime'; break; + case 'numeric': + $type = 'decimal'; + break; } break; case 'length': @@ -180,20 +183,28 @@ class MDB2SchemaReader { $primary = $this->asBool($child); $options['primary'] = $primary; break; + case 'precision': + $precision = (string)$child; + $options['precision'] = $precision; + break; + case 'scale': + $scale = (string)$child; + $options['scale'] = $scale; + break; default: throw new \DomainException('Unknown element: ' . $child->getName()); } } if (isset($name) && isset($type)) { - if (empty($options['default'])) { + if (isset($options['default']) && empty($options['default'])) { if (empty($options['notnull']) || !$options['notnull']) { unset($options['default']); $options['notnull'] = false; } else { $options['default'] = ''; } - if ($type == 'integer') { + if ($type == 'integer' || $type == 'decimal') { $options['default'] = 0; } elseif ($type == 'boolean') { $options['default'] = false; diff --git a/lib/private/db/statementwrapper.php b/lib/private/db/statementwrapper.php index b8da1afc0e5..5e89261d936 100644 --- a/lib/private/db/statementwrapper.php +++ b/lib/private/db/statementwrapper.php @@ -30,25 +30,6 @@ class OC_DB_StatementWrapper { } /** - * provide numRows - */ - public function numRows() { - $type = OC_Config::getValue( "dbtype", "sqlite" ); - if ($type == 'oci') { - // OCI doesn't have a queryString, just do a rowCount for now - return $this->statement->rowCount(); - } - $regex = '/^SELECT\s+(?:ALL\s+|DISTINCT\s+)?(?:.*?)\s+FROM\s+(.*)$/i'; - $queryString = $this->statement->getWrappedStatement()->queryString; - if (preg_match($regex, $queryString, $output) > 0) { - $query = OC_DB::prepare("SELECT COUNT(*) FROM {$output[1]}"); - return $query->execute($this->lastArguments)->fetchColumn(); - }else{ - return $this->statement->rowCount(); - } - } - - /** * make execute return the result instead of a bool */ public function execute($input=array()) { diff --git a/lib/private/defaults.php b/lib/private/defaults.php index 10813a3e8d8..cec9a65c7f3 100644 --- a/lib/private/defaults.php +++ b/lib/private/defaults.php @@ -1,18 +1,17 @@ <?php -/** - * Default strings and values which differ between the enterprise and the - * community edition. Use the get methods to always get the right strings. - */ - - if (file_exists(OC::$SERVERROOT . '/themes/' . OC_Util::getTheme() . '/defaults.php')) { require_once 'themes/' . OC_Util::getTheme() . '/defaults.php'; } +/** + * Default strings and values which differ between the enterprise and the + * community edition. Use the get methods to always get the right strings. + */ class OC_Defaults { private $theme; + private $l; private $defaultEntity; private $defaultName; @@ -24,7 +23,7 @@ class OC_Defaults { private $defaultLogoClaim; function __construct() { - $l = OC_L10N::get('core'); + $this->l = OC_L10N::get('core'); $this->defaultEntity = "ownCloud"; /* e.g. company name, used for footers and copyright notices */ $this->defaultName = "ownCloud"; /* short name, used when referring to the software */ @@ -32,7 +31,7 @@ class OC_Defaults { $this->defaultBaseUrl = "http://owncloud.org"; $this->defaultSyncClientUrl = " http://owncloud.org/sync-clients/"; $this->defaultDocBaseUrl = "http://doc.owncloud.org"; - $this->defaultSlogan = $l->t("web services under your control"); + $this->defaultSlogan = $this->l->t("web services under your control"); $this->defaultLogoClaim = ""; if (class_exists("OC_Theme")) { @@ -47,6 +46,10 @@ class OC_Defaults { return false; } + /** + * Returns the base URL + * @return string URL + */ public function getBaseUrl() { if ($this->themeExist('getBaseUrl')) { return $this->theme->getBaseUrl(); @@ -55,6 +58,10 @@ class OC_Defaults { } } + /** + * Returns the URL where the sync clients are listed + * @return string URL + */ public function getSyncClientUrl() { if ($this->themeExist('getSyncClientUrl')) { return $this->theme->getSyncClientUrl(); @@ -63,6 +70,10 @@ class OC_Defaults { } } + /** + * Returns the documentation URL + * @return string URL + */ public function getDocBaseUrl() { if ($this->themeExist('getDocBaseUrl')) { return $this->theme->getDocBaseUrl(); @@ -71,6 +82,10 @@ class OC_Defaults { } } + /** + * Returns the title + * @return string title + */ public function getTitle() { if ($this->themeExist('getTitle')) { return $this->theme->getTitle(); @@ -79,6 +94,10 @@ class OC_Defaults { } } + /** + * Returns the short name of the software + * @return string title + */ public function getName() { if ($this->themeExist('getName')) { return $this->theme->getName(); @@ -87,6 +106,10 @@ class OC_Defaults { } } + /** + * Returns entity (e.g. company name) - used for footer, copyright + * @return string entity name + */ public function getEntity() { if ($this->themeExist('getEntity')) { return $this->theme->getEntity(); @@ -95,6 +118,10 @@ class OC_Defaults { } } + /** + * Returns slogan + * @return string slogan + */ public function getSlogan() { if ($this->themeExist('getSlogan')) { return $this->theme->getSlogan(); @@ -103,6 +130,10 @@ class OC_Defaults { } } + /** + * Returns logo claim + * @return string logo claim + */ public function getLogoClaim() { if ($this->themeExist('getLogoClaim')) { return $this->theme->getLogoClaim(); @@ -111,6 +142,10 @@ class OC_Defaults { } } + /** + * Returns short version of the footer + * @return string short footer + */ public function getShortFooter() { if ($this->themeExist('getShortFooter')) { $footer = $this->theme->getShortFooter(); @@ -122,6 +157,10 @@ class OC_Defaults { return $footer; } + /** + * Returns long version of the footer + * @return string long footer + */ public function getLongFooter() { if ($this->themeExist('getLongFooter')) { $footer = $this->theme->getLongFooter(); diff --git a/lib/private/eventsource.php b/lib/private/eventsource.php index a83084d9251..4df0bc2e7cd 100644 --- a/lib/private/eventsource.php +++ b/lib/private/eventsource.php @@ -64,13 +64,13 @@ class OC_EventSource{ } if($this->fallback) { $response='<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack(' - .$this->fallBackId.',"'.$type.'",'.json_encode($data).')</script>'.PHP_EOL; + .$this->fallBackId.',"' . $type . '",' . OCP\JSON::encode($data) . ')</script>' . PHP_EOL; echo $response; }else{ if($type) { - echo 'event: '.$type.PHP_EOL; + echo 'event: ' . $type.PHP_EOL; } - echo 'data: '.json_encode($data).PHP_EOL; + echo 'data: ' . OCP\JSON::encode($data) . PHP_EOL; } echo PHP_EOL; flush(); diff --git a/lib/private/filechunking.php b/lib/private/filechunking.php index 313a6ee87d2..aa4f73c7c05 100644 --- a/lib/private/filechunking.php +++ b/lib/private/filechunking.php @@ -34,10 +34,19 @@ class OC_FileChunking { return $this->cache; } + /** + * Stores the given $data under the given $key - the number of stored bytes is returned + * + * @param $index + * @param $data + * @return int + */ public function store($index, $data) { $cache = $this->getCache(); $name = $this->getPrefix().$index; $cache->set($name, $data); + + return $cache->size($name); } public function isComplete() { @@ -58,12 +67,34 @@ class OC_FileChunking { $count = 0; for($i=0; $i < $this->info['chunkcount']; $i++) { $chunk = $cache->get($prefix.$i); - $cache->remove($prefix.$i); $count += fwrite($f, $chunk); } + + $this->cleanup(); return $count; } + /** + * Removes all chunks which belong to this transmission + */ + public function cleanup() { + $cache = $this->getCache(); + $prefix = $this->getPrefix(); + for($i=0; $i < $this->info['chunkcount']; $i++) { + $cache->remove($prefix.$i); + } + } + + /** + * Removes one specific chunk + * @param $index + */ + public function remove($index) { + $cache = $this->getCache(); + $prefix = $this->getPrefix(); + $cache->remove($prefix.$index); + } + public function signature_split($orgfile, $input) { $info = unpack('n', fread($input, 2)); $blocksize = $info[1]; diff --git a/lib/private/fileproxy.php b/lib/private/fileproxy.php index 52ec79b4bdb..2997aaf81b6 100644 --- a/lib/private/fileproxy.php +++ b/lib/private/fileproxy.php @@ -67,7 +67,11 @@ class OC_FileProxy{ self::$proxies[]=$proxy; } - public static function getProxies($operation) { + public static function getProxies($operation = null) { + if ($operation === null) { + // return all + return self::$proxies; + } $proxies=array(); foreach(self::$proxies as $proxy) { if(method_exists($proxy, $operation)) { diff --git a/lib/private/files.php b/lib/private/files.php index c705d2adb1a..8ce632013cf 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -28,8 +28,8 @@ class OC_Files { static $tmpFiles = array(); - static public function getFileInfo($path){ - return \OC\Files\Filesystem::getFileInfo($path); + static public function getFileInfo($path, $includeMountPoints = true){ + return \OC\Files\Filesystem::getFileInfo($path, $includeMountPoints); } static public function getDirectoryContent($path){ @@ -83,7 +83,7 @@ class OC_Files { if ($basename) { $name = $basename . '.zip'; } else { - $name = 'owncloud.zip'; + $name = 'download.zip'; } set_time_limit($executionTime); @@ -109,15 +109,13 @@ class OC_Files { $zip = false; $filename = $dir . '/' . $files; $name = $files; + if ($xsendfile && OC_App::isEnabled('files_encryption')) { + $xsendfile = false; + } } OC_Util::obEnd(); if ($zip or \OC\Files\Filesystem::isReadable($filename)) { - if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) { - header( 'Content-Disposition: attachment; filename="' . rawurlencode($name) . '"' ); - } else { - header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode($name) - . '; filename="' . rawurlencode($name) . '"' ); - } + OC_Response::setContentDispositionHeader($name, 'attachment'); header('Content-Transfer-Encoding: binary'); OC_Response::disableCaching(); if ($zip) { @@ -131,9 +129,11 @@ class OC_Files { if ($filesize > -1) { header("Content-Length: ".$filesize); } - list($storage) = \OC\Files\Filesystem::resolvePath($filename); - if ($storage instanceof \OC\Files\Storage\Local) { - self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename)); + if ($xsendfile) { + list($storage) = \OC\Files\Filesystem::resolvePath(\OC\Files\Filesystem::getView()->getAbsolutePath($filename)); + if ($storage instanceof \OC\Files\Storage\Local) { + self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename)); + } } } } elseif ($zip or !\OC\Files\Filesystem::file_exists($filename)) { @@ -251,7 +251,7 @@ class OC_Files { header("HTTP/1.0 409 Conflict"); OC_Template::printErrorPage( $l->t('Selected files too large to generate zip file.'), - $l->t('Download the files in smaller chunks, seperately or kindly ask your administrator.') + $l->t('Please download the files separately in smaller chunks or kindly ask your administrator.') .'<br/><a href="javascript:history.back()">' . $l->t('Back to Files') . '</a>' ); diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index e69733727af..1e7936ca26d 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -34,8 +34,8 @@ class Cache { */ private $storageCache; - private $mimetypeIds = array(); - private $mimetypes = array(); + private static $mimetypeIds = array(); + private static $mimetypes = array(); /** * @param \OC\Files\Storage\Storage|string $storage @@ -64,30 +64,45 @@ class Cache { * @return int */ public function getMimetypeId($mime) { - if (!isset($this->mimetypeIds[$mime])) { - $result = \OC_DB::executeAudited('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?', array($mime)); - if ($row = $result->fetchRow()) { - $this->mimetypeIds[$mime] = $row['id']; - } else { + if (empty($mime)) { + // Can not insert empty string into Oracle NOT NULL column. + $mime = 'application/octet-stream'; + } + if (empty(self::$mimetypeIds)) { + $this->loadMimetypes(); + } + + if (!isset(self::$mimetypeIds[$mime])) { + try{ $result = \OC_DB::executeAudited('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)', array($mime)); - $this->mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes'); + self::$mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes'); + self::$mimetypes[self::$mimetypeIds[$mime]] = $mime; } - $this->mimetypes[$this->mimetypeIds[$mime]] = $mime; - } - return $this->mimetypeIds[$mime]; + catch (\Doctrine\DBAL\DBALException $e){ + \OC_Log::write('core', 'Exception during mimetype insertion: ' . $e->getmessage(), \OC_Log::DEBUG); + return -1; + } + } + + return self::$mimetypeIds[$mime]; } public function getMimetype($id) { - if (!isset($this->mimetypes[$id])) { - $sql = 'SELECT `mimetype` FROM `*PREFIX*mimetypes` WHERE `id` = ?'; - $result = \OC_DB::executeAudited($sql, array($id)); - if ($row = $result->fetchRow()) { - $this->mimetypes[$id] = $row['mimetype']; - } else { - return null; - } + if (empty(self::$mimetypes)) { + $this->loadMimetypes(); } - return $this->mimetypes[$id]; + + return isset(self::$mimetypes[$id]) ? self::$mimetypes[$id] : null; + } + + public function loadMimetypes(){ + $result = \OC_DB::executeAudited('SELECT `id`, `mimetype` FROM `*PREFIX*mimetypes`', array()); + if ($result) { + while ($row = $result->fetchRow()) { + self::$mimetypeIds[$row['mimetype']] = $row['id']; + self::$mimetypes[$row['id']] = $row['mimetype']; + } + } } /** @@ -129,6 +144,7 @@ class Cache { $data['fileid'] = (int)$data['fileid']; $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; + $data['storage_mtime'] = (int)$data['storage_mtime']; $data['encrypted'] = (bool)$data['encrypted']; $data['unencrypted_size'] = (int)$data['unencrypted_size']; $data['storage'] = $this->storageId; @@ -162,6 +178,10 @@ class Cache { if ($file['storage_mtime'] == 0) { $file['storage_mtime'] = $file['mtime']; } + if ($file['encrypted'] or ($file['unencrypted_size'] > 0 and $file['mimetype'] === 'httpd/unix-directory')) { + $file['encrypted_size'] = $file['size']; + $file['size'] = $file['unencrypted_size']; + } } return $files; } else { @@ -491,22 +511,34 @@ class Cache { $entry = $this->get($path); if ($entry && $entry['mimetype'] === 'httpd/unix-directory') { $id = $entry['fileid']; - $sql = 'SELECT SUM(`size`), MIN(`size`) FROM `*PREFIX*filecache` '. + $sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2, ' . + 'SUM(`unencrypted_size`) AS f3 ' . + 'FROM `*PREFIX*filecache` ' . 'WHERE `parent` = ? AND `storage` = ?'; $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); if ($row = $result->fetchRow()) { - list($sum, $min) = array_values($row); + list($sum, $min, $unencryptedSum) = array_values($row); $sum = (int)$sum; $min = (int)$min; + $unencryptedSum = (int)$unencryptedSum; if ($min === -1) { $totalSize = $min; } else { $totalSize = $sum; } + $update = array(); if ($entry['size'] !== $totalSize) { - $this->update($id, array('size' => $totalSize)); + $update['size'] = $totalSize; + } + if ($entry['unencrypted_size'] !== $unencryptedSum) { + $update['unencrypted_size'] = $unencryptedSum; + } + if (count($update) > 0) { + $this->update($id, $update); + } + if ($totalSize !== -1 and $unencryptedSum > 0) { + $totalSize = $unencryptedSum; } - } } return $totalSize; diff --git a/lib/private/files/cache/homecache.php b/lib/private/files/cache/homecache.php new file mode 100644 index 00000000000..71bb944da71 --- /dev/null +++ b/lib/private/files/cache/homecache.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +class HomeCache extends Cache { + /** + * get the size of a folder and set it in the cache + * + * @param string $path + * @return int + */ + public function calculateFolderSize($path) { + if ($path !== '/' and $path !== '' and $path !== 'files') { + return parent::calculateFolderSize($path); + } + + $totalSize = 0; + $entry = $this->get($path); + if ($entry && $entry['mimetype'] === 'httpd/unix-directory') { + $id = $entry['fileid']; + $sql = 'SELECT SUM(`size`) FROM `*PREFIX*filecache` ' . + 'WHERE `parent` = ? AND `storage` = ? AND `size` >= 0'; + $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); + if ($row = $result->fetchRow()) { + list($sum) = array_values($row); + $totalSize = (int)$sum; + if ($entry['size'] !== $totalSize) { + $this->update($id, array('size' => $totalSize)); + } + } + } + return $totalSize; + } + + public function get($path) { + $data = parent::get($path); + if ($path === '' or $path === '/') { + // only the size of the "files" dir counts + $filesData = parent::get('files'); + + if (isset($filesData['size'])) { + $data['size'] = $filesData['size']; + } + } + return $data; + } +} diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index 96f84609cf2..92a4c01841b 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -17,6 +17,8 @@ use OC\Hooks\BasicEmitter; * Hooks available in scope \OC\Files\Cache\Scanner: * - scanFile(string $path, string $storageId) * - scanFolder(string $path, string $storageId) + * - postScanFile(string $path, string $storageId) + * - postScanFolder(string $path, string $storageId) * * @package OC\Files\Cache */ @@ -62,8 +64,12 @@ class Scanner extends BasicEmitter { * @return array with metadata of the file */ public function getData($path) { + if (!$this->storage->isReadable($path)) { + //cant read, nothing we can do + \OCP\Util::writeLog('OC\Files\Cache\Scanner', "!!! Path '$path' is not readable !!!", \OCP\Util::DEBUG); + return null; + } $data = array(); - if (!$this->storage->isReadable($path)) return null; //cant read, nothing we can do $data['mimetype'] = $this->storage->getMimeType($path); $data['mtime'] = $this->storage->filemtime($path); if ($data['mimetype'] == 'httpd/unix-directory') { @@ -104,7 +110,9 @@ class Scanner extends BasicEmitter { $newData = $data; $cacheData = $this->cache->get($file); if ($cacheData) { - $this->permissionsCache->remove($cacheData['fileid']); + if (isset($cacheData['fileid'])) { + $this->permissionsCache->remove($cacheData['fileid']); + } if ($reuseExisting) { // prevent empty etag $etag = $cacheData['etag']; @@ -114,7 +122,7 @@ class Scanner extends BasicEmitter { $propagateETagChange = true; } // only reuse data if the file hasn't explicitly changed - if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) { + if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) { if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) { $data['size'] = $cacheData['size']; } @@ -136,11 +144,20 @@ class Scanner extends BasicEmitter { } } // Only update metadata that has changed - $newData = array_diff($data, $cacheData); + $newData = array_diff_assoc($data, $cacheData); + if (isset($newData['etag'])) { + $cacheDataString = print_r($cacheData, true); + $dataString = print_r($data, true); + \OCP\Util::writeLog('OC\Files\Cache\Scanner', + "!!! No reuse of etag for '$file' !!! \ncache: $cacheDataString \ndata: $dataString", + \OCP\Util::DEBUG); + } } } if (!empty($newData)) { $this->cache->put($file, $newData); + $this->emit('\OC\Files\Cache\Scanner', 'postScanFile', array($file, $this->storageId)); + \OC_Hook::emit('\OC\Files\Cache\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId)); } } else { $this->cache->remove($file); @@ -190,24 +207,34 @@ class Scanner extends BasicEmitter { } $newChildren = array(); if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) { + $exceptionOccurred = false; \OC_DB::beginTransaction(); if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { $child = ($path) ? $path . '/' . $file : $file; if (!Filesystem::isIgnoredDir($file)) { $newChildren[] = $file; - $data = $this->scanFile($child, $reuse, true); - if ($data) { - if ($data['size'] === -1) { - if ($recursive === self::SCAN_RECURSIVE) { - $childQueue[] = $child; - } else { - $size = -1; + try { + $data = $this->scanFile($child, $reuse, true); + if ($data) { + if ($data['size'] === -1) { + if ($recursive === self::SCAN_RECURSIVE) { + $childQueue[] = $child; + } else { + $size = -1; + } + } else if ($size !== -1) { + $size += $data['size']; } - } else if ($size !== -1) { - $size += $data['size']; } } + catch (\Doctrine\DBAL\DBALException $ex){ + // might happen if inserting duplicate while a scanning + // process is running in parallel + // log and ignore + \OC_Log::write('core', 'Exception while scanning file "' . $child . '": ' . $ex->getMessage(), \OC_Log::DEBUG); + $exceptionOccurred = true; + } } } } @@ -217,6 +244,14 @@ class Scanner extends BasicEmitter { $this->cache->remove($child); } \OC_DB::commit(); + if ($exceptionOccurred){ + // It might happen that the parallel scan process has already + // inserted mimetypes but those weren't available yet inside the transaction + // To make sure to have the updated mime types in such cases, + // we reload them here + $this->cache->loadMimetypes(); + } + foreach ($childQueue as $child) { $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse); if ($childSize === -1) { @@ -227,6 +262,7 @@ class Scanner extends BasicEmitter { } $this->cache->put($path, array('size' => $size)); } + $this->emit('\OC\Files\Cache\Scanner', 'postScanFolder', array($path, $this->storageId)); return $size; } @@ -250,7 +286,7 @@ class Scanner extends BasicEmitter { public function backgroundScan() { $lastPath = null; while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { - $this->scan($path); + $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG); $this->cache->correctFolderSize($path); $lastPath = $path; } diff --git a/lib/private/files/cache/storage.php b/lib/private/files/cache/storage.php index 8a9e47ca36d..5657cf06e12 100644 --- a/lib/private/files/cache/storage.php +++ b/lib/private/files/cache/storage.php @@ -48,7 +48,7 @@ class Storage { } public static function getStorageId($numericId) { - + $sql = 'SELECT `id` FROM `*PREFIX*storages` WHERE `numeric_id` = ?'; $result = \OC_DB::executeAudited($sql, array($numericId)); if ($row = $result->fetchRow()) { @@ -57,4 +57,17 @@ class Storage { return null; } } + + public static function exists($storageId) { + if (strlen($storageId) > 64) { + $storageId = md5($storageId); + } + $sql = 'SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?'; + $result = \OC_DB::executeAudited($sql, array($storageId)); + if ($row = $result->fetchRow()) { + return true; + } else { + return false; + } + } } diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php index 1f30173a8f8..73bc30e538f 100644 --- a/lib/private/files/cache/updater.php +++ b/lib/private/files/cache/updater.php @@ -7,6 +7,7 @@ */ namespace OC\Files\Cache; + use OCP\Util; /** @@ -42,6 +43,7 @@ class Updater { $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); self::correctFolder($path, $storage->filemtime($internalPath)); + self::correctParentStorageMtime($storage, $internalPath); } } @@ -57,10 +59,15 @@ class Updater { */ list($storage, $internalPath) = self::resolvePath($path); if ($storage) { + $parent = dirname($internalPath); + if ($parent === '.') { + $parent = ''; + } $cache = $storage->getCache($internalPath); $cache->remove($internalPath); - $cache->correctFolderSize($internalPath); + $cache->correctFolderSize($parent); self::correctFolder($path, time()); + self::correctParentStorageMtime($storage, $internalPath); } } @@ -83,10 +90,18 @@ class Updater { if ($storageFrom === $storageTo) { $cache = $storageFrom->getCache($internalFrom); $cache->move($internalFrom, $internalTo); + if (pathinfo($internalFrom, PATHINFO_EXTENSION) !== pathinfo($internalTo, PATHINFO_EXTENSION)) { + // redetect mime type change + $mimeType = $storageTo->getMimeType($internalTo); + $fileId = $storageTo->getCache()->getId($internalTo); + $storageTo->getCache()->update($fileId, array('mimetype' => $mimeType)); + } $cache->correctFolderSize($internalFrom); $cache->correctFolderSize($internalTo); self::correctFolder($from, time()); self::correctFolder($to, time()); + self::correctParentStorageMtime($storageFrom, $internalFrom); + self::correctParentStorageMtime($storageTo, $internalTo); } else { self::deleteUpdate($from); self::writeUpdate($to); @@ -95,6 +110,24 @@ class Updater { } /** + * @brief get file owner and path + * @param string $filename + * @return array with the oweners uid and the owners path + */ + private static function getUidAndFilename($filename) { + + $uid = \OC\Files\Filesystem::getOwner($filename); + \OC\Files\Filesystem::initMountPoints($uid); + + if ($uid != \OCP\User::getUser()) { + $info = \OC\Files\Filesystem::getFileInfo($filename); + $ownerView = new \OC\Files\View('/' . $uid . '/files'); + $filename = $ownerView->getPath($info['fileid']); + } + return array($uid, '/files/' . $filename); + } + + /** * Update the mtime and ETag of all parent folders * * @param string $path @@ -102,29 +135,53 @@ class Updater { */ static public function correctFolder($path, $time) { if ($path !== '' && $path !== '/') { - $parent = dirname($path); - if ($parent === '.' || $parent === '\\') { - $parent = ''; - } + + list($owner, $realPath) = self::getUidAndFilename(dirname($path)); + /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = self::resolvePath($parent); - if ($storage) { - $cache = $storage->getCache(); - $id = $cache->getId($internalPath); - if ($id !== -1) { - $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); - self::correctFolder($parent, $time); + $view = new \OC\Files\View('/' . $owner); + + list($storage, $internalPath) = $view->resolvePath($realPath); + $cache = $storage->getCache(); + $id = $cache->getId($internalPath); + + while ($id !== -1) { + $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); + if ($realPath !== '') { + $realPath = dirname($realPath); + if($realPath === DIRECTORY_SEPARATOR ) { + $realPath = ""; + } + // check storage for parent in case we change the storage in this step + list($storage, $internalPath) = $view->resolvePath($realPath); + $cache = $storage->getCache(); + $id = $cache->getId($internalPath); } else { - Util::writeLog('core', 'Path not in cache: '.$internalPath, Util::ERROR); + $id = -1; } } } } /** + * update the storage_mtime of the parent + * + * @param \OC\Files\Storage\Storage $storage + * @param string $internalPath + */ + static private function correctParentStorageMtime($storage, $internalPath) { + $cache = $storage->getCache(); + $parentId = $cache->getParentId($internalPath); + $parent = dirname($internalPath); + if ($parentId != -1) { + $cache->update($parentId, array('storage_mtime' => $storage->filemtime($parent))); + } + } + + /** * @param array $params */ static public function writeHook($params) { diff --git a/lib/private/files/cache/upgrade.php b/lib/private/files/cache/upgrade.php index cfb9a117311..e3a46896cbf 100644 --- a/lib/private/files/cache/upgrade.php +++ b/lib/private/files/cache/upgrade.php @@ -192,7 +192,15 @@ class Upgrade { */ static function needUpgrade($user) { $cacheVersion = (int)\OCP\Config::getUserValue($user, 'files', 'cache_version', 4); - return $cacheVersion < 5; + if ($cacheVersion < 5) { + $legacy = new \OC\Files\Cache\Legacy($user); + if ($legacy->hasItems()) { + return true; + } + self::upgradeDone($user); + } + + return false; } /** diff --git a/lib/private/files/cache/watcher.php b/lib/private/files/cache/watcher.php index 8bfd4602f3a..251ecbe7071 100644 --- a/lib/private/files/cache/watcher.php +++ b/lib/private/files/cache/watcher.php @@ -15,17 +15,17 @@ class Watcher { /** * @var \OC\Files\Storage\Storage $storage */ - private $storage; + protected $storage; /** * @var Cache $cache */ - private $cache; + protected $cache; /** * @var Scanner $scanner; */ - private $scanner; + protected $scanner; /** * @param \OC\Files\Storage\Storage $storage @@ -40,6 +40,7 @@ class Watcher { * check $path for updates * * @param string $path + * @return boolean | array true if path was updated, otherwise the cached data is returned */ public function checkUpdate($path) { $cachedEntry = $this->cache->get($path); @@ -53,7 +54,9 @@ class Watcher { $this->cleanFolder($path); } $this->cache->correctFolderSize($path); + return true; } + return $cachedEntry; } /** diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index 10ec5c41d11..a83e9aa86d2 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -305,7 +305,21 @@ class Filesystem { $parser = new \OC\ArrayParser(); $root = \OC_User::getHome($user); - self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); + + $userObject = \OC_User::getManager()->get($user); + + if (!is_null($userObject)) { + // check for legacy home id (<= 5.0.12) + if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) { + self::mount('\OC\Files\Storage\Home', array('user' => $userObject, 'legacy' => true), $user); + } + else { + self::mount('\OC\Files\Storage\Home', array('user' => $userObject), $user); + } + } + else { + self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); + } $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data"); //move config file to it's new position @@ -675,18 +689,32 @@ class Filesystem { } //no windows style slashes $path = str_replace('\\', '/', $path); + //add leading slash if ($path[0] !== '/') { $path = '/' . $path; } - //remove duplicate slashes - while (strpos($path, '//') !== false) { - $path = str_replace('//', '/', $path); + + // remove '/./' + // ugly, but str_replace() can't replace them all in one go + // as the replacement itself is part of the search string + // which will only be found during the next iteration + while (strpos($path, '/./') !== false) { + $path = str_replace('/./', '/', $path); } + // remove sequences of slashes + $path = preg_replace('#/{2,}#', '/', $path); + //remove trailing slash if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { $path = substr($path, 0, -1); } + + // remove trailing '/.' + if (substr($path, -2) == '/.') { + $path = substr($path, 0, -2); + } + //normalize unicode if possible $path = \OC_Util::normalizeUnicode($path); @@ -697,6 +725,8 @@ class Filesystem { * get the filesystem info * * @param string $path + * @param boolean $includeMountPoints whether to add mountpoint sizes, + * defaults to true * @return array * * returns an associative array with the following keys: @@ -706,8 +736,8 @@ class Filesystem { * - encrypted * - versioned */ - public static function getFileInfo($path) { - return self::$defaultInstance->getFileInfo($path); + public static function getFileInfo($path, $includeMountPoints = true) { + return self::$defaultInstance->getFileInfo($path, $includeMountPoints); } /** diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index a5b79f0e967..678bf419023 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -21,11 +21,11 @@ namespace OC\Files\Storage; */ abstract class Common implements \OC\Files\Storage\Storage { - private $cache; - private $scanner; - private $permissioncache; - private $watcher; - private $storageCache; + protected $cache; + protected $scanner; + protected $permissioncache; + protected $watcher; + protected $storageCache; public function __construct($parameters) { } @@ -51,6 +51,19 @@ abstract class Common implements \OC\Files\Storage\Storage { } } + public function isReadable($path) { + // at least check whether it exists + // subclasses might want to implement this more thoroughly + return $this->file_exists($path); + } + + public function isUpdatable($path) { + // at least check whether it exists + // subclasses might want to implement this more thoroughly + // a non-existing file/folder isn't updatable + return $this->file_exists($path); + } + public function isCreatable($path) { if ($this->is_dir($path) && $this->isUpdatable($path)) { return true; @@ -142,7 +155,7 @@ abstract class Common implements \OC\Files\Storage\Storage { return false; } else { $directoryHandle = $this->opendir($directory); - if(is_resource($directoryHandle)) { + if (is_resource($directoryHandle)) { while (($contents = readdir($directoryHandle)) !== false) { if (!\OC\Files\Filesystem::isIgnoredDir($contents)) { $path = $directory . '/' . $contents; @@ -165,27 +178,13 @@ abstract class Common implements \OC\Files\Storage\Storage { } public function getMimeType($path) { - if (!$this->file_exists($path)) { - return false; - } if ($this->is_dir($path)) { return 'httpd/unix-directory'; - } - $source = $this->fopen($path, 'r'); - if (!$source) { - return false; - } - $head = fread($source, 8192); //8kb should suffice to determine a mimetype - if ($pos = strrpos($path, '.')) { - $extension = substr($path, $pos); + } elseif ($this->file_exists($path)) { + return \OC_Helper::getFileNameMimeType($path); } else { - $extension = ''; + return false; } - $tmpFile = \OC_Helper::tmpFile($extension); - file_put_contents($tmpFile, $head); - $mime = \OC_Helper::getMimeType($tmpFile); - unlink($tmpFile); - return $mime; } public function hash($type, $path, $raw = false) { @@ -227,7 +226,7 @@ abstract class Common implements \OC\Files\Storage\Storage { private function addLocalFolder($path, $target) { $dh = $this->opendir($path); - if(is_resource($dh)) { + if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { if ($file !== '.' and $file !== '..') { if ($this->is_dir($path . '/' . $file)) { @@ -298,7 +297,7 @@ abstract class Common implements \OC\Files\Storage\Storage { return $this->watcher; } - public function getStorageCache(){ + public function getStorageCache() { if (!isset($this->storageCache)) { $this->storageCache = new \OC\Files\Cache\Storage($this); } diff --git a/lib/private/files/storage/commontest.php b/lib/private/files/storage/commontest.php index c3f1eb31955..2394b14a82f 100644 --- a/lib/private/files/storage/commontest.php +++ b/lib/private/files/storage/commontest.php @@ -54,7 +54,7 @@ class CommonTest extends \OC\Files\Storage\Common{ return $this->storage->stat($path); } public function filetype($path) { - return $this->storage->filetype($path); + return @$this->storage->filetype($path); } public function isReadable($path) { return $this->storage->isReadable($path); diff --git a/lib/private/files/storage/home.php b/lib/private/files/storage/home.php new file mode 100644 index 00000000000..1c2a682f197 --- /dev/null +++ b/lib/private/files/storage/home.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + +/** + * Specialized version of Local storage for home directory usage + */ +class Home extends Local { + /** + * @var string + */ + protected $id; + + /** + * @var \OC\User\User $user + */ + protected $user; + + /** + * @brief Construct a Home storage instance + * @param array $arguments array with "user" containing the + * storage owner and "legacy" containing "true" if the storage is + * a legacy storage with "local::" URL instead of the new "home::" one. + */ + public function __construct($arguments) { + $this->user = $arguments['user']; + $datadir = $this->user->getHome(); + if (isset($arguments['legacy']) && $arguments['legacy']) { + // legacy home id (<= 5.0.12) + $this->id = 'local::' . $datadir . '/'; + } + else { + $this->id = 'home::' . $this->user->getUID(); + } + + parent::__construct(array('datadir' => $datadir)); + } + + public function getId() { + return $this->id; + } + + /** + * @return \OC\Files\Cache\HomeCache + */ + public function getCache($path = '') { + if (!isset($this->cache)) { + $this->cache = new \OC\Files\Cache\HomeCache($this); + } + return $this->cache; + } + + /** + * @brief Returns the owner of this home storage + * @return \OC\User\User owner of this home storage + */ + public function getUser() { + return $this->user; + } +} diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index 5209fabc30a..db3c6bfca3a 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -203,14 +203,6 @@ if (\OC_Util::runningOnWindows()) { return $return; } - public function getMimeType($path) { - if ($this->isReadable($path)) { - return \OC_Helper::getMimeType($this->datadir . $path); - } else { - return false; - } - } - private function delTree($dir) { $dirRelative = $dir; $dir = $this->datadir . $dir; @@ -264,7 +256,7 @@ if (\OC_Util::runningOnWindows()) { public function free_space($path) { $space = @disk_free_space($this->datadir . $path); - if ($space === false) { + if ($space === false || is_null($space)) { return \OC\Files\SPACE_UNKNOWN; } return $space; diff --git a/lib/private/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php index ba5ac4191c5..6c37d445867 100644 --- a/lib/private/files/storage/mappedlocal.php +++ b/lib/private/files/storage/mappedlocal.php @@ -210,14 +210,6 @@ class MappedLocal extends \OC\Files\Storage\Common{ return $return; } - public function getMimeType($path) { - if($this->isReadable($path)) { - return \OC_Helper::getMimeType($this->buildPath($path)); - }else{ - return false; - } - } - private function delTree($dir, $isLogicPath=true) { $dirRelative=$dir; if ($isLogicPath) { diff --git a/lib/private/files/storage/storage.php b/lib/private/files/storage/storage.php index b673bb9a32d..5be90f24756 100644 --- a/lib/private/files/storage/storage.php +++ b/lib/private/files/storage/storage.php @@ -14,278 +14,6 @@ namespace OC\Files\Storage; * All paths passed to the storage are relative to the storage and should NOT have a leading slash. */ interface Storage extends \OCP\Files\Storage { - /** - * $parameters is a free form array with the configuration options needed to construct the storage - * - * @param array $parameters - */ - public function __construct($parameters); - - /** - * Get the identifier for the storage, - * the returned id should be the same for every storage object that is created with the same parameters - * and two storage objects with the same id should refer to two storages that display the same files. - * - * @return string - */ - public function getId(); - - /** - * see http://php.net/manual/en/function.mkdir.php - * - * @param string $path - * @return bool - */ - public function mkdir($path); - - /** - * see http://php.net/manual/en/function.rmdir.php - * - * @param string $path - * @return bool - */ - public function rmdir($path); - - /** - * see http://php.net/manual/en/function.opendir.php - * - * @param string $path - * @return resource - */ - public function opendir($path); - - /** - * see http://php.net/manual/en/function.is_dir.php - * - * @param string $path - * @return bool - */ - public function is_dir($path); - - /** - * see http://php.net/manual/en/function.is_file.php - * - * @param string $path - * @return bool - */ - public function is_file($path); - - /** - * see http://php.net/manual/en/function.stat.php - * only the following keys are required in the result: size and mtime - * - * @param string $path - * @return array - */ - public function stat($path); - - /** - * see http://php.net/manual/en/function.filetype.php - * - * @param string $path - * @return bool - */ - public function filetype($path); - - /** - * see http://php.net/manual/en/function.filesize.php - * The result for filesize when called on a folder is required to be 0 - * - * @param string $path - * @return int - */ - public function filesize($path); - - /** - * check if a file can be created in $path - * - * @param string $path - * @return bool - */ - public function isCreatable($path); - - /** - * check if a file can be read - * - * @param string $path - * @return bool - */ - public function isReadable($path); - - /** - * check if a file can be written to - * - * @param string $path - * @return bool - */ - public function isUpdatable($path); - - /** - * check if a file can be deleted - * - * @param string $path - * @return bool - */ - public function isDeletable($path); - - /** - * check if a file can be shared - * - * @param string $path - * @return bool - */ - public function isSharable($path); - - /** - * get the full permissions of a path. - * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php - * - * @param string $path - * @return int - */ - public function getPermissions($path); - - /** - * see http://php.net/manual/en/function.file_exists.php - * - * @param string $path - * @return bool - */ - public function file_exists($path); - - /** - * see http://php.net/manual/en/function.filemtime.php - * - * @param string $path - * @return int - */ - public function filemtime($path); - - /** - * see http://php.net/manual/en/function.file_get_contents.php - * - * @param string $path - * @return string - */ - public function file_get_contents($path); - - /** - * see http://php.net/manual/en/function.file_put_contents.php - * - * @param string $path - * @param string $data - * @return bool - */ - public function file_put_contents($path, $data); - - /** - * see http://php.net/manual/en/function.unlink.php - * - * @param string $path - * @return bool - */ - public function unlink($path); - - /** - * see http://php.net/manual/en/function.rename.php - * - * @param string $path1 - * @param string $path2 - * @return bool - */ - public function rename($path1, $path2); - - /** - * see http://php.net/manual/en/function.copy.php - * - * @param string $path1 - * @param string $path2 - * @return bool - */ - public function copy($path1, $path2); - - /** - * see http://php.net/manual/en/function.fopen.php - * - * @param string $path - * @param string $mode - * @return resource - */ - public function fopen($path, $mode); - - /** - * get the mimetype for a file or folder - * The mimetype for a folder is required to be "httpd/unix-directory" - * - * @param string $path - * @return string - */ - public function getMimeType($path); - - /** - * see http://php.net/manual/en/function.hash.php - * - * @param string $type - * @param string $path - * @param bool $raw - * @return string - */ - public function hash($type, $path, $raw = false); - - /** - * see http://php.net/manual/en/function.free_space.php - * - * @param string $path - * @return int - */ - public function free_space($path); - - /** - * search for occurrences of $query in file names - * - * @param string $query - * @return array - */ - public function search($query); - - /** - * see http://php.net/manual/en/function.touch.php - * If the backend does not support the operation, false should be returned - * - * @param string $path - * @param int $mtime - * @return bool - */ - public function touch($path, $mtime = null); - - /** - * get the path to a local version of the file. - * The local version of the file can be temporary and doesn't have to be persistent across requests - * - * @param string $path - * @return string - */ - public function getLocalFile($path); - - /** - * get the path to a local version of the folder. - * The local version of the folder can be temporary and doesn't have to be persistent across requests - * - * @param string $path - * @return string - */ - public function getLocalFolder($path); - /** - * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool - * - * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed. - * returning true for other changes in the folder is optional - */ - public function hasUpdated($path, $time); /** * get a cache instance for the storage @@ -333,11 +61,4 @@ interface Storage extends \OCP\Files\Storage { */ public function getStorageCache(); - /** - * get the ETag for a file or folder - * - * @param string $path - * @return string - */ - public function getETag($path); } diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php index e2da8cf2e05..a430e3e4617 100644 --- a/lib/private/files/storage/wrapper/quota.php +++ b/lib/private/files/storage/wrapper/quota.php @@ -95,7 +95,7 @@ class Quota extends Wrapper { public function fopen($path, $mode) { $source = $this->storage->fopen($path, $mode); $free = $this->free_space(''); - if ($free >= 0) { + if ($source && $free >= 0 && $mode !== 'r' && $mode !== 'rb') { return \OC\Files\Stream\Quota::wrap($source, $free); } else { return $source; diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php index 0336c27efa1..f9adda80314 100644 --- a/lib/private/files/storage/wrapper/wrapper.php +++ b/lib/private/files/storage/wrapper/wrapper.php @@ -424,4 +424,12 @@ class Wrapper implements \OC\Files\Storage\Storage { public function getETag($path) { return $this->storage->getETag($path); } + + /** + * Returns true + * @return true + */ + public function test() { + return $this->storage->test(); + } } diff --git a/lib/private/files/stream/quota.php b/lib/private/files/stream/quota.php index 53d8a03d30f..60e60da8e67 100644 --- a/lib/private/files/stream/quota.php +++ b/lib/private/files/stream/quota.php @@ -66,12 +66,24 @@ class Quota { } public function stream_seek($offset, $whence = SEEK_SET) { - if ($whence === SEEK_SET) { + if ($whence === SEEK_END){ + // go to the end to find out last position's offset + $oldOffset = $this->stream_tell(); + if (fseek($this->source, 0, $whence) !== 0){ + return false; + } + $whence = SEEK_SET; + $offset = $this->stream_tell() + $offset; + $this->limit += $oldOffset - $offset; + } + else if ($whence === SEEK_SET) { $this->limit += $this->stream_tell() - $offset; } else { $this->limit -= $offset; } - fseek($this->source, $offset, $whence); + // this wrapper needs to return "true" for success. + // the fseek call itself returns 0 on succeess + return !fseek($this->source, $offset, $whence); } public function stream_tell() { diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php index 242a81cb5a4..d7cc9ebbf4e 100644 --- a/lib/private/files/type/detection.php +++ b/lib/private/files/type/detection.php @@ -61,8 +61,6 @@ class Detection { * @return string */ public function detect($path) { - $isWrapped = (strpos($path, '://') !== false) and (substr($path, 0, 7) === 'file://'); - if (@is_dir($path)) { // directories are easy return "httpd/unix-directory"; @@ -76,9 +74,11 @@ class Detection { $info = @strtolower(finfo_file($finfo, $path)); if ($info) { $mimeType = substr($info, 0, strpos($info, ';')); + return empty($mimeType) ? 'application/octet-stream' : $mimeType; } finfo_close($finfo); } + $isWrapped = (strpos($path, '://') !== false) and (substr($path, 0, 7) === 'file://'); if (!$isWrapped and $mimeType === 'application/octet-stream' && function_exists("mime_content_type")) { // use mime magic extension if available $mimeType = mime_content_type($path); @@ -94,6 +94,10 @@ class Detection { //trim the newline $mimeType = trim($reply); + if (empty($mimeType)) { + $mimeType = 'application/octet-stream'; + } + } return $mimeType; } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index aa08a5f7cc9..d97544b865e 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -110,7 +110,9 @@ class View { * @return array consisting of the storage and the internal path */ public function resolvePath($path) { - return Filesystem::resolvePath($this->getAbsolutePath($path)); + $a = $this->getAbsolutePath($path); + $p = Filesystem::normalizePath($a); + return Filesystem::resolvePath($p); } /** @@ -157,7 +159,11 @@ class View { } public function rmdir($path) { - return $this->basicOperation('rmdir', $path, array('delete')); + if ($this->is_dir($path)) { + return $this->basicOperation('rmdir', $path, array('delete')); + } else { + return false; + } } public function opendir($path) { @@ -324,11 +330,25 @@ class View { return false; } } else { - return $this->basicOperation('file_put_contents', $path, array('create', 'write'), $data); + $hooks = ($this->file_exists($path)) ? array('write') : array('create', 'write'); + return $this->basicOperation('file_put_contents', $path, $hooks, $data); } } public function unlink($path) { + if ($path === '' || $path === '/') { + // do not allow deleting the root + return false; + } + $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); + if (!$internalPath || $internalPath === '' || $internalPath === '/') { + // do not allow deleting the storage's root / the mount point + // because for some storages it might delete the whole contents + // but isn't supposed to work that way + return false; + } return $this->basicOperation('unlink', $path, array('delete')); } @@ -709,7 +729,10 @@ class View { return false; } $defaultRoot = Filesystem::getRoot(); - return (strlen($this->fakeRoot) >= strlen($defaultRoot)) && (substr($this->fakeRoot, 0, strlen($defaultRoot)) === $defaultRoot); + if ($this->fakeRoot === $defaultRoot) { + return true; + } + return (strlen($this->fakeRoot) > strlen($defaultRoot)) && (substr($this->fakeRoot, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/'); } private function runHooks($hooks, $path, $post = false) { @@ -756,6 +779,8 @@ class View { * get the filesystem info * * @param string $path + * @param boolean $includeMountPoints whether to add mountpoint sizes, + * defaults to true * @return array * * returns an associative array with the following keys: @@ -765,7 +790,7 @@ class View { * - encrypted * - versioned */ - public function getFileInfo($path) { + public function getFileInfo($path, $includeMountPoints = true) { $data = array(); if (!Filesystem::isValidPath($path)) { return $data; @@ -776,6 +801,7 @@ class View { * @var string $internalPath */ list($storage, $internalPath) = Filesystem::resolvePath($path); + $data = null; if ($storage) { $cache = $storage->getCache($internalPath); $permissionsCache = $storage->getPermissionsCache($internalPath); @@ -786,13 +812,15 @@ class View { $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { $watcher = $storage->getWatcher($internalPath); - $watcher->checkUpdate($internalPath); + $data = $watcher->checkUpdate($internalPath); } - $data = $cache->get($internalPath); + if (!is_array($data)) { + $data = $cache->get($internalPath); + } if ($data and $data['fileid']) { - if ($data['mimetype'] === 'httpd/unix-directory') { + if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { @@ -898,7 +926,8 @@ class View { $permissions = $subStorage->getPermissions($rootEntry['path']); $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); } - $rootEntry['permissions'] = $permissions; + // do not allow renaming/deleting the mount point + $rootEntry['permissions'] = $permissions & (\OCP\PERMISSION_ALL - (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE)); //remove any existing entry with the same name foreach ($files as $i => $file) { diff --git a/lib/private/group.php b/lib/private/group.php index ba93dc129a1..444788c97f1 100644 --- a/lib/private/group.php +++ b/lib/private/group.php @@ -265,10 +265,10 @@ class OC_Group { public static function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { $group = self::getManager()->get($gid); if ($group) { - $users = $group->searchDisplayName($search . $limit, $offset); + $users = $group->searchDisplayName($search, $limit, $offset); $displayNames = array(); foreach ($users as $user) { - $displayNames[] = $user->getDisplayName(); + $displayNames[$user->getUID()] = $user->getDisplayName(); } return $displayNames; } else { diff --git a/lib/private/group/group.php b/lib/private/group/group.php index bcd2419b309..8d2aa87a788 100644 --- a/lib/private/group/group.php +++ b/lib/private/group/group.php @@ -18,7 +18,12 @@ class Group { /** * @var \OC\User\User[] $users */ - private $users; + private $users = array(); + + /** + * @var bool $usersLoaded + */ + private $usersLoaded; /** * @var \OC_Group_Backend[] | \OC_Group_Database[] $backend @@ -26,7 +31,7 @@ class Group { private $backends; /** - * @var \OC\Hooks\PublicEmitter $emitter; + * @var \OC\Hooks\PublicEmitter $emitter */ private $emitter; @@ -58,7 +63,7 @@ class Group { * @return \OC\User\User[] */ public function getUsers() { - if ($this->users) { + if ($this->usersLoaded) { return $this->users; } @@ -74,6 +79,7 @@ class Group { } $this->users = $this->getVerifiedUsers($userIds); + $this->usersLoaded = true; return $this->users; } @@ -84,8 +90,12 @@ class Group { * @return bool */ public function inGroup($user) { + if (isset($this->users[$user->getUID()])) { + return true; + } foreach ($this->backends as $backend) { if ($backend->inGroup($user->getUID(), $this->gid)) { + $this->users[$user->getUID()] = $user; return true; } } @@ -185,6 +195,7 @@ class Group { * @return \OC\User\User[] */ public function searchDisplayName($search, $limit = null, $offset = null) { + $users = array(); foreach ($this->backends as $backend) { if ($backend->implementsActions(OC_GROUP_BACKEND_GET_DISPLAYNAME)) { $userIds = array_keys($backend->displayNamesInGroup($this->gid, $search, $limit, $offset)); @@ -229,17 +240,17 @@ class Group { /** * @brief returns all the Users from an array that really exists - * @param $userIds an array containing user IDs - * @return an Array with the userId as Key and \OC\User\User as value + * @param string[] $userIds an array containing user IDs + * @return \OC\User\User[] an Array with the userId as Key and \OC\User\User as value */ private function getVerifiedUsers($userIds) { - if(!is_array($userIds)) { + if (!is_array($userIds)) { return array(); } $users = array(); foreach ($userIds as $userId) { $user = $this->userManager->get($userId); - if(!is_null($user)) { + if (!is_null($user)) { $users[$userId] = $user; } } diff --git a/lib/private/helper.php b/lib/private/helper.php index 66e7acb407a..580f81acc62 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -41,8 +41,7 @@ class OC_Helper { * Returns a url to the given app and file. */ public static function linkToRoute($route, $parameters = array()) { - $urlLinkTo = OC::getRouter()->generate($route, $parameters); - return $urlLinkTo; + return OC::$server->getURLGenerator()->linkToRoute($route, $parameters); } /** @@ -56,32 +55,16 @@ class OC_Helper { * Returns a url to the given app and file. */ public static function linkTo( $app, $file, $args = array() ) { - if( $app != '' ) { - $app_path = OC_App::getAppPath($app); - // Check if the app is in the app folder - if ($app_path && file_exists($app_path . '/' . $file)) { - if (substr($file, -3) == 'php' || substr($file, -3) == 'css') { - $urlLinkTo = OC::$WEBROOT . '/index.php/apps/' . $app; - $urlLinkTo .= ($file != 'index.php') ? '/' . $file : ''; - } else { - $urlLinkTo = OC_App::getAppWebPath($app) . '/' . $file; - } - } else { - $urlLinkTo = OC::$WEBROOT . '/' . $app . '/' . $file; - } - } else { - if (file_exists(OC::$SERVERROOT . '/core/' . $file)) { - $urlLinkTo = OC::$WEBROOT . '/core/' . $file; - } else { - $urlLinkTo = OC::$WEBROOT . '/' . $file; - } - } - - if ($args && $query = http_build_query($args, '', '&')) { - $urlLinkTo .= '?' . $query; - } + return OC::$server->getURLGenerator()->linkTo($app, $file, $args); + } - return $urlLinkTo; + /** + * @param $key + * @return string url to the online documentation + */ + public static function linkToDocs($key) { + $theme = new OC_Defaults(); + return $theme->getDocBaseUrl() . '/server/6.0/go.php?to=' . $key; } /** @@ -107,7 +90,7 @@ class OC_Helper { * Returns a absolute url to the given app and file. */ public static function makeURLAbsolute($url) { - return OC_Request::serverProtocol() . '://' . OC_Request::serverHost() . $url; + return OC::$server->getURLGenerator()->getAbsoluteURL($url); } /** @@ -156,25 +139,7 @@ class OC_Helper { * Returns the path to the image. */ public static function imagePath($app, $image) { - // Read the selected theme from the config file - $theme = OC_Util::getTheme(); - - // Check if the app is in the app folder - if (file_exists(OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$image")) { - return OC::$WEBROOT . "/themes/$theme/apps/$app/img/$image"; - } elseif (file_exists(OC_App::getAppPath($app) . "/img/$image")) { - return OC_App::getAppWebPath($app) . "/img/$image"; - } elseif (!empty($app) and file_exists(OC::$SERVERROOT . "/themes/$theme/$app/img/$image")) { - return OC::$WEBROOT . "/themes/$theme/$app/img/$image"; - } elseif (!empty($app) and file_exists(OC::$SERVERROOT . "/$app/img/$image")) { - return OC::$WEBROOT . "/$app/img/$image"; - } elseif (file_exists(OC::$SERVERROOT . "/themes/$theme/core/img/$image")) { - return OC::$WEBROOT . "/themes/$theme/core/img/$image"; - } elseif (file_exists(OC::$SERVERROOT . "/core/img/$image")) { - return OC::$WEBROOT . "/core/img/$image"; - } else { - throw new RuntimeException('image not found: image:' . $image . ' webroot:' . OC::$WEBROOT . ' serverroot:' . OC::$SERVERROOT); - } + return OC::$server->getURLGenerator()->imagePath($app, $image); } /** @@ -196,6 +161,7 @@ class OC_Helper { 'application/vnd.oasis.opendocument.text-template' => 'x-office/document', 'application/vnd.oasis.opendocument.text-web' => 'x-office/document', 'application/vnd.oasis.opendocument.text-master' => 'x-office/document', + 'application/mspowerpoint' => 'x-office/presentation', 'application/vnd.ms-powerpoint' => 'x-office/presentation', 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'x-office/presentation', 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'x-office/presentation', @@ -206,6 +172,7 @@ class OC_Helper { 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => 'x-office/presentation', 'application/vnd.oasis.opendocument.presentation' => 'x-office/presentation', 'application/vnd.oasis.opendocument.presentation-template' => 'x-office/presentation', + 'application/msexcel' => 'x-office/spreadsheet', 'application/vnd.ms-excel' => 'x-office/spreadsheet', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'x-office/spreadsheet', 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'x-office/spreadsheet', @@ -215,6 +182,7 @@ class OC_Helper { 'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => 'x-office/spreadsheet', 'application/vnd.oasis.opendocument.spreadsheet' => 'x-office/spreadsheet', 'application/vnd.oasis.opendocument.spreadsheet-template' => 'x-office/spreadsheet', + 'application/msaccess' => 'database', ); if (isset($alias[$mimetype])) { @@ -266,11 +234,11 @@ class OC_Helper { * Returns the path to the preview of the file. */ public static function previewIcon($path) { - return self::linkToRoute( 'core_ajax_preview', array('x' => 36, 'y' => 36, 'file' => urlencode($path) )); + return self::linkToRoute( 'core_ajax_preview', array('x' => 36, 'y' => 36, 'file' => $path )); } public static function publicPreviewIcon( $path, $token ) { - return self::linkToRoute( 'core_ajax_public_preview', array('x' => 36, 'y' => 36, 'file' => urlencode($path), 't' => $token)); + return self::linkToRoute( 'core_ajax_public_preview', array('x' => 36, 'y' => 36, 'file' => $path, 't' => $token)); } /** @@ -287,7 +255,7 @@ class OC_Helper { if ($bytes < 1024) { return "$bytes B"; } - $bytes = round($bytes / 1024, 1); + $bytes = round($bytes / 1024, 0); if ($bytes < 1024) { return "$bytes kB"; } @@ -480,29 +448,6 @@ class OC_Helper { * */ - //FIXME: should also check for value validation (i.e. the email is an email). - public static function init_var($s, $d = "") { - $r = $d; - if (isset($_REQUEST[$s]) && !empty($_REQUEST[$s])) { - $r = OC_Util::sanitizeHTML($_REQUEST[$s]); - } - - return $r; - } - - /** - * returns "checked"-attribute if request contains selected radio element - * OR if radio element is the default one -- maybe? - * - * @param string $s Name of radio-button element name - * @param string $v Value of current radio-button element - * @param string $d Value of default radio-button element - */ - public static function init_radio($s, $v, $d) { - if ((isset($_REQUEST[$s]) && $_REQUEST[$s] == $v) || (!isset($_REQUEST[$s]) && $v == $d)) - print "checked=\"checked\" "; - } - /** * detect if a given program is found in the search PATH * @@ -553,11 +498,11 @@ class OC_Helper { * * @param resource $source * @param resource $target - * @return int the number of bytes copied + * @return array the number of bytes copied and result */ public static function streamCopy($source, $target) { if (!$source or !$target) { - return false; + return array(0, false); } $result = true; $count = 0; @@ -863,23 +808,39 @@ class OC_Helper { * @return number of bytes representing */ public static function maxUploadFilesize($dir) { - $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize')); - $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); - $freeSpace = \OC\Files\Filesystem::free_space($dir); - if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) { - $maxUploadFilesize = \OC\Files\SPACE_UNLIMITED; - } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) { - $maxUploadFilesize = max($upload_max_filesize, $post_max_size); //only the non 0 value counts - } else { - $maxUploadFilesize = min($upload_max_filesize, $post_max_size); - } + return min(self::freeSpace($dir), self::uploadLimit()); + } + /** + * Calculate free space left within user quota + * + * @param $dir the current folder where the user currently operates + * @return number of bytes representing + */ + public static function freeSpace($dir) { + $freeSpace = \OC\Files\Filesystem::free_space($dir); if ($freeSpace !== \OC\Files\SPACE_UNKNOWN) { $freeSpace = max($freeSpace, 0); + return $freeSpace; + } else { + return INF; + } + } - return min($maxUploadFilesize, $freeSpace); + /** + * Calculate PHP upload limit + * + * @return PHP upload file size limit + */ + public static function uploadLimit() { + $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize')); + $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); + if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) { + return INF; + } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) { + return max($upload_max_filesize, $post_max_size); //only the non 0 value counts } else { - return $maxUploadFilesize; + return min($upload_max_filesize, $post_max_size); } } @@ -893,11 +854,13 @@ class OC_Helper { if (!function_exists($function_name)) { return false; } - $disabled = explode(', ', ini_get('disable_functions')); + $disabled = explode(',', ini_get('disable_functions')); + $disabled = array_map('trim', $disabled); if (in_array($function_name, $disabled)) { return false; } - $disabled = explode(', ', ini_get('suhosin.executor.func.blacklist')); + $disabled = explode(',', ini_get('suhosin.executor.func.blacklist')); + $disabled = array_map('trim', $disabled); if (in_array($function_name, $disabled)) { return false; } @@ -911,7 +874,8 @@ class OC_Helper { * @return array */ public static function getStorageInfo($path) { - $rootInfo = \OC\Files\Filesystem::getFileInfo($path); + // return storage info without adding mount points + $rootInfo = \OC\Files\Filesystem::getFileInfo($path, false); $used = $rootInfo['size']; if ($used < 0) { $used = 0; diff --git a/lib/private/hook.php b/lib/private/hook.php index 8516cf0dcff..b63b442c31b 100644 --- a/lib/private/hook.php +++ b/lib/private/hook.php @@ -97,4 +97,12 @@ class OC_Hook{ self::$registered=array(); } } + + /** + * DO NOT USE! + * For unit tests ONLY! + */ + static public function getHooks() { + return self::$registered; + } } diff --git a/lib/private/image.php b/lib/private/image.php index 7761a3c7737..91a9f91e1d6 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -409,14 +409,14 @@ class OC_Image { /** * @brief Loads an image from a local file. - * @param $imageref The path to a local file. + * @param $imagePath The path to a local file. * @returns An image resource or false on error */ public function loadFromFile($imagePath=false) { // exif_imagetype throws "read error!" if file is less than 12 byte if(!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) { // Debug output disabled because this method is tried before loadFromBase64? - OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: '.$imagePath, OC_Log::DEBUG); + OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: ' . (string) urlencode($imagePath), OC_Log::DEBUG); return false; } $iType = exif_imagetype($imagePath); diff --git a/lib/private/installer.php b/lib/private/installer.php index 89358e78277..835b6b4c01a 100644 --- a/lib/private/installer.php +++ b/lib/private/installer.php @@ -147,7 +147,14 @@ class OC_Installer{ } // check if the ocs version is the same as the version in info.xml/version - if(!isset($info['version']) or ($info['version']<>$data['appdata']['version'])) { + $versionFile= $extractDir.'/appinfo/version'; + if(is_file($versionFile)) { + $version = trim(file_get_contents($versionFile)); + }else{ + $version = trim($info['version']); + } + + if($version<>trim($data['appdata']['version'])) { OC_Helper::rmdirr($extractDir); throw new \Exception($l->t("App can't be installed because the version in info.xml/version is not the same as the version reported from the app store")); } @@ -181,7 +188,11 @@ class OC_Installer{ //install the database if(is_file($basedir.'/appinfo/database.xml')) { - OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml'); + if (OC_Appconfig::getValue($info['id'], 'installed_version') === null) { + OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml'); + } else { + OC_DB::updateDbFromStructure($basedir.'/appinfo/database.xml'); + } } //run appinfo/install.php @@ -259,7 +270,7 @@ class OC_Installer{ /** * @brief Check if an update for the app is available * @param $name name of the application - * @returns empty string is no update available or the version number of the update + * @return boolean false or the version number of the update * * The function will check if an update for a version is available */ @@ -275,11 +286,11 @@ class OC_Installer{ return($ocsversion); }else{ - return(''); + return false; } }else{ - return(''); + return false; } } @@ -397,7 +408,7 @@ class OC_Installer{ } $info=OC_App::getAppInfo($app); if (is_null($info)) { - return; + return false; } OC_Appconfig::setValue($app, 'installed_version', OC_App::getAppVersion($app)); @@ -452,8 +463,7 @@ class OC_Installer{ ); // is the code checker enabled? - if(OC_Config::getValue('appcodechecker', false)) { - + if(OC_Config::getValue('appcodechecker', true)) { // check if grep is installed $grep = exec('which grep'); if($grep=='') { diff --git a/lib/private/json.php b/lib/private/json.php index 6ba0b13806b..5c5d7e3a3da 100644 --- a/lib/private/json.php +++ b/lib/private/json.php @@ -65,6 +65,20 @@ class OC_JSON{ } /** + * Check is a given user exists - send json error msg if not + * @param string $user + */ + public static function checkUserExists($user) { + if (!OCP\User::userExists($user)) { + $l = OC_L10N::get('lib'); + OCP\JSON::error(array('data' => array('message' => $l->t('Unknown user')))); + exit; + } + } + + + + /** * Check if the user is a subadmin, send json error msg if not */ public static function checkSubAdminUser() { @@ -109,7 +123,16 @@ class OC_JSON{ if($setContentType) { self::setContentTypeHeader(); } - array_walk_recursive($data, array('OC_JSON', 'to_string')); - echo json_encode($data); + echo self::encode($data); + } + + /** + * Encode JSON + */ + public static function encode($data) { + if (is_array($data)) { + array_walk_recursive($data, array('OC_JSON', 'to_string')); + } + return json_encode($data); } } diff --git a/lib/private/l10n.php b/lib/private/l10n.php index f93443b886a..98665c84c55 100644 --- a/lib/private/l10n.php +++ b/lib/private/l10n.php @@ -25,12 +25,7 @@ /** * This class is for i18n and l10n */ -class OC_L10N { - /** - * cached instances - */ - protected static $instances=array(); - +class OC_L10N implements \OCP\IL10N { /** * cache */ @@ -83,13 +78,10 @@ class OC_L10N { * @return OC_L10N */ public static function get($app, $lang=null) { - if(is_null($lang)) { - if(!isset(self::$instances[$app])) { - self::$instances[$app]=new OC_L10N($app); - } - return self::$instances[$app]; - }else{ - return new OC_L10N($app, $lang); + if (is_null($lang)) { + return OC::$server->getL10N($app); + } else { + return new \OC_L10N($app, $lang); } } @@ -270,7 +262,7 @@ class OC_L10N { */ public function n($text_singular, $text_plural, $count, $parameters = array()) { $this->init(); - $identifier = "_${text_singular}__${text_plural}_"; + $identifier = "_${text_singular}_::_${text_plural}_"; if( array_key_exists($identifier, $this->translations)) { return new OC_L10N_String( $this, $identifier, $parameters, $count ); } @@ -427,7 +419,7 @@ class OC_L10N { /** * @brief find the best language * @param $app Array or string, details below - * @returns language + * @returns string language * * If $app is an array, ownCloud assumes that these are the available * languages. Otherwise ownCloud tries to find the files in the l10n @@ -446,8 +438,7 @@ class OC_L10N { if(is_array($app)) { $available = $app; $lang_exists = array_search($lang, $available) !== false; - } - else { + } else { $lang_exists = self::languageExists($app, $lang); } if($lang_exists) { @@ -455,35 +446,40 @@ class OC_L10N { } } - $default_language = OC_Config::getValue('default_language', false); + $default_language = OC_Config::getValue('default_language', false); - if($default_language !== false) { - return $default_language; - } + if($default_language !== false) { + return $default_language; + } if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - $accepted_languages = preg_split('/,\s*/', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])); if(is_array($app)) { $available = $app; - } - else{ + } else { $available = self::findAvailableLanguages($app); } - foreach($accepted_languages as $i) { - $temp = explode(';', $i); - $temp[0] = str_replace('-', '_', $temp[0]); - if( ($key = array_search($temp[0], $available)) !== false) { - if (is_null($app)) { - self::$language = $available[$key]; + + // E.g. make sure that 'de' is before 'de_DE'. + sort($available); + + $preferences = preg_split('/,\s*/', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])); + foreach($preferences as $preference) { + list($preferred_language) = explode(';', $preference); + $preferred_language = str_replace('-', '_', $preferred_language); + foreach($available as $available_language) { + if ($preferred_language === strtolower($available_language)) { + if (is_null($app)) { + self::$language = $available_language; + } + return $available_language; } - return $available[$key]; } - foreach($available as $l) { - if ( $temp[0] == substr($l, 0, 2) ) { + foreach($available as $available_language) { + if (substr($preferred_language, 0, 2) === $available_language) { if (is_null($app)) { - self::$language = $l; + self::$language = $available_language; } - return $l; + return $available_language; } } } diff --git a/lib/private/l10n/ach.php b/lib/private/l10n/ach.php deleted file mode 100644 index 406ff5f5a26..00000000000 --- a/lib/private/l10n/ach.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/lib/private/l10n/af_ZA.php b/lib/private/l10n/af_ZA.php deleted file mode 100644 index d6bf5771e8d..00000000000 --- a/lib/private/l10n/af_ZA.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Hulp", -"Personal" => "Persoonlik", -"Settings" => "Instellings", -"Users" => "Gebruikers", -"Admin" => "Admin", -"web services under your control" => "webdienste onder jou beheer", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/ar.php b/lib/private/l10n/ar.php deleted file mode 100644 index f626dcdfda6..00000000000 --- a/lib/private/l10n/ar.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "المساعدة", -"Personal" => "شخصي", -"Settings" => "إعدادات", -"Users" => "المستخدمين", -"Admin" => "المدير", -"web services under your control" => "خدمات الشبكة تحت سيطرتك", -"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", -"Application is not enabled" => "التطبيق غير مفعّل", -"Authentication error" => "لم يتم التأكد من الشخصية بنجاح", -"Token expired. Please reload page." => "انتهت صلاحية الكلمة , يرجى اعادة تحميل الصفحة", -"Files" => "الملفات", -"Text" => "معلومات إضافية", -"Images" => "صور", -"%s enter the database username." => "%s ادخل اسم المستخدم الخاص بقاعدة البيانات.", -"%s enter the database name." => "%s ادخل اسم فاعدة البيانات", -"%s you may not use dots in the database name" => "%s لا يسمح لك باستخدام نقطه (.) في اسم قاعدة البيانات", -"MS SQL username and/or password not valid: %s" => "اسم المستخدم و/أو كلمة المرور لنظام MS SQL غير صحيح : %s", -"You need to enter either an existing account or the administrator." => "انت بحاجة لكتابة اسم مستخدم موجود أو حساب المدير.", -"MySQL username and/or password not valid" => "اسم المستخدم و/أو كلمة المرور لنظام MySQL غير صحيح", -"DB Error: \"%s\"" => "خطأ في قواعد البيانات : \"%s\"", -"Offending command was: \"%s\"" => "الأمر المخالف كان : \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "أسم المستخدم '%s'@'localhost' الخاص بـ MySQL موجود مسبقا", -"Drop this user from MySQL" => "احذف اسم المستخدم هذا من الـ MySQL", -"MySQL user '%s'@'%%' already exists" => "أسم المستخدم '%s'@'%%' الخاص بـ MySQL موجود مسبقا", -"Drop this user from MySQL." => "احذف اسم المستخدم هذا من الـ MySQL.", -"Oracle username and/or password not valid" => "اسم المستخدم و/أو كلمة المرور لنظام Oracle غير صحيح", -"Offending command was: \"%s\", name: %s, password: %s" => "الأمر المخالف كان : \"%s\", اسم المستخدم : %s, كلمة المرور: %s", -"PostgreSQL username and/or password not valid" => "اسم المستخدم / أو كلمة المرور الخاصة بـPostgreSQL غير صحيحة", -"Set an admin username." => "اعداد اسم مستخدم للمدير", -"Set an admin password." => "اعداد كلمة مرور للمدير", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "اعدادات خادمك غير صحيحة بشكل تسمح لك بمزامنة ملفاتك وذلك بسبب أن واجهة WebDAV تبدو معطلة", -"Please double check the <a href='%s'>installation guides</a>." => "الرجاء التحقق من <a href='%s'>دليل التنصيب</a>.", -"seconds ago" => "منذ ثواني", -"_%n minute ago_::_%n minutes ago_" => array("","","","","",""), -"_%n hour ago_::_%n hours ago_" => array("","","","","",""), -"today" => "اليوم", -"yesterday" => "يوم أمس", -"_%n day go_::_%n days ago_" => array("","","","","",""), -"last month" => "الشهر الماضي", -"_%n month ago_::_%n months ago_" => array("","","","","",""), -"last year" => "السنةالماضية", -"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/private/l10n/be.php b/lib/private/l10n/be.php deleted file mode 100644 index 1570411eb86..00000000000 --- a/lib/private/l10n/be.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("","","",""), -"_%n hour ago_::_%n hours ago_" => array("","","",""), -"_%n day go_::_%n days ago_" => array("","","",""), -"_%n month ago_::_%n months ago_" => array("","","","") -); -$PLURAL_FORMS = "nplurals=4; 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/private/l10n/bg_BG.php b/lib/private/l10n/bg_BG.php deleted file mode 100644 index b6cc949eb8a..00000000000 --- a/lib/private/l10n/bg_BG.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Помощ", -"Personal" => "Лични", -"Settings" => "Настройки", -"Users" => "Потребители", -"Admin" => "Админ", -"web services under your control" => "уеб услуги под Ваш контрол", -"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 архив.", -"Application is not enabled" => "Приложението не е включено.", -"Authentication error" => "Възникна проблем с идентификацията", -"Token expired. Please reload page." => "Ключът е изтекъл, моля презаредете страницата", -"Files" => "Файлове", -"Text" => "Текст", -"Images" => "Снимки", -"%s enter the database username." => "%s въведете потребителско име за базата с данни.", -"%s enter the database name." => "%s въведете име на базата с данни.", -"%s you may not use dots in the database name" => "%s, не можете да ползвате точки в името на базата от данни", -"MS SQL username and/or password not valid: %s" => "Невалидно MS SQL потребителско име и/или парола: %s", -"You need to enter either an existing account or the administrator." => "Необходимо е да влезете в всъществуващ акаунт или като администратора", -"MySQL username and/or password not valid" => "Невалидно MySQL потребителско име и/или парола", -"DB Error: \"%s\"" => "Грешка в базата от данни: \"%s\"", -"Offending command was: \"%s\"" => "Проблемната команда беше: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL потребителят '%s'@'localhost' вече съществува", -"Drop this user from MySQL" => "Изтриване на потребителя от MySQL", -"MySQL user '%s'@'%%' already exists" => "MySQL потребителят '%s'@'%%' вече съществува.", -"Drop this user from MySQL." => "Изтриване на потребителя от MySQL.", -"Oracle connection could not be established" => "Oracle връзка не можа да се осъществи", -"Oracle username and/or password not valid" => "Невалидно Oracle потребителско име и/или парола", -"Offending command was: \"%s\", name: %s, password: %s" => "Проблемната команда беше: \"%s\", име: %s, парола: %s", -"PostgreSQL username and/or password not valid" => "Невалидно PostgreSQL потребителско име и/или парола", -"Set an admin username." => "Въведете потребителско име за администратор.", -"Set an admin password." => "Въведете парола за администратор.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Вашият web сървър все още не е удачно настроен да позволява синхронизация на файлове, защото WebDAV интерфейсът изглежда не работи.", -"Please double check the <a href='%s'>installation guides</a>." => "Моля направете повторна справка с <a href='%s'>ръководството за инсталиране</a>.", -"seconds ago" => "преди секунди", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "днес", -"yesterday" => "вчера", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "последният месец", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "последната година", -"years ago" => "последните години", -"Could not find category \"%s\"" => "Невъзможно откриване на категорията \"%s\"" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/bn_BD.php b/lib/private/l10n/bn_BD.php deleted file mode 100644 index a42435a2a47..00000000000 --- a/lib/private/l10n/bn_BD.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "সহায়িকা", -"Personal" => "ব্যক্তিগত", -"Settings" => "নিয়ামকসমূহ", -"Users" => "ব্যবহারকারী", -"Admin" => "প্রশাসন", -"web services under your control" => "ওয়েব সার্ভিস আপনার হাতের মুঠোয়", -"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." => "নির্বাচিত ফাইলগুলো এতই বৃহৎ যে জিপ ফাইল তৈরী করা সম্ভব নয়।", -"Application is not enabled" => "অ্যাপ্লিকেসনটি সক্রিয় নয়", -"Authentication error" => "অনুমোদন ঘটিত সমস্যা", -"Token expired. Please reload page." => "টোকেন মেয়াদোত্তীর্ণ। দয়া করে পৃষ্ঠাটি পূনরায় লোড করুন।", -"Files" => "ফাইল", -"Text" => "টেক্সট", -"seconds ago" => "সেকেন্ড পূর্বে", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "আজ", -"yesterday" => "গতকাল", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "গত মাস", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "গত বছর", -"years ago" => "বছর পূর্বে" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/bs.php b/lib/private/l10n/bs.php deleted file mode 100644 index 3cb98906e62..00000000000 --- a/lib/private/l10n/bs.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("","",""), -"_%n hour ago_::_%n hours ago_" => array("","",""), -"_%n day go_::_%n days ago_" => array("","",""), -"_%n month ago_::_%n months ago_" => array("","","") -); -$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/private/l10n/ca.php b/lib/private/l10n/ca.php deleted file mode 100644 index a8769224705..00000000000 --- a/lib/private/l10n/ca.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "L'aplicació \"%s\" no es pot instal·lar perquè no és compatible amb aquesta versió d'ownCloud.", -"No app name specified" => "No heu especificat cap nom d'aplicació", -"Help" => "Ajuda", -"Personal" => "Personal", -"Settings" => "Configuració", -"Users" => "Usuaris", -"Admin" => "Administració", -"Failed to upgrade \"%s\"." => "Ha fallat l'actualització \"%s\".", -"Custom profile pictures don't work with encryption yet" => "Les imatges de perfil personals encara no funcionen amb encriptació", -"Unknown filetype" => "Tipus de fitxer desconegut", -"Invalid image" => "Imatge no vàlida", -"web services under your control" => "controleu els vostres serveis web", -"cannot open \"%s\"" => "no es pot obrir \"%s\"", -"ZIP download is turned off." => "La baixada en ZIP està desactivada.", -"Files need to be downloaded one by one." => "Els fitxers s'han de baixar d'un en un.", -"Back to Files" => "Torna a Fitxers", -"Selected files too large to generate zip file." => "Els fitxers seleccionats son massa grans per generar un fitxer zip.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Baixeu els fitxers en trossos petits, de forma separada, o pregunteu a l'administrador.", -"No source specified when installing app" => "No heu especificat la font en instal·lar l'aplicació", -"No href specified when installing app from http" => "No heu especificat href en instal·lar l'aplicació des de http", -"No path specified when installing app from local file" => "No heu seleccionat el camí en instal·lar una aplicació des d'un fitxer local", -"Archives of type %s are not supported" => "Els fitxers del tipus %s no són compatibles", -"Failed to open archive when installing app" => "Ha fallat l'obertura del fitxer en instal·lar l'aplicació", -"App does not provide an info.xml file" => "L'aplicació no proporciona un fitxer info.xml", -"App can't be installed because of not allowed code in the App" => "L'aplicació no es pot instal·lar perquè hi ha codi no autoritzat en l'aplicació", -"App can't be installed because it is not compatible with this version of ownCloud" => "L'aplicació no es pot instal·lar perquè no és compatible amb aquesta versió d'ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "L'aplicació no es pot instal·lar perquè conté l'etiqueta <shipped>vertader</shipped> que no es permet per aplicacions no enviades", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "L'aplicació no es pot instal·lar perquè la versió a info.xml/version no és la mateixa que la versió indicada des de la botiga d'aplicacions", -"App directory already exists" => "La carpeta de l'aplicació ja existeix", -"Can't create app folder. Please fix permissions. %s" => "No es pot crear la carpeta de l'aplicació. Arregleu els permisos. %s", -"Application is not enabled" => "L'aplicació no està habilitada", -"Authentication error" => "Error d'autenticació", -"Token expired. Please reload page." => "El testimoni ha expirat. Torneu a carregar la pàgina.", -"Files" => "Fitxers", -"Text" => "Text", -"Images" => "Imatges", -"%s enter the database username." => "%s escriviu el nom d'usuari de la base de dades.", -"%s enter the database name." => "%s escriviu el nom de la base de dades.", -"%s you may not use dots in the database name" => "%s no podeu usar punts en el nom de la base de dades", -"MS SQL username and/or password not valid: %s" => "Nom d'usuari i/o contrasenya MS SQL no vàlids: %s", -"You need to enter either an existing account or the administrator." => "Heu d'escriure un compte existent o el d'administrador.", -"MySQL username and/or password not valid" => "Nom d'usuari i/o contrasenya MySQL no vàlids", -"DB Error: \"%s\"" => "Error DB: \"%s\"", -"Offending command was: \"%s\"" => "L'ordre en conflicte és: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "L'usuari MySQL '%s'@'localhost' ja existeix.", -"Drop this user from MySQL" => "Elimina aquest usuari de MySQL", -"MySQL user '%s'@'%%' already exists" => "L'usuari MySQL '%s'@'%%' ja existeix", -"Drop this user from MySQL." => "Elimina aquest usuari de MySQL.", -"Oracle connection could not be established" => "No s'ha pogut establir la connexió Oracle", -"Oracle username and/or password not valid" => "Nom d'usuari i/o contrasenya Oracle no vàlids", -"Offending command was: \"%s\", name: %s, password: %s" => "L'ordre en conflicte és: \"%s\", nom: %s, contrasenya: %s", -"PostgreSQL username and/or password not valid" => "Nom d'usuari i/o contrasenya PostgreSQL no vàlids", -"Set an admin username." => "Establiu un nom d'usuari per l'administrador.", -"Set an admin password." => "Establiu una contrasenya per l'administrador.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "El servidor web no està configurat correctament per permetre la sincronització de fitxers perquè la interfície WebDAV sembla no funcionar correctament.", -"Please double check the <a href='%s'>installation guides</a>." => "Comproveu les <a href='%s'>guies d'instal·lació</a>.", -"seconds ago" => "segons enrere", -"_%n minute ago_::_%n minutes ago_" => array("fa %n minut","fa %n minuts"), -"_%n hour ago_::_%n hours ago_" => array("fa %n hora","fa %n hores"), -"today" => "avui", -"yesterday" => "ahir", -"_%n day go_::_%n days ago_" => array("fa %n dia","fa %n dies"), -"last month" => "el mes passat", -"_%n month ago_::_%n months ago_" => array("fa %n mes","fa %n mesos"), -"last year" => "l'any passat", -"years ago" => "anys enrere", -"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/private/l10n/cs_CZ.php b/lib/private/l10n/cs_CZ.php deleted file mode 100644 index ed31ae79529..00000000000 --- a/lib/private/l10n/cs_CZ.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Aplikace \"%s\" nemůže být nainstalována, protože není kompatibilní s touto verzí ownCloud.", -"No app name specified" => "Nebyl zadan název aplikace", -"Help" => "Nápověda", -"Personal" => "Osobní", -"Settings" => "Nastavení", -"Users" => "Uživatelé", -"Admin" => "Administrace", -"Failed to upgrade \"%s\"." => "Selhala aktualizace verze \"%s\".", -"Custom profile pictures don't work with encryption yet" => "Vlastní profilové obrázky zatím nefungují v kombinaci se šifrováním", -"Unknown filetype" => "Neznámý typ souboru", -"Invalid image" => "Chybný obrázek", -"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í 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.", -"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.", -"No source specified when installing app" => "Nebyl zadán zdroj při instalaci aplikace", -"No href specified when installing app from http" => "Nebyl zadán odkaz pro instalaci aplikace z HTTP", -"No path specified when installing app from local file" => "Nebyla zadána cesta pro instalaci aplikace z místního souboru", -"Archives of type %s are not supported" => "Archivy typu %s nejsou podporovány", -"Failed to open archive when installing app" => "Chyba při otevírání archivu během instalace aplikace", -"App does not provide an info.xml file" => "Aplikace neposkytuje soubor info.xml", -"App can't be installed because of not allowed code in the App" => "Aplikace nemůže být nainstalována, protože obsahuje nepovolený kód", -"App can't be installed because it is not compatible with this version of ownCloud" => "Aplikace nemůže být nainstalována, protože není kompatibilní s touto verzí ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Aplikace nemůže být nainstalována, protože obsahuje značku\n<shipped>\n\ntrue\n</shipped>\n\ncož není povoleno pro nedodávané aplikace", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Aplikace nemůže být nainstalována, protože verze uvedená v info.xml/version nesouhlasí s verzí oznámenou z úložiště aplikací.", -"App directory already exists" => "Adresář aplikace již existuje", -"Can't create app folder. Please fix permissions. %s" => "Nelze vytvořit složku aplikace. Opravte práva souborů. %s", -"Application is not enabled" => "Aplikace není povolena", -"Authentication error" => "Chyba ověření", -"Token expired. Please reload page." => "Token vypršel. Obnovte prosím stránku.", -"Files" => "Soubory", -"Text" => "Text", -"Images" => "Obrázky", -"%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 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" => "Zrušte tohoto uživatele z MySQL", -"MySQL user '%s'@'%%' already exists" => "Uživatel '%s'@'%%' již v MySQL existuje", -"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" => "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, 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 sekundami", -"_%n minute ago_::_%n minutes ago_" => array("před %n minutou","před %n minutami","před %n minutami"), -"_%n hour ago_::_%n hours ago_" => array("před %n hodinou","před %n hodinami","před %n hodinami"), -"today" => "dnes", -"yesterday" => "včera", -"_%n day go_::_%n days ago_" => array("před %n dnem","před %n dny","před %n dny"), -"last month" => "minulý měsíc", -"_%n month ago_::_%n months ago_" => array("před %n měsícem","před %n měsíci","před %n 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/private/l10n/cy_GB.php b/lib/private/l10n/cy_GB.php deleted file mode 100644 index 6973b51878f..00000000000 --- a/lib/private/l10n/cy_GB.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Cymorth", -"Personal" => "Personol", -"Settings" => "Gosodiadau", -"Users" => "Defnyddwyr", -"Admin" => "Gweinyddu", -"web services under your control" => "gwasanaethau gwe a reolir gennych", -"ZIP download is turned off." => "Mae llwytho ZIP wedi ei ddiffodd.", -"Files need to be downloaded one by one." => "Mae angen llwytho ffeiliau i lawr fesul un.", -"Back to Files" => "Nôl i Ffeiliau", -"Selected files too large to generate zip file." => "Mae'r ffeiliau ddewiswyd yn rhy fawr i gynhyrchu ffeil zip.", -"Application is not enabled" => "Nid yw'r pecyn wedi'i alluogi", -"Authentication error" => "Gwall dilysu", -"Token expired. Please reload page." => "Tocyn wedi dod i ben. Ail-lwythwch y dudalen.", -"Files" => "Ffeiliau", -"Text" => "Testun", -"Images" => "Delweddau", -"%s enter the database username." => "%s rhowch enw defnyddiwr y gronfa ddata.", -"%s enter the database name." => "%s rhowch enw'r gronfa ddata.", -"%s you may not use dots in the database name" => "%s does dim hawl defnyddio dot yn enw'r gronfa ddata", -"MS SQL username and/or password not valid: %s" => "Enw a/neu gyfrinair MS SQL annilys: %s", -"You need to enter either an existing account or the administrator." => "Rhaid i chi naill ai gyflwyno cyfrif presennol neu'r gweinyddwr.", -"MySQL username and/or password not valid" => "Enw a/neu gyfrinair MySQL annilys", -"DB Error: \"%s\"" => "Gwall DB: \"%s\"", -"Offending command was: \"%s\"" => "Y gorchymyn wnaeth beri tramgwydd oedd: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Defnyddiwr MySQL '%s'@'localhost' yn bodoli eisoes.", -"Drop this user from MySQL" => "Gollwng y defnyddiwr hwn o MySQL", -"MySQL user '%s'@'%%' already exists" => "Defnyddiwr MySQL '%s'@'%%' eisoes yn bodoli", -"Drop this user from MySQL." => "Gollwng y defnyddiwr hwn o MySQL.", -"Oracle username and/or password not valid" => "Enw a/neu gyfrinair Oracle annilys", -"Offending command was: \"%s\", name: %s, password: %s" => "Y gorchymyn wnaeth beri tramgwydd oedd: \"%s\", enw: %s, cyfrinair: %s", -"PostgreSQL username and/or password not valid" => "Enw a/neu gyfrinair PostgreSQL annilys", -"Set an admin username." => "Creu enw defnyddiwr i'r gweinyddwr.", -"Set an admin password." => "Gosod cyfrinair y gweinyddwr.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Nid yw eich gweinydd wedi'i gyflunio eto i ganiatáu cydweddu ffeiliau oherwydd bod y rhyngwyneb WebDAV wedi torri.", -"Please double check the <a href='%s'>installation guides</a>." => "Gwiriwch y <a href='%s'>canllawiau gosod</a> eto.", -"seconds ago" => "eiliad yn ôl", -"_%n minute ago_::_%n minutes ago_" => array("","","",""), -"_%n hour ago_::_%n hours ago_" => array("","","",""), -"today" => "heddiw", -"yesterday" => "ddoe", -"_%n day go_::_%n days ago_" => array("","","",""), -"last month" => "mis diwethaf", -"_%n month ago_::_%n months ago_" => array("","","",""), -"last year" => "y llynedd", -"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/private/l10n/da.php b/lib/private/l10n/da.php deleted file mode 100644 index 05a43f42ed9..00000000000 --- a/lib/private/l10n/da.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "App'en \"%s\" kan ikke blive installeret, da den ikke er kompatibel med denne version af ownCloud.", -"No app name specified" => "Intet app-navn angivet", -"Help" => "Hjælp", -"Personal" => "Personligt", -"Settings" => "Indstillinger", -"Users" => "Brugere", -"Admin" => "Admin", -"Failed to upgrade \"%s\"." => "Upgradering af \"%s\" fejlede", -"Custom profile pictures don't work with encryption yet" => "Personligt profilbillede virker endnu ikke sammen med kryptering", -"Unknown filetype" => "Ukendt filtype", -"Invalid image" => "Ugyldigt billede", -"web services under your control" => "Webtjenester under din kontrol", -"cannot open \"%s\"" => "Kan ikke åbne \"%s\"", -"ZIP download is turned off." => "ZIP-download er slået fra.", -"Files need to be downloaded one by one." => "Filer skal downloades en for en.", -"Back to Files" => "Tilbage til Filer", -"Selected files too large to generate zip file." => "De markerede filer er for store til at generere en ZIP-fil.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Download filerne i små bider, seperat, eller kontakt venligst din administrator.", -"No source specified when installing app" => "Ingen kilde angivet under installation af app", -"No href specified when installing app from http" => "Ingen href angivet under installation af app via http", -"No path specified when installing app from local file" => "Ingen sti angivet under installation af app fra lokal fil", -"Archives of type %s are not supported" => "Arkiver af type %s understøttes ikke", -"Failed to open archive when installing app" => "Kunne ikke åbne arkiv under installation af appen", -"App does not provide an info.xml file" => "Der følger ingen info.xml-fil med appen", -"App can't be installed because of not allowed code in the App" => "Appen kan ikke installeres, da den indeholder ikke-tilladt kode", -"App can't be installed because it is not compatible with this version of ownCloud" => "Appen kan ikke installeres, da den ikke er kompatibel med denne version af ownCloud.", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Appen kan ikke installeres, da den indeholder taget\n<shipped>\n\ntrue\n</shipped>\n\nhvilket ikke er tilladt for ikke-medfølgende apps", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "App kan ikke installeres, da versionen i info.xml/version ikke er den samme som versionen rapporteret fra app-storen", -"App directory already exists" => "App-mappe findes allerede", -"Can't create app folder. Please fix permissions. %s" => "Kan ikke oprette app-mappe. Ret tilladelser. %s", -"Application is not enabled" => "Programmet er ikke aktiveret", -"Authentication error" => "Adgangsfejl", -"Token expired. Please reload page." => "Adgang er udløbet. Genindlæs siden.", -"Files" => "Filer", -"Text" => "SMS", -"Images" => "Billeder", -"%s enter the database username." => "%s indtast database brugernavnet.", -"%s enter the database name." => "%s indtast database navnet.", -"%s you may not use dots in the database name" => "%s du må ikke bruge punktummer i databasenavnet.", -"MS SQL username and/or password not valid: %s" => "MS SQL brugernavn og/eller adgangskode ikke er gyldigt: %s", -"You need to enter either an existing account or the administrator." => "Du bliver nødt til at indtaste en eksisterende bruger eller en administrator.", -"MySQL username and/or password not valid" => "MySQL brugernavn og/eller kodeord er ikke gyldigt.", -"DB Error: \"%s\"" => "Databasefejl: \"%s\"", -"Offending command was: \"%s\"" => "Fejlende kommando var: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL brugeren '%s'@'localhost' eksisterer allerede.", -"Drop this user from MySQL" => "Slet denne bruger fra MySQL", -"MySQL user '%s'@'%%' already exists" => "MySQL brugeren '%s'@'%%' eksisterer allerede.", -"Drop this user from MySQL." => "Slet denne bruger fra MySQL", -"Oracle connection could not be established" => "Oracle forbindelsen kunne ikke etableres", -"Oracle username and/or password not valid" => "Oracle brugernavn og/eller kodeord er ikke gyldigt.", -"Offending command was: \"%s\", name: %s, password: %s" => "Fejlende kommando var: \"%s\", navn: %s, password: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL brugernavn og/eller kodeord er ikke gyldigt.", -"Set an admin username." => "Angiv et admin brugernavn.", -"Set an admin password." => "Angiv et admin kodeord.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Din webserver er endnu ikke sat op til at tillade fil synkronisering fordi WebDAV grænsefladen virker ødelagt.", -"Please double check the <a href='%s'>installation guides</a>." => "Dobbelttjek venligst <a href='%s'>installations vejledningerne</a>.", -"seconds ago" => "sekunder siden", -"_%n minute ago_::_%n minutes ago_" => array("%n minut siden","%n minutter siden"), -"_%n hour ago_::_%n hours ago_" => array("%n time siden","%n timer siden"), -"today" => "i dag", -"yesterday" => "i går", -"_%n day go_::_%n days ago_" => array("%n dag siden","%n dage siden"), -"last month" => "sidste måned", -"_%n month ago_::_%n months ago_" => array("%n måned siden","%n måneder siden"), -"last year" => "sidste år", -"years ago" => "år siden", -"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/private/l10n/de.php b/lib/private/l10n/de.php deleted file mode 100644 index 87e7a67b47b..00000000000 --- a/lib/private/l10n/de.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Applikation \"%s\" kann nicht installiert werden, da sie mit dieser ownCloud Version nicht kompatibel ist.", -"No app name specified" => "Es wurde kein Applikation-Name angegeben", -"Help" => "Hilfe", -"Personal" => "Persönlich", -"Settings" => "Einstellungen", -"Users" => "Benutzer", -"Admin" => "Administration", -"Failed to upgrade \"%s\"." => "Konnte \"%s\" nicht aktualisieren.", -"Custom profile pictures don't work with encryption yet" => "Individuelle Profilbilder werden noch nicht von der Verschlüsselung unterstützt", -"Unknown filetype" => "Unbekannter Dateityp", -"Invalid image" => "Ungültiges Bild", -"web services under your control" => "Web-Services unter Deiner 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 groß, um eine ZIP-Datei zu erstellen.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Lade die Dateien in kleineren, separaten, Stücken herunter oder bitte deinen Administrator.", -"No source specified when installing app" => "Für die Installation der Applikation wurde keine Quelle angegeben", -"No href specified when installing app from http" => "Der Link (href) wurde nicht angegeben um die Applikation per http zu installieren", -"No path specified when installing app from local file" => "Bei der Installation der Applikation aus einer lokalen Datei wurde kein Pfad angegeben", -"Archives of type %s are not supported" => "Archive vom Typ %s werden nicht unterstützt", -"Failed to open archive when installing app" => "Das Archiv konnte bei der Installation der Applikation nicht geöffnet werden", -"App does not provide an info.xml file" => "Die Applikation enthält keine info,xml Datei", -"App can't be installed because of not allowed code in the App" => "Die Applikation kann auf Grund von unerlaubten Code nicht installiert werden", -"App can't be installed because it is not compatible with this version of ownCloud" => "Die Anwendung konnte nicht installiert werden, weil Sie nicht mit dieser Version von ownCloud kompatibel ist.", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Die Applikation konnte nicht installiert werden, da diese das <shipped>true</shipped> Tag beinhaltet und dieses, bei nicht mitausgelieferten Applikationen, nicht erlaubt ist ist", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Die Applikation konnte nicht installiert werden, da die Version in der info.xml nicht die gleiche Version wie im App-Store ist", -"App directory already exists" => "Das Applikationsverzeichnis existiert bereits", -"Can't create app folder. Please fix permissions. %s" => "Es kann kein Applikationsordner erstellt werden. Bitte passen sie die Berechtigungen an. %s", -"Application is not enabled" => "Die Anwendung ist nicht aktiviert", -"Authentication error" => "Fehler bei der Anmeldung", -"Token expired. Please reload page." => "Token abgelaufen. Bitte lade die Seite neu.", -"Files" => "Dateien", -"Text" => "Text", -"Images" => "Bilder", -"%s enter the database username." => "%s gib den Datenbank-Benutzernamen an.", -"%s enter the database name." => "%s gib 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 Password ungültig: %s", -"You need to enter either an existing account or the administrator." => "Du musst 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 von 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" => "Es konnte keine Verbindung zur Oracle-Datenbank hergestellt 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." => "Dein Web-Server ist noch nicht für Datei-Synchronisation bereit, weil die WebDAV-Schnittstelle vermutlich defekt ist.", -"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfe die <a href='%s'>Installationsanleitungen</a>.", -"seconds ago" => "Gerade eben", -"_%n minute ago_::_%n minutes ago_" => array("","Vor %n Minuten"), -"_%n hour ago_::_%n hours ago_" => array("","Vor %n Stunden"), -"today" => "Heute", -"yesterday" => "Gestern", -"_%n day go_::_%n days ago_" => array("","Vor %n Tagen"), -"last month" => "Letzten Monat", -"_%n month ago_::_%n months ago_" => array("","Vor %n 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/private/l10n/de_AT.php b/lib/private/l10n/de_AT.php deleted file mode 100644 index 15f78e0bce6..00000000000 --- a/lib/private/l10n/de_AT.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/de_CH.php b/lib/private/l10n/de_CH.php deleted file mode 100644 index 33f3446a693..00000000000 --- a/lib/private/l10n/de_CH.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Anwendung \"%s\" kann nicht installiert werden, da sie mit dieser Version von ownCloud nicht kompatibel ist.", -"No app name specified" => "Kein App-Name spezifiziert", -"Help" => "Hilfe", -"Personal" => "Persönlich", -"Settings" => "Einstellungen", -"Users" => "Benutzer", -"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.", -"App can't be installed because of not allowed code in the App" => "Anwendung kann wegen nicht erlaubten Codes nicht installiert werden", -"App directory already exists" => "Anwendungsverzeichnis existiert bereits", -"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", -"_%n minute ago_::_%n minutes ago_" => array("","Vor %n Minuten"), -"_%n hour ago_::_%n hours ago_" => array("","Vor %n Stunden"), -"today" => "Heute", -"yesterday" => "Gestern", -"_%n day go_::_%n days ago_" => array("","Vor %n Tagen"), -"last month" => "Letzten Monat", -"_%n month ago_::_%n months ago_" => array("","Vor %n 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/private/l10n/de_DE.php b/lib/private/l10n/de_DE.php deleted file mode 100644 index 09be0eea22d..00000000000 --- a/lib/private/l10n/de_DE.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Applikation \"%s\" kann nicht installiert werden, da sie mit dieser ownCloud Version nicht kompatibel ist.", -"No app name specified" => "Es wurde kein Applikation-Name angegeben", -"Help" => "Hilfe", -"Personal" => "Persönlich", -"Settings" => "Einstellungen", -"Users" => "Benutzer", -"Admin" => "Administrator", -"Failed to upgrade \"%s\"." => "Konnte \"%s\" nicht aktualisieren.", -"Custom profile pictures don't work with encryption yet" => "Individuelle Profilbilder werden noch nicht von der Verschlüsselung unterstützt", -"Unknown filetype" => "Unbekannter Dateityp", -"Invalid image" => "Ungültiges Bild", -"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 groß, 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.", -"No source specified when installing app" => "Für die Installation der Applikation wurde keine Quelle angegeben", -"No href specified when installing app from http" => "Der Link (href) wurde nicht angegeben um die Applikation per http zu installieren", -"No path specified when installing app from local file" => "Bei der Installation der Applikation aus einer lokalen Datei wurde kein Pfad angegeben", -"Archives of type %s are not supported" => "Archive des Typs %s werden nicht unterstützt.", -"Failed to open archive when installing app" => "Das Archiv konnte bei der Installation der Applikation nicht geöffnet werden", -"App does not provide an info.xml file" => "Die Applikation enthält keine info,xml Datei", -"App can't be installed because of not allowed code in the App" => "Die Applikation kann auf Grund von unerlaubten Code nicht installiert werden", -"App can't be installed because it is not compatible with this version of ownCloud" => "Die Anwendung konnte nicht installiert werden, weil Sie nicht mit dieser Version von ownCloud kompatibel ist.", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Die Applikation konnte nicht installiert werden, da diese das <shipped>true</shipped> Tag beinhaltet und dieses, bei nicht mitausgelieferten Applikationen, nicht erlaubt ist ist", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Die Applikation konnte nicht installiert werden, da die Version in der info.xml nicht die gleiche Version wie im App-Store ist", -"App directory already exists" => "Der Ordner für die Anwendung existiert bereits.", -"Can't create app folder. Please fix permissions. %s" => "Der Ordner für die Anwendung konnte nicht angelegt werden. Bitte überprüfen Sie die Ordner- und Dateirechte und passen Sie diese entsprechend an. %s", -"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", -"_%n minute ago_::_%n minutes ago_" => array("Vor %n Minute","Vor %n Minuten"), -"_%n hour ago_::_%n hours ago_" => array("Vor %n Stunde","Vor %n Stunden"), -"today" => "Heute", -"yesterday" => "Gestern", -"_%n day go_::_%n days ago_" => array("Vor %n Tag","Vor %n Tagen"), -"last month" => "Letzten Monat", -"_%n month ago_::_%n months ago_" => array("Vor %n Monat","Vor %n 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/private/l10n/el.php b/lib/private/l10n/el.php deleted file mode 100644 index dcbf82d4a4b..00000000000 --- a/lib/private/l10n/el.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Βοήθεια", -"Personal" => "Προσωπικά", -"Settings" => "Ρυθμίσεις", -"Users" => "Χρήστες", -"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." => "Λήψη των αρχείων σε μικρότερα κομμάτια, χωριστά ή ρωτήστε τον διαχειριστή σας.", -"Application is not enabled" => "Δεν ενεργοποιήθηκε η εφαρμογή", -"Authentication error" => "Σφάλμα πιστοποίησης", -"Token expired. Please reload page." => "Το αναγνωριστικό έληξε. Παρακαλώ φορτώστε ξανά την σελίδα.", -"Files" => "Αρχεία", -"Text" => "Κείμενο", -"Images" => "Εικόνες", -"%s enter the database username." => "%s εισάγετε το όνομα χρήστη της βάσης δεδομένων.", -"%s enter the database name." => "%s εισάγετε το όνομα της βάσης δεδομένων.", -"%s you may not use dots in the database name" => "%s μάλλον δεν χρησιμοποιείτε τελείες στο όνομα της βάσης δεδομένων", -"MS SQL username and/or password not valid: %s" => "Το όνομα χρήστη και/ή ο κωδικός της MS SQL δεν είναι έγκυρα: %s", -"You need to enter either an existing account or the administrator." => "Χρειάζεται να εισάγετε είτε έναν υπάρχον λογαριασμό ή του διαχειριστή.", -"MySQL username and/or password not valid" => "Μη έγκυρος χρήστης και/ή συνθηματικό της MySQL", -"DB Error: \"%s\"" => "Σφάλμα Βάσης Δεδομένων: \"%s\"", -"Offending command was: \"%s\"" => "Η εντολη παραβατικοτητας ηταν: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Υπάρχει ήδη ο χρήστης '%s'@'localhost' της MySQL.", -"Drop this user from MySQL" => "Απόρριψη αυτού του χρήστη από την MySQL", -"MySQL user '%s'@'%%' already exists" => "Ο χρήστης '%s'@'%%' της MySQL υπάρχει ήδη", -"Drop this user from MySQL." => "Απόρριψη αυτού του χρήστη από την MySQL", -"Oracle connection could not be established" => "Αδυναμία σύνδεσης Oracle", -"Oracle username and/or password not valid" => "Μη έγκυρος χρήστης και/ή συνθηματικό της Oracle", -"Offending command was: \"%s\", name: %s, password: %s" => "Η εντολη παραβατικοτητας ηταν: \"%s\", ονομα: %s, κωδικος: %s", -"PostgreSQL username and/or password not valid" => "Μη έγκυρος χρήστης και/ή συνθηματικό της PostgreSQL", -"Set an admin username." => "Εισάγετε όνομα χρήστη διαχειριστή.", -"Set an admin password." => "Εισάγετε συνθηματικό διαχειριστή.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Ο διακομιστής σας δεν έχει ρυθμιστεί κατάλληλα ώστε να επιτρέπει τον συγχρονισμό αρχείων γιατί η διεπαφή WebDAV πιθανόν να είναι κατεστραμμένη.", -"Please double check the <a href='%s'>installation guides</a>." => "Ελέγξτε ξανά τις <a href='%s'>οδηγίες εγκατάστασης</a>.", -"seconds ago" => "δευτερόλεπτα πριν", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "σήμερα", -"yesterday" => "χτες", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "τελευταίο μήνα", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "τελευταίο χρόνο", -"years ago" => "χρόνια πριν", -"Caused by:" => "Προκλήθηκε από:", -"Could not find category \"%s\"" => "Αδυναμία εύρεσης κατηγορίας \"%s\"" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/en@pirate.php b/lib/private/l10n/en@pirate.php deleted file mode 100644 index a8175b1400f..00000000000 --- a/lib/private/l10n/en@pirate.php +++ /dev/null @@ -1,9 +0,0 @@ -<?php -$TRANSLATIONS = array( -"web services under your control" => "web services under your control", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/en_GB.php b/lib/private/l10n/en_GB.php deleted file mode 100644 index d02f553eda8..00000000000 --- a/lib/private/l10n/en_GB.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "App \"%s\" can't be installed because it is not compatible with this version of ownCloud.", -"No app name specified" => "No app name specified", -"Help" => "Help", -"Personal" => "Personal", -"Settings" => "Settings", -"Users" => "Users", -"Admin" => "Admin", -"Failed to upgrade \"%s\"." => "Failed to upgrade \"%s\".", -"Custom profile pictures don't work with encryption yet" => "Custom profile pictures don't work with encryption yet", -"Unknown filetype" => "Unknown filetype", -"Invalid image" => "Invalid image", -"web services under your control" => "web services under your control", -"cannot open \"%s\"" => "cannot open \"%s\"", -"ZIP download is turned off." => "ZIP download is turned off.", -"Files need to be downloaded one by one." => "Files need to be downloaded one by one.", -"Back to Files" => "Back to Files", -"Selected files too large to generate zip file." => "Selected files too large to generate zip file.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Download the files in smaller chunks, seperately or kindly ask your administrator.", -"No source specified when installing app" => "No source specified when installing app", -"No href specified when installing app from http" => "No href specified when installing app from http", -"No path specified when installing app from local file" => "No path specified when installing app from local file", -"Archives of type %s are not supported" => "Archives of type %s are not supported", -"Failed to open archive when installing app" => "Failed to open archive when installing app", -"App does not provide an info.xml file" => "App does not provide an info.xml file", -"App can't be installed because of not allowed code in the App" => "App can't be installed because of unallowed code in the App", -"App can't be installed because it is not compatible with this version of ownCloud" => "App can't be installed because it is not compatible with this version of ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "App can't be installed because the version in info.xml/version is not the same as the version reported from the app store", -"App directory already exists" => "App directory already exists", -"Can't create app folder. Please fix permissions. %s" => "Can't create app folder. Please fix permissions. %s", -"Application is not enabled" => "Application is not enabled", -"Authentication error" => "Authentication error", -"Token expired. Please reload page." => "Token expired. Please reload page.", -"Files" => "Files", -"Text" => "Text", -"Images" => "Images", -"%s enter the database username." => "%s enter the database username.", -"%s enter the database name." => "%s enter the database name.", -"%s you may not use dots in the database name" => "%s you may not use dots in the database name", -"MS SQL username and/or password not valid: %s" => "MS SQL username and/or password not valid: %s", -"You need to enter either an existing account or the administrator." => "You need to enter either an existing account or the administrator.", -"MySQL username and/or password not valid" => "MySQL username and/or password not valid", -"DB Error: \"%s\"" => "DB Error: \"%s\"", -"Offending command was: \"%s\"" => "Offending command was: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL user '%s'@'localhost' exists already.", -"Drop this user from MySQL" => "Drop this user from MySQL", -"MySQL user '%s'@'%%' already exists" => "MySQL user '%s'@'%%' already exists", -"Drop this user from MySQL." => "Drop this user from MySQL.", -"Oracle connection could not be established" => "Oracle connection could not be established", -"Oracle username and/or password not valid" => "Oracle username and/or password not valid", -"Offending command was: \"%s\", name: %s, password: %s" => "Offending command was: \"%s\", name: %s, password: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL username and/or password not valid", -"Set an admin username." => "Set an admin username.", -"Set an admin password." => "Set an admin password.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Your web server is not yet properly setup to allow files synchronisation because the WebDAV interface seems to be broken.", -"Please double check the <a href='%s'>installation guides</a>." => "Please double check the <a href='%s'>installation guides</a>.", -"seconds ago" => "seconds ago", -"_%n minute ago_::_%n minutes ago_" => array("%n minute ago","%n minutes ago"), -"_%n hour ago_::_%n hours ago_" => array("%n hour ago","%n hours ago"), -"today" => "today", -"yesterday" => "yesterday", -"_%n day go_::_%n days ago_" => array("%n day go","%n days ago"), -"last month" => "last month", -"_%n month ago_::_%n months ago_" => array("%n month ago","%n months ago"), -"last year" => "last year", -"years ago" => "years ago", -"Caused by:" => "Caused by:", -"Could not find category \"%s\"" => "Could not find category \"%s\"" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/eo.php b/lib/private/l10n/eo.php deleted file mode 100644 index 5311dd6eb15..00000000000 --- a/lib/private/l10n/eo.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Helpo", -"Personal" => "Persona", -"Settings" => "Agordo", -"Users" => "Uzantoj", -"Admin" => "Administranto", -"web services under your control" => "TTT-servoj regataj de vi", -"ZIP download is turned off." => "ZIP-elŝuto estas malkapabligita.", -"Files need to be downloaded one by one." => "Dosieroj devas elŝutiĝi unuope.", -"Back to Files" => "Reen al la dosieroj", -"Selected files too large to generate zip file." => "La elektitaj dosieroj tro grandas por genero de ZIP-dosiero.", -"Application is not enabled" => "La aplikaĵo ne estas kapabligita", -"Authentication error" => "Aŭtentiga eraro", -"Token expired. Please reload page." => "Ĵetono eksvalidiĝis. Bonvolu reŝargi la paĝon.", -"Files" => "Dosieroj", -"Text" => "Teksto", -"Images" => "Bildoj", -"%s enter the database username." => "%s enigu la uzantonomon de la datumbazo.", -"%s enter the database name." => "%s enigu la nomon de la datumbazo.", -"%s you may not use dots in the database name" => "%s vi ne povas uzi punktojn en la nomo de la datumbazo", -"MS SQL username and/or password not valid: %s" => "La uzantonomo de MS SQL aŭ la pasvorto ne validas: %s", -"MySQL username and/or password not valid" => "La uzantonomo de MySQL aŭ la pasvorto ne validas", -"DB Error: \"%s\"" => "Datumbaza eraro: “%s”", -"MySQL user '%s'@'localhost' exists already." => "La uzanto de MySQL “%s”@“localhost” jam ekzistas.", -"Drop this user from MySQL" => "Forigi ĉi tiun uzanton el MySQL", -"MySQL user '%s'@'%%' already exists" => "La uzanto de MySQL “%s”@“%%” jam ekzistas", -"Drop this user from MySQL." => "Forigi ĉi tiun uzanton el MySQL.", -"Oracle connection could not be established" => "Konekto al Oracle ne povas stariĝi", -"Oracle username and/or password not valid" => "La uzantonomo de Oracle aŭ la pasvorto ne validas", -"PostgreSQL username and/or password not valid" => "La uzantonomo de PostgreSQL aŭ la pasvorto ne validas", -"Set an admin username." => "Starigi administran uzantonomon.", -"Set an admin password." => "Starigi administran pasvorton.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Via TTT-servilo ankoraŭ ne ĝuste agordiĝis por permesi sinkronigi dosierojn ĉar la WebDAV-interfaco ŝajnas rompita.", -"Please double check the <a href='%s'>installation guides</a>." => "Bonvolu duoble kontroli la <a href='%s'>gvidilon por instalo</a>.", -"seconds ago" => "sekundoj antaŭe", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "hodiaŭ", -"yesterday" => "hieraŭ", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "lastamonate", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "lastajare", -"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/private/l10n/es.php b/lib/private/l10n/es.php deleted file mode 100644 index 047d5d955bb..00000000000 --- a/lib/private/l10n/es.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "La aplicación \"%s\" no puede ser instalada porque no es compatible con esta versión de ownCloud", -"No app name specified" => "No se ha especificado nombre de la aplicación", -"Help" => "Ayuda", -"Personal" => "Personal", -"Settings" => "Ajustes", -"Users" => "Usuarios", -"Admin" => "Administración", -"Failed to upgrade \"%s\"." => "Falló la actualización \"%s\".", -"web services under your control" => "Servicios web bajo su control", -"cannot open \"%s\"" => "No se puede abrir \"%s\"", -"ZIP download is turned off." => "La descarga en ZIP está desactivada.", -"Files need to be downloaded one by one." => "Los archivos deben ser descargados uno por uno.", -"Back to Files" => "Volver a Archivos", -"Selected files too large to generate zip file." => "Los archivos seleccionados son demasiado grandes para generar el archivo zip.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Descargue los archivos en trozos más pequeños, por separado o solicítelos amablemente su administrador.", -"No source specified when installing app" => "No se ha especificado origen cuando se ha instalado la aplicación", -"No href specified when installing app from http" => "No href especificado cuando se ha instalado la aplicación", -"No path specified when installing app from local file" => "Sin path especificado cuando se ha instalado la aplicación desde el fichero local", -"Archives of type %s are not supported" => "Ficheros de tipo %s no son soportados", -"Failed to open archive when installing app" => "Fallo de apertura de fichero mientras se instala la aplicación", -"App does not provide an info.xml file" => "La aplicación no suministra un fichero info.xml", -"App can't be installed because of not allowed code in the App" => "La aplicación no puede ser instalada por tener código no autorizado en la aplicación", -"App can't be installed because it is not compatible with this version of ownCloud" => "La aplicación no se puede instalar porque no es compatible con esta versión de ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "La aplicación no se puede instalar porque contiene la etiqueta\n<shipped>\ntrue\n</shipped>\nque no está permitida para aplicaciones no distribuidas", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "La aplicación no puede ser instalada por que la versión en info.xml/version no es la misma que la establecida en la app store", -"App directory already exists" => "El directorio de la aplicación ya existe", -"Can't create app folder. Please fix permissions. %s" => "No se puede crear la carpeta de la aplicación. Corrija los permisos. %s", -"Application is not enabled" => "La aplicación no está habilitada", -"Authentication error" => "Error de autenticación", -"Token expired. Please reload page." => "Token expirado. Por favor, recarga la página.", -"Files" => "Archivos", -"Text" => "Texto", -"Images" => "Imágenes", -"%s enter the database username." => "%s ingresar el usuario de la base de datos.", -"%s enter the database name." => "%s ingresar el nombre de la base de datos", -"%s you may not use dots in the database name" => "%s puede utilizar puntos en el nombre de la base de datos", -"MS SQL username and/or password not valid: %s" => "Usuario y/o contraseña de MS SQL no válidos: %s", -"You need to enter either an existing account or the administrator." => "Tiene que ingresar una cuenta existente o la del administrador.", -"MySQL username and/or password not valid" => "Usuario y/o contraseña de MySQL no válidos", -"DB Error: \"%s\"" => "Error BD: \"%s\"", -"Offending command was: \"%s\"" => "Comando infractor: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Usuario MySQL '%s'@'localhost' ya existe.", -"Drop this user from MySQL" => "Eliminar este usuario de MySQL", -"MySQL user '%s'@'%%' already exists" => "Usuario MySQL '%s'@'%%' ya existe", -"Drop this user from MySQL." => "Eliminar este usuario de MySQL.", -"Oracle connection could not be established" => "No se pudo establecer la conexión a Oracle", -"Oracle username and/or password not valid" => "Usuario y/o contraseña de Oracle no válidos", -"Offending command was: \"%s\", name: %s, password: %s" => "Comando infractor: \"%s\", nombre: %s, contraseña: %s", -"PostgreSQL username and/or password not valid" => "Usuario y/o contraseña de PostgreSQL no válidos", -"Set an admin username." => "Configurar un nombre de usuario del administrador", -"Set an admin password." => "Configurar la contraseña del administrador.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Su servidor web aún no está configurado adecuadamente para permitir sincronización de archivos ya que la interfaz WebDAV parece no estar funcionando.", -"Please double check the <a href='%s'>installation guides</a>." => "Por favor, vuelva a comprobar las <a href='%s'>guías de instalación</a>.", -"seconds ago" => "hace segundos", -"_%n minute ago_::_%n minutes ago_" => array("Hace %n minuto","Hace %n minutos"), -"_%n hour ago_::_%n hours ago_" => array("Hace %n hora","Hace %n horas"), -"today" => "hoy", -"yesterday" => "ayer", -"_%n day go_::_%n days ago_" => array("Hace %n día","Hace %n días"), -"last month" => "mes pasado", -"_%n month ago_::_%n months ago_" => array("Hace %n mes","Hace %n meses"), -"last year" => "año pasado", -"years ago" => "hace años", -"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/private/l10n/es_AR.php b/lib/private/l10n/es_AR.php deleted file mode 100644 index f637eb403ed..00000000000 --- a/lib/private/l10n/es_AR.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "La app \"%s\" no puede ser instalada porque no es compatible con esta versión de ownCloud", -"No app name specified" => "No fue especificado el nombre de la app", -"Help" => "Ayuda", -"Personal" => "Personal", -"Settings" => "Configuración", -"Users" => "Usuarios", -"Admin" => "Administración", -"Failed to upgrade \"%s\"." => "No se pudo actualizar \"%s\".", -"web services under your control" => "servicios web sobre los que tenés control", -"cannot open \"%s\"" => "no se puede abrir \"%s\"", -"ZIP download is turned off." => "La descarga en ZIP está desactivada.", -"Files need to be downloaded one by one." => "Los archivos deben ser descargados de a uno.", -"Back to Files" => "Volver a Archivos", -"Selected files too large to generate zip file." => "Los archivos seleccionados son demasiado grandes para generar el archivo zip.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Descargá los archivos en partes más chicas, de forma separada, o pedíselos al administrador", -"No source specified when installing app" => "No se especificó el origen al instalar la app", -"No href specified when installing app from http" => "No se especificó href al instalar la app", -"No path specified when installing app from local file" => "No se especificó PATH al instalar la app desde el archivo local", -"Archives of type %s are not supported" => "No hay soporte para archivos de tipo %s", -"Failed to open archive when installing app" => "Error al abrir archivo mientras se instalaba la app", -"App does not provide an info.xml file" => "La app no suministra un archivo info.xml", -"App can't be installed because of not allowed code in the App" => "No puede ser instalada la app por tener código no autorizado", -"App can't be installed because it is not compatible with this version of ownCloud" => "No se puede instalar la app porque no es compatible con esta versión de ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "La app no se puede instalar porque contiene la etiqueta <shipped>true</shipped> que no está permitida para apps no distribuidas", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "La app no puede ser instalada porque la versión en info.xml/version no es la misma que la establecida en el app store", -"App directory already exists" => "El directorio de la app ya existe", -"Can't create app folder. Please fix permissions. %s" => "No se puede crear el directorio para la app. Corregí los permisos. %s", -"Application is not enabled" => "La aplicación no está habilitada", -"Authentication error" => "Error al autenticar", -"Token expired. Please reload page." => "Token expirado. Por favor, recargá la página.", -"Files" => "Archivos", -"Text" => "Texto", -"Images" => "Imágenes", -"%s enter the database username." => "%s Entrá el usuario de la base de datos", -"%s enter the database name." => "%s Entrá el nombre de la base de datos.", -"%s you may not use dots in the database name" => "%s no podés usar puntos en el nombre de la base de datos", -"MS SQL username and/or password not valid: %s" => "Nombre de usuario y contraseña de MS SQL no son válidas: %s", -"You need to enter either an existing account or the administrator." => "Tenés que ingresar una cuenta existente o el administrador.", -"MySQL username and/or password not valid" => "Usuario y/o contraseña MySQL no válido", -"DB Error: \"%s\"" => "Error DB: \"%s\"", -"Offending command was: \"%s\"" => "El comando no comprendido es: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Usuario MySQL '%s'@'localhost' ya existe.", -"Drop this user from MySQL" => "Borrar este usuario de MySQL", -"MySQL user '%s'@'%%' already exists" => "Usuario MySQL '%s'@'%%' ya existe", -"Drop this user from MySQL." => "Borrar este usuario de MySQL", -"Oracle connection could not be established" => "No fue posible establecer la conexión a Oracle", -"Oracle username and/or password not valid" => "El nombre de usuario y/o contraseña no son válidos", -"Offending command was: \"%s\", name: %s, password: %s" => "El comando no comprendido es: \"%s\", nombre: \"%s\", contraseña: \"%s\"", -"PostgreSQL username and/or password not valid" => "Nombre de usuario o contraseña PostgradeSQL inválido.", -"Set an admin username." => "Configurar un nombre de administrador.", -"Set an admin password." => "Configurar una contraseña de administrador.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Tu servidor web no está configurado todavía para permitir sincronización de archivos porque la interfaz WebDAV parece no funcionar.", -"Please double check the <a href='%s'>installation guides</a>." => "Por favor, comprobá nuevamente la <a href='%s'>guía de instalación</a>.", -"seconds ago" => "segundos atrás", -"_%n minute ago_::_%n minutes ago_" => array("Hace %n minuto","Hace %n minutos"), -"_%n hour ago_::_%n hours ago_" => array("Hace %n hora","Hace %n horas"), -"today" => "hoy", -"yesterday" => "ayer", -"_%n day go_::_%n days ago_" => array("Hace %n día","Hace %n días"), -"last month" => "el mes pasado", -"_%n month ago_::_%n months ago_" => array("Hace %n mes","Hace %n meses"), -"last year" => "el año pasado", -"years ago" => "años atrás", -"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/private/l10n/es_MX.php b/lib/private/l10n/es_MX.php deleted file mode 100644 index 15f78e0bce6..00000000000 --- a/lib/private/l10n/es_MX.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/et_EE.php b/lib/private/l10n/et_EE.php deleted file mode 100644 index 85dfaeb52d5..00000000000 --- a/lib/private/l10n/et_EE.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Rakendit \"%s\" ei saa paigaldada, kuna see pole ühilduv selle ownCloud versiooniga.", -"No app name specified" => "Ühegi rakendi nime pole määratletud", -"Help" => "Abiinfo", -"Personal" => "Isiklik", -"Settings" => "Seaded", -"Users" => "Kasutajad", -"Admin" => "Admin", -"Failed to upgrade \"%s\"." => "Ebaõnnestunud uuendus \"%s\".", -"Custom profile pictures don't work with encryption yet" => "Kohandatud profiili pildid ei toimi veel koos krüpteeringuga", -"Unknown filetype" => "Tundmatu failitüüp", -"Invalid image" => "Vigane pilt", -"web services under your control" => "veebitenused sinu kontrolli all", -"cannot open \"%s\"" => "ei suuda avada \"%s\"", -"ZIP download is turned off." => "ZIP-ina allalaadimine on välja lülitatud.", -"Files need to be downloaded one by one." => "Failid tuleb alla laadida ükshaaval.", -"Back to Files" => "Tagasi failide juurde", -"Selected files too large to generate zip file." => "Valitud failid on ZIP-faili loomiseks liiga suured.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Laadi failid alla eraldi väiksemate osadena või küsi nõu oma süsteemiadminstraatorilt.", -"No source specified when installing app" => "Ühegi lähteallikat pole rakendi paigalduseks määratletud", -"No href specified when installing app from http" => "Ühtegi aadressi pole määratletud rakendi paigalduseks veebist", -"No path specified when installing app from local file" => "Ühtegi teed pole määratletud paigaldamaks rakendit kohalikust failist", -"Archives of type %s are not supported" => "%s tüüpi arhiivid pole toetatud", -"Failed to open archive when installing app" => "Arhiivi avamine ebaõnnestus rakendi paigalduse käigus", -"App does not provide an info.xml file" => "Rakend ei paku ühtegi info.xml faili", -"App can't be installed because of not allowed code in the App" => "Rakendit ei saa paigaldada, kuna sisaldab lubamatud koodi", -"App can't be installed because it is not compatible with this version of ownCloud" => "Rakendit ei saa paigaldada, kuna see pole ühilduv selle ownCloud versiooniga.", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Rakendit ei saa paigaldada, kuna see sisaldab \n<shipped>\n\ntrue\n</shipped>\nmärgendit, mis pole lubatud mitte veetud (non shipped) rakendites", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Rakendit ei saa paigaldada, kuna selle versioon info.xml/version pole sama, mis on märgitud rakendite laos.", -"App directory already exists" => "Rakendi kataloog on juba olemas", -"Can't create app folder. Please fix permissions. %s" => "Ei saa luua rakendi kataloogi. Palun korrigeeri õigusi. %s", -"Application is not enabled" => "Rakendus pole sisse lülitatud", -"Authentication error" => "Autentimise viga", -"Token expired. Please reload page." => "Kontrollkood aegus. Paelun lae leht uuesti.", -"Files" => "Failid", -"Text" => "Tekst", -"Images" => "Pildid", -"%s enter the database username." => "%s sisesta andmebaasi kasutajatunnus.", -"%s enter the database name." => "%s sisesta andmebaasi nimi.", -"%s you may not use dots in the database name" => "%s punktide kasutamine andmebaasi nimes pole lubatud", -"MS SQL username and/or password not valid: %s" => "MS SQL kasutajatunnus ja/või parool pole õiged: %s", -"You need to enter either an existing account or the administrator." => "Sisesta kas juba olemasolev konto või administrator.", -"MySQL username and/or password not valid" => "MySQL kasutajatunnus ja/või parool pole õiged", -"DB Error: \"%s\"" => "Andmebaasi viga: \"%s\"", -"Offending command was: \"%s\"" => "Tõrkuv käsk oli: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL kasutaja '%s'@'localhost' on juba olemas.", -"Drop this user from MySQL" => "Kustuta see kasutaja MySQL-ist", -"MySQL user '%s'@'%%' already exists" => "MySQL kasutaja '%s'@'%%' on juba olemas", -"Drop this user from MySQL." => "Kustuta see kasutaja MySQL-ist.", -"Oracle connection could not be established" => "Ei suuda luua ühendust Oracle baasiga", -"Oracle username and/or password not valid" => "Oracle kasutajatunnus ja/või parool pole õiged", -"Offending command was: \"%s\", name: %s, password: %s" => "Tõrkuv käsk oli: \"%s\", nimi: %s, parool: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL kasutajatunnus ja/või parool pole õiged", -"Set an admin username." => "Määra admin kasutajanimi.", -"Set an admin password." => "Määra admini parool.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Veebiserveri ei ole veel korralikult seadistatud võimaldamaks failide sünkroniseerimist, kuna WebDAV liides näib olevat mittetoimiv.", -"Please double check the <a href='%s'>installation guides</a>." => "Palun tutvu veelkord <a href='%s'>paigalduse juhenditega</a>.", -"seconds ago" => "sekundit tagasi", -"_%n minute ago_::_%n minutes ago_" => array("","%n minutit tagasi"), -"_%n hour ago_::_%n hours ago_" => array("","%n tundi tagasi"), -"today" => "täna", -"yesterday" => "eile", -"_%n day go_::_%n days ago_" => array("","%n päeva tagasi"), -"last month" => "viimasel kuul", -"_%n month ago_::_%n months ago_" => array("","%n kuud tagasi"), -"last year" => "viimasel aastal", -"years ago" => "aastat tagasi", -"Caused by:" => "Põhjustaja:", -"Could not find category \"%s\"" => "Ei leia kategooriat \"%s\"" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/eu.php b/lib/private/l10n/eu.php deleted file mode 100644 index 413819f4f94..00000000000 --- a/lib/private/l10n/eu.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Laguntza", -"Personal" => "Pertsonala", -"Settings" => "Ezarpenak", -"Users" => "Erabiltzaileak", -"Admin" => "Admin", -"Failed to upgrade \"%s\"." => "Ezin izan da \"%s\" eguneratu.", -"web services under your control" => "web zerbitzuak zure kontrolpean", -"cannot open \"%s\"" => "ezin da \"%s\" ireki", -"ZIP download is turned off." => "ZIP deskarga ez dago gaituta.", -"Files need to be downloaded one by one." => "Fitxategiak banan-banan deskargatu behar dira.", -"Back to Files" => "Itzuli fitxategietara", -"Selected files too large to generate zip file." => "Hautatuko fitxategiak oso handiak dira zip fitxategia sortzeko.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Deskargatu fitzategiak zati txikiagoetan, banan-banan edo eskatu mesedez zure administradoreari", -"Application is not enabled" => "Aplikazioa ez dago gaituta", -"Authentication error" => "Autentifikazio errorea", -"Token expired. Please reload page." => "Tokena iraungitu da. Mesedez birkargatu orria.", -"Files" => "Fitxategiak", -"Text" => "Testua", -"Images" => "Irudiak", -"%s enter the database username." => "%s sartu datu basearen erabiltzaile izena.", -"%s enter the database name." => "%s sartu datu basearen izena.", -"%s you may not use dots in the database name" => "%s ezin duzu punturik erabili datu basearen izenean.", -"MS SQL username and/or password not valid: %s" => "MS SQL erabiltzaile izena edota pasahitza ez dira egokiak: %s", -"You need to enter either an existing account or the administrator." => "Existitzen den kontu bat edo administradorearena jarri behar duzu.", -"MySQL username and/or password not valid" => "MySQL erabiltzaile edota pasahitza ez dira egokiak.", -"DB Error: \"%s\"" => "DB errorea: \"%s\"", -"Offending command was: \"%s\"" => "Errorea komando honek sortu du: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL '%s'@'localhost' erabiltzailea dagoeneko existitzen da.", -"Drop this user from MySQL" => "Ezabatu erabiltzaile hau MySQLtik", -"MySQL user '%s'@'%%' already exists" => "MySQL '%s'@'%%' erabiltzailea dagoeneko existitzen da", -"Drop this user from MySQL." => "Ezabatu erabiltzaile hau MySQLtik.", -"Oracle connection could not be established" => "Ezin da Oracle konexioa sortu", -"Oracle username and/or password not valid" => "Oracle erabiltzaile edota pasahitza ez dira egokiak.", -"Offending command was: \"%s\", name: %s, password: %s" => "Errorea komando honek sortu du: \"%s\", izena: %s, pasahitza: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL erabiltzaile edota pasahitza ez dira egokiak.", -"Set an admin username." => "Ezarri administraziorako erabiltzaile izena.", -"Set an admin password." => "Ezarri administraziorako pasahitza.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Zure web zerbitzaria ez dago oraindik ongi konfiguratuta fitxategien sinkronizazioa egiteko, WebDAV interfazea ongi ez dagoela dirudi.", -"Please double check the <a href='%s'>installation guides</a>." => "Mesedez begiratu <a href='%s'>instalazio gidak</a>.", -"seconds ago" => "segundu", -"_%n minute ago_::_%n minutes ago_" => array("orain dela minutu %n","orain dela %n minutu"), -"_%n hour ago_::_%n hours ago_" => array("orain dela ordu %n","orain dela %n ordu"), -"today" => "gaur", -"yesterday" => "atzo", -"_%n day go_::_%n days ago_" => array("orain dela egun %n","orain dela %n egun"), -"last month" => "joan den hilabetean", -"_%n month ago_::_%n months ago_" => array("orain dela hilabete %n","orain dela %n hilabete"), -"last year" => "joan den urtean", -"years ago" => "urte", -"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/private/l10n/fa.php b/lib/private/l10n/fa.php deleted file mode 100644 index e9cb695bade..00000000000 --- a/lib/private/l10n/fa.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "راهنما", -"Personal" => "شخصی", -"Settings" => "تنظیمات", -"Users" => "کاربران", -"Admin" => "مدیر", -"web services under your control" => "سرویس های تحت وب در کنترل شما", -"ZIP download is turned off." => "دانلود به صورت فشرده غیر فعال است", -"Files need to be downloaded one by one." => "فایل ها باید به صورت یکی یکی دانلود شوند", -"Back to Files" => "بازگشت به فایل ها", -"Selected files too large to generate zip file." => "فایل های انتخاب شده بزرگتر از آن هستند که بتوان یک فایل فشرده تولید کرد", -"Application is not enabled" => "برنامه فعال نشده است", -"Authentication error" => "خطا در اعتبار سنجی", -"Token expired. Please reload page." => "رمز منقضی شده است. لطفا دوباره صفحه را بارگذاری نمایید.", -"Files" => "پروندهها", -"Text" => "متن", -"Images" => "تصاویر", -"%s enter the database username." => "%s نام کاربری پایگاه داده را وارد نمایید.", -"%s enter the database name." => "%s نام پایگاه داده را وارد نمایید.", -"%s you may not use dots in the database name" => "%s شما نباید از نقطه در نام پایگاه داده استفاده نمایید.", -"MS SQL username and/or password not valid: %s" => "نام کاربری و / یا رمزعبور MS SQL معتبر نیست: %s", -"You need to enter either an existing account or the administrator." => "شما نیاز به وارد کردن یک حساب کاربری موجود یا حساب مدیریتی دارید.", -"MySQL username and/or password not valid" => "نام کاربری و / یا رمزعبور MySQL معتبر نیست.", -"DB Error: \"%s\"" => "خطای پایگاه داده: \"%s\"", -"Offending command was: \"%s\"" => "دستور متخلف عبارت است از: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "کاربرMySQL '%s'@'localhost' درحال حاضر موجود است.", -"Drop this user from MySQL" => "این کاربر را از MySQL حذف نمایید.", -"MySQL user '%s'@'%%' already exists" => "کاربر'%s'@'%%' MySQL در حال حاضر موجود است.", -"Drop this user from MySQL." => "این کاربر را از MySQL حذف نمایید.", -"Oracle connection could not be established" => "ارتباط اراکل نمیتواند برقرار باشد.", -"Oracle username and/or password not valid" => "نام کاربری و / یا رمزعبور اراکل معتبر نیست.", -"Offending command was: \"%s\", name: %s, password: %s" => "دستور متخلف عبارت است از: \"%s\"، نام: \"%s\"، رمزعبور:\"%s\"", -"PostgreSQL username and/or password not valid" => "PostgreSQL نام کاربری و / یا رمزعبور معتبر نیست.", -"Set an admin username." => "یک نام کاربری برای مدیر تنظیم نمایید.", -"Set an admin password." => "یک رمزعبور برای مدیر تنظیم نمایید.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "احتمالاً وب سرور شما طوری تنظیم نشده است که اجازه ی همگام سازی فایلها را بدهد زیرا به نظر میرسد رابط WebDAV از کار افتاده است.", -"Please double check the <a href='%s'>installation guides</a>." => "لطفاً دوباره <a href='%s'>راهنمای نصب</a>را بررسی کنید.", -"seconds ago" => "ثانیهها پیش", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "امروز", -"yesterday" => "دیروز", -"_%n day go_::_%n days ago_" => array(""), -"last month" => "ماه قبل", -"_%n month ago_::_%n months ago_" => array(""), -"last year" => "سال قبل", -"years ago" => "سالهای قبل", -"Could not find category \"%s\"" => "دسته بندی %s یافت نشد" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/factory.php b/lib/private/l10n/factory.php new file mode 100644 index 00000000000..8c65f368171 --- /dev/null +++ b/lib/private/l10n/factory.php @@ -0,0 +1,34 @@ +<?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\L10N; + +/** + * TODO: Description + */ +class Factory { + /** + * cached instances + */ + protected $instances = array(); + + /** + * get an L10N instance + * @param $app string + * @param $lang string|null + * @return \OC_L10N + */ + public function get($app) { + if (!isset($this->instances[$app])) { + $this->instances[$app] = new \OC_L10N($app); + } + return $this->instances[$app]; + } + +} diff --git a/lib/private/l10n/fi.php b/lib/private/l10n/fi.php deleted file mode 100644 index ac1f80a8f73..00000000000 --- a/lib/private/l10n/fi.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Settings" => "asetukset" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/fi_FI.php b/lib/private/l10n/fi_FI.php deleted file mode 100644 index 1d2bdab749c..00000000000 --- a/lib/private/l10n/fi_FI.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Sovellusta \"%s\" ei voi asentaa, koska se ei ole yhteensopiva käytössä olevan ownCloud-version kanssa.", -"No app name specified" => "Sovelluksen nimeä ei määritelty", -"Help" => "Ohje", -"Personal" => "Henkilökohtainen", -"Settings" => "Asetukset", -"Users" => "Käyttäjät", -"Admin" => "Ylläpitäjä", -"Failed to upgrade \"%s\"." => "Kohteen \"%s\" päivitys epäonnistui.", -"Custom profile pictures don't work with encryption yet" => "Omavalintaiset profiilikuvat eivät toimi salauksen kanssa vielä", -"Unknown filetype" => "Tuntematon tiedostotyyppi", -"Invalid image" => "Virheellinen kuva", -"web services under your control" => "verkkopalvelut hallinnassasi", -"ZIP download is turned off." => "ZIP-lataus on poistettu käytöstä.", -"Files need to be downloaded one by one." => "Tiedostot on ladattava yksittäin.", -"Back to Files" => "Takaisin tiedostoihin", -"Selected files too large to generate zip file." => "Valitut tiedostot ovat liian suurikokoisia mahtuakseen zip-tiedostoon.", -"No source specified when installing app" => "Lähdettä ei määritelty sovellusta asennettaessa", -"No path specified when installing app from local file" => "Polkua ei määritelty sovellusta asennettaessa paikallisesta tiedostosta", -"Archives of type %s are not supported" => "Tyypin %s arkistot eivät ole tuettuja", -"App does not provide an info.xml file" => "Sovellus ei sisällä info.xml-tiedostoa", -"App can't be installed because of not allowed code in the App" => "Sovellusta ei voi asentaa, koska sovellus sisältää kiellettyä koodia", -"App can't be installed because it is not compatible with this version of ownCloud" => "Sovellusta ei voi asentaa, koska se ei ole yhteensopiva käytössä olevan ownCloud-version kanssa", -"App directory already exists" => "Sovelluskansio on jo olemassa", -"Can't create app folder. Please fix permissions. %s" => "Sovelluskansion luominen ei onnistu. Korjaa käyttöoikeudet. %s", -"Application is not enabled" => "Sovellusta ei ole otettu käyttöön", -"Authentication error" => "Tunnistautumisvirhe", -"Token expired. Please reload page." => "Valtuutus vanheni. Lataa sivu uudelleen.", -"Files" => "Tiedostot", -"Text" => "Teksti", -"Images" => "Kuvat", -"%s enter the database username." => "%s anna tietokannan käyttäjätunnus.", -"%s enter the database name." => "%s anna tietokannan nimi.", -"%s you may not use dots in the database name" => "%s et voi käyttää pisteitä tietokannan nimessä", -"MS SQL username and/or password not valid: %s" => "MS SQL -käyttäjätunnus ja/tai -salasana on väärin: %s", -"MySQL username and/or password not valid" => "MySQL:n käyttäjätunnus ja/tai salasana on väärin", -"DB Error: \"%s\"" => "Tietokantavirhe: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL-käyttäjä '%s'@'localhost' on jo olemassa.", -"Drop this user from MySQL" => "Pudota tämä käyttäjä MySQL:stä", -"MySQL user '%s'@'%%' already exists" => "MySQL-käyttäjä '%s'@'%%' on jo olemassa", -"Drop this user from MySQL." => "Pudota tämä käyttäjä MySQL:stä.", -"Oracle connection could not be established" => "Oracle-yhteyttä ei voitu muodostaa", -"Oracle username and/or password not valid" => "Oraclen käyttäjätunnus ja/tai salasana on väärin", -"PostgreSQL username and/or password not valid" => "PostgreSQL:n käyttäjätunnus ja/tai salasana on väärin", -"Set an admin username." => "Aseta ylläpitäjän käyttäjätunnus.", -"Set an admin password." => "Aseta ylläpitäjän salasana.", -"Please double check the <a href='%s'>installation guides</a>." => "Lue tarkasti <a href='%s'>asennusohjeet</a>.", -"seconds ago" => "sekuntia sitten", -"_%n minute ago_::_%n minutes ago_" => array("%n minuutti sitten","%n minuuttia sitten"), -"_%n hour ago_::_%n hours ago_" => array("%n tunti sitten","%n tuntia sitten"), -"today" => "tänään", -"yesterday" => "eilen", -"_%n day go_::_%n days ago_" => array("%n päivä sitten","%n päivää sitten"), -"last month" => "viime kuussa", -"_%n month ago_::_%n months ago_" => array("%n kuukausi sitten","%n kuukautta sitten"), -"last year" => "viime vuonna", -"years ago" => "vuotta sitten", -"Caused by:" => "Aiheuttaja:", -"Could not find category \"%s\"" => "Luokkaa \"%s\" ei löytynyt" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/fr.php b/lib/private/l10n/fr.php deleted file mode 100644 index ab3d618849e..00000000000 --- a/lib/private/l10n/fr.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "L'application \"%s\" ne peut être installée car elle n'est pas compatible avec cette version de ownCloud.", -"No app name specified" => "Aucun nom d'application spécifié", -"Help" => "Aide", -"Personal" => "Personnel", -"Settings" => "Paramètres", -"Users" => "Utilisateurs", -"Admin" => "Administration", -"Failed to upgrade \"%s\"." => "Echec de la mise à niveau \"%s\".", -"Custom profile pictures don't work with encryption yet" => "Les images de profil personnalisées ne fonctionnent pas encore avec le système de chiffrement.", -"Unknown filetype" => "Type de fichier inconnu", -"Invalid image" => "Image invalide", -"web services under your control" => "services web sous votre contrôle", -"cannot open \"%s\"" => "impossible d'ouvrir \"%s\"", -"ZIP download is turned off." => "Téléchargement ZIP désactivé.", -"Files need to be downloaded one by one." => "Les fichiers nécessitent d'être téléchargés un par un.", -"Back to Files" => "Retour aux Fichiers", -"Selected files too large to generate zip file." => "Les fichiers sélectionnés sont trop volumineux pour être compressés.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Télécharger les fichiers en parties plus petites, séparément ou demander avec bienveillance à votre administrateur.", -"No source specified when installing app" => "Aucune source spécifiée pour installer l'application", -"No href specified when installing app from http" => "Aucun href spécifié pour installer l'application par http", -"No path specified when installing app from local file" => "Aucun chemin spécifié pour installer l'application depuis un fichier local", -"Archives of type %s are not supported" => "Les archives de type %s ne sont pas supportées", -"Failed to open archive when installing app" => "Échec de l'ouverture de l'archive lors de l'installation de l'application", -"App does not provide an info.xml file" => "L'application ne fournit pas de fichier info.xml", -"App can't be installed because of not allowed code in the App" => "L'application ne peut être installée car elle contient du code non-autorisé", -"App can't be installed because it is not compatible with this version of ownCloud" => "L'application ne peut être installée car elle n'est pas compatible avec cette version de ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "L'application ne peut être installée car elle contient la balise <shipped>true</shipped> qui n'est pas autorisée pour les applications non-diffusées", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "L'application ne peut être installée car la version de info.xml/version n'est identique à celle indiquée sur l'app store", -"App directory already exists" => "Le dossier de l'application existe déjà", -"Can't create app folder. Please fix permissions. %s" => "Impossible de créer le dossier de l'application. Corrigez les droits d'accès. %s", -"Application is not enabled" => "L'application n'est pas activée", -"Authentication error" => "Erreur d'authentification", -"Token expired. Please reload page." => "La session a expiré. Veuillez recharger la page.", -"Files" => "Fichiers", -"Text" => "Texte", -"Images" => "Images", -"%s enter the database username." => "%s entrez le nom d'utilisateur de la base de données.", -"%s enter the database name." => "%s entrez le nom de la base de données.", -"%s you may not use dots in the database name" => "%s vous nez pouvez pas utiliser de points dans le nom de la base de données", -"MS SQL username and/or password not valid: %s" => "Le nom d'utilisateur et/ou le mot de passe de la base MS SQL est invalide : %s", -"You need to enter either an existing account or the administrator." => "Vous devez spécifier soit le nom d'un compte existant, soit celui de l'administrateur.", -"MySQL username and/or password not valid" => "Nom d'utilisateur et/ou mot de passe de la base MySQL invalide", -"DB Error: \"%s\"" => "Erreur de la base de données : \"%s\"", -"Offending command was: \"%s\"" => "La requête en cause est : \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "L'utilisateur MySQL '%s'@'localhost' existe déjà.", -"Drop this user from MySQL" => "Retirer cet utilisateur de la base MySQL", -"MySQL user '%s'@'%%' already exists" => "L'utilisateur MySQL '%s'@'%%' existe déjà", -"Drop this user from MySQL." => "Retirer cet utilisateur de la base MySQL.", -"Oracle connection could not be established" => "La connexion Oracle ne peut pas être établie", -"Oracle username and/or password not valid" => "Nom d'utilisateur et/ou mot de passe de la base Oracle invalide", -"Offending command was: \"%s\", name: %s, password: %s" => "La requête en cause est : \"%s\", nom : %s, mot de passe : %s", -"PostgreSQL username and/or password not valid" => "Nom d'utilisateur et/ou mot de passe de la base PostgreSQL invalide", -"Set an admin username." => "Spécifiez un nom d'utilisateur pour l'administrateur.", -"Set an admin password." => "Spécifiez un mot de passe administrateur.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Votre serveur web, n'est pas correctement configuré pour permettre la synchronisation des fichiers, car l'interface WebDav ne fonctionne pas comme il faut.", -"Please double check the <a href='%s'>installation guides</a>." => "Veuillez vous référer au <a href='%s'>guide d'installation</a>.", -"seconds ago" => "il y a quelques secondes", -"_%n minute ago_::_%n minutes ago_" => array("","il y a %n minutes"), -"_%n hour ago_::_%n hours ago_" => array("","Il y a %n heures"), -"today" => "aujourd'hui", -"yesterday" => "hier", -"_%n day go_::_%n days ago_" => array("","il y a %n jours"), -"last month" => "le mois dernier", -"_%n month ago_::_%n months ago_" => array("","Il y a %n mois"), -"last year" => "l'année dernière", -"years ago" => "il y a plusieurs années", -"Caused by:" => "Causé par :", -"Could not find category \"%s\"" => "Impossible de trouver la catégorie \"%s\"" -); -$PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/lib/private/l10n/gl.php b/lib/private/l10n/gl.php deleted file mode 100644 index 406272d690f..00000000000 --- a/lib/private/l10n/gl.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Non é posíbel instalar o aplicativo «%s» por non seren compatíbel con esta versión do ownCloud.", -"No app name specified" => "Non se especificou o nome do aplicativo", -"Help" => "Axuda", -"Personal" => "Persoal", -"Settings" => "Axustes", -"Users" => "Usuarios", -"Admin" => "Administración", -"Failed to upgrade \"%s\"." => "Non foi posíbel anovar «%s».", -"Custom profile pictures don't work with encryption yet" => "As imaxes personalizadas de perfil aínda non funcionan co cifrado", -"Unknown filetype" => "Tipo de ficheiro descoñecido", -"Invalid image" => "Imaxe incorrecta", -"web services under your control" => "servizos web baixo o seu control", -"cannot open \"%s\"" => "non foi posíbel abrir «%s»", -"ZIP download is turned off." => "As descargas ZIP están desactivadas.", -"Files need to be downloaded one by one." => "Os ficheiros necesitan seren descargados dun en un.", -"Back to Files" => "Volver aos ficheiros", -"Selected files too large to generate zip file." => "Os ficheiros seleccionados son demasiado grandes como para xerar un ficheiro zip.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Descargue os ficheiros en cachos máis pequenos e por separado, ou pídallos amabelmente ao seu administrador.", -"No source specified when installing app" => "Non foi especificada ningunha orixe ao instalar aplicativos", -"No href specified when installing app from http" => "Non foi especificada ningunha href ao instalar aplicativos", -"No path specified when installing app from local file" => "Non foi especificada ningunha ruta ao instalar aplicativos desde un ficheiro local", -"Archives of type %s are not supported" => "Os arquivos do tipo %s non están admitidos", -"Failed to open archive when installing app" => "Non foi posíbel abrir o arquivo ao instalar aplicativos", -"App does not provide an info.xml file" => "O aplicativo non fornece un ficheiro info.xml", -"App can't be installed because of not allowed code in the App" => "Non é posíbel instalar o aplicativo por mor de conter código non permitido", -"App can't be installed because it is not compatible with this version of ownCloud" => "Non é posíbel instalar o aplicativo por non seren compatíbel con esta versión do ownCloud.", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Non é posíbel instalar o aplicativo por conter a etiqueta\n<shipped>\n\ntrue\n</shipped>\nque non está permitida para os aplicativos non enviados", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Non é posíbel instalar o aplicativo xa que a versión en info.xml/version non é a mesma que a versión informada desde a App Store", -"App directory already exists" => "Xa existe o directorio do aplicativo", -"Can't create app folder. Please fix permissions. %s" => "Non é posíbel crear o cartafol de aplicativos. Corrixa os permisos. %s", -"Application is not enabled" => "O aplicativo non está activado", -"Authentication error" => "Produciuse un erro de autenticación", -"Token expired. Please reload page." => "Testemuña caducada. Recargue a páxina.", -"Files" => "Ficheiros", -"Text" => "Texto", -"Images" => "Imaxes", -"%s enter the database username." => "%s introduza o nome de usuario da base de datos", -"%s enter the database name." => "%s introduza o nome da base de datos", -"%s you may not use dots in the database name" => "%s non se poden empregar puntos na base de datos", -"MS SQL username and/or password not valid: %s" => "Nome de usuario e/ou contrasinal de MS SQL incorrecto: %s", -"You need to enter either an existing account or the administrator." => "Deberá introducir unha conta existente ou o administrador.", -"MySQL username and/or password not valid" => "Nome de usuario e/ou contrasinal de MySQL incorrecto", -"DB Error: \"%s\"" => "Produciuse un erro na base de datos: «%s»", -"Offending command was: \"%s\"" => "A orde ofensiva foi: «%s»", -"MySQL user '%s'@'localhost' exists already." => "O usuario MySQL '%s'@'localhost' xa existe.", -"Drop this user from MySQL" => "Omitir este usuario de MySQL", -"MySQL user '%s'@'%%' already exists" => "O usuario MySQL «%s»@«%%» xa existe.", -"Drop this user from MySQL." => "Omitir este usuario de MySQL.", -"Oracle connection could not be established" => "Non foi posíbel estabelecer a conexión con Oracle", -"Oracle username and/or password not valid" => "Nome de usuario e/ou contrasinal de Oracle incorrecto", -"Offending command was: \"%s\", name: %s, password: %s" => "A orde ofensiva foi: «%s», nome: %s, contrasinal: %s", -"PostgreSQL username and/or password not valid" => "Nome de usuario e/ou contrasinal de PostgreSQL incorrecto", -"Set an admin username." => "Estabeleza un nome de usuario administrador", -"Set an admin password." => "Estabeleza un contrasinal de administrador", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "O seu servidor web non está aínda configurado adecuadamente para permitir a sincronización de ficheiros xa que semella que a interface WebDAV non está a funcionar.", -"Please double check the <a href='%s'>installation guides</a>." => "Volva comprobar as <a href='%s'>guías de instalación</a>", -"seconds ago" => "segundos atrás", -"_%n minute ago_::_%n minutes ago_" => array("hai %n minuto","hai %n minutos"), -"_%n hour ago_::_%n hours ago_" => array("hai %n hora","hai %n horas"), -"today" => "hoxe", -"yesterday" => "onte", -"_%n day go_::_%n days ago_" => array("hai %n día","hai %n días"), -"last month" => "último mes", -"_%n month ago_::_%n months ago_" => array("hai %n mes","hai %n meses"), -"last year" => "último ano", -"years ago" => "anos atrás", -"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/private/l10n/he.php b/lib/private/l10n/he.php deleted file mode 100644 index ced6244ee91..00000000000 --- a/lib/private/l10n/he.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "עזרה", -"Personal" => "אישי", -"Settings" => "הגדרות", -"Users" => "משתמשים", -"Admin" => "מנהל", -"web services under your control" => "שירותי רשת תחת השליטה שלך", -"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.", -"Application is not enabled" => "יישומים אינם מופעלים", -"Authentication error" => "שגיאת הזדהות", -"Token expired. Please reload page." => "פג תוקף. נא לטעון שוב את הדף.", -"Files" => "קבצים", -"Text" => "טקסט", -"Images" => "תמונות", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "שרת האינטרנט שלך אינו מוגדר לצורכי סנכרון קבצים עדיין כיוון שמנשק ה־WebDAV כנראה אינו תקין.", -"Please double check the <a href='%s'>installation guides</a>." => "נא לעיין שוב ב<a href='%s'>מדריכי ההתקנה</a>.", -"seconds ago" => "שניות", -"_%n minute ago_::_%n minutes ago_" => array("","לפני %n דקות"), -"_%n hour ago_::_%n hours ago_" => array("","לפני %n שעות"), -"today" => "היום", -"yesterday" => "אתמול", -"_%n day go_::_%n days ago_" => array("","לפני %n ימים"), -"last month" => "חודש שעבר", -"_%n month ago_::_%n months ago_" => array("","לפני %n חודשים"), -"last year" => "שנה שעברה", -"years ago" => "שנים", -"Could not find category \"%s\"" => "לא ניתן למצוא את הקטגוריה „%s“" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/hi.php b/lib/private/l10n/hi.php deleted file mode 100644 index 039dfa4465d..00000000000 --- a/lib/private/l10n/hi.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "सहयोग", -"Personal" => "यक्तिगत", -"Settings" => "सेटिंग्स", -"Users" => "उपयोगकर्ता", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/hr.php b/lib/private/l10n/hr.php deleted file mode 100644 index d217f924099..00000000000 --- a/lib/private/l10n/hr.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Pomoć", -"Personal" => "Osobno", -"Settings" => "Postavke", -"Users" => "Korisnici", -"Admin" => "Administrator", -"web services under your control" => "web usluge pod vašom kontrolom", -"Authentication error" => "Greška kod autorizacije", -"Files" => "Datoteke", -"Text" => "Tekst", -"seconds ago" => "sekundi prije", -"_%n minute ago_::_%n minutes ago_" => array("","",""), -"_%n hour ago_::_%n hours ago_" => array("","",""), -"today" => "danas", -"yesterday" => "jučer", -"_%n day go_::_%n days ago_" => array("","",""), -"last month" => "prošli mjesec", -"_%n month ago_::_%n months ago_" => array("","",""), -"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/private/l10n/hu_HU.php b/lib/private/l10n/hu_HU.php deleted file mode 100644 index e944291caee..00000000000 --- a/lib/private/l10n/hu_HU.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -$TRANSLATIONS = array( -"No app name specified" => "Nincs az alkalmazás név megadva.", -"Help" => "Súgó", -"Personal" => "Személyes", -"Settings" => "Beállítások", -"Users" => "Felhasználók", -"Admin" => "Adminsztráció", -"Failed to upgrade \"%s\"." => "Sikertelen Frissítés \"%s\".", -"Unknown filetype" => "Ismeretlen file tipús", -"Invalid image" => "Hibás kép", -"web services under your control" => "webszolgáltatások saját kézben", -"cannot open \"%s\"" => "nem sikerült megnyitni \"%s\"", -"ZIP download is turned off." => "A ZIP-letöltés nincs engedélyezve.", -"Files need to be downloaded one by one." => "A fájlokat egyenként kell letölteni.", -"Back to Files" => "Vissza a Fájlokhoz", -"Selected files too large to generate zip file." => "A kiválasztott fájlok túl nagyok a zip tömörítéshez.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Tölts le a fileokat kisebb chunkokban, kölün vagy kérj segitséget a rendszergazdádtól.", -"App does not provide an info.xml file" => "Az alkalmazás nem szolgáltatott info.xml file-t", -"App can't be installed because it is not compatible with this version of ownCloud" => "Az alalmazás nem telepíthető, mert nem kompatibilis az ownClod ezzel a verziójával.", -"App directory already exists" => "Az alkalmazás mappája már létezik", -"Can't create app folder. Please fix permissions. %s" => "Nem lehetett létrehozni az alkalmzás mappáját. Kérlek ellenőrizd a jogosultásgokat. %s", -"Application is not enabled" => "Az alkalmazás nincs engedélyezve", -"Authentication error" => "Azonosítási hiba", -"Token expired. Please reload page." => "A token lejárt. Frissítse az oldalt.", -"Files" => "Fájlok", -"Text" => "Szöveg", -"Images" => "Képek", -"%s enter the database username." => "%s adja meg az adatbázist elérő felhasználó login nevét.", -"%s enter the database name." => "%s adja meg az adatbázis nevét.", -"%s you may not use dots in the database name" => "%s az adatbázis neve nem tartalmazhat pontot", -"MS SQL username and/or password not valid: %s" => "Az MS SQL felhasználónév és/vagy jelszó érvénytelen: %s", -"You need to enter either an existing account or the administrator." => "Vagy egy létező felhasználó vagy az adminisztrátor bejelentkezési nevét kell megadnia", -"MySQL username and/or password not valid" => "A MySQL felhasználói név és/vagy jelszó érvénytelen", -"DB Error: \"%s\"" => "Adatbázis hiba: \"%s\"", -"Offending command was: \"%s\"" => "A hibát ez a parancs okozta: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "A '%s'@'localhost' MySQL felhasználó már létezik.", -"Drop this user from MySQL" => "Törölje ezt a felhasználót a MySQL-ből", -"MySQL user '%s'@'%%' already exists" => "A '%s'@'%%' MySQL felhasználó már létezik", -"Drop this user from MySQL." => "Törölje ezt a felhasználót a MySQL-ből.", -"Oracle connection could not be established" => "Az Oracle kapcsolat nem hozható létre", -"Oracle username and/or password not valid" => "Az Oracle felhasználói név és/vagy jelszó érvénytelen", -"Offending command was: \"%s\", name: %s, password: %s" => "A hibát okozó parancs ez volt: \"%s\", login név: %s, jelszó: %s", -"PostgreSQL username and/or password not valid" => "A PostgreSQL felhasználói név és/vagy jelszó érvénytelen", -"Set an admin username." => "Állítson be egy felhasználói nevet az adminisztrációhoz.", -"Set an admin password." => "Állítson be egy jelszót az adminisztrációhoz.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Az Ön webkiszolgálója nincs megfelelően beállítva az állományok szinkronizálásához, mert a WebDAV-elérés úgy tűnik, nem működik.", -"Please double check the <a href='%s'>installation guides</a>." => "Kérjük tüzetesen tanulmányozza át a <a href='%s'>telepítési útmutatót</a>.", -"Could not find category \"%s\"" => "Ez a kategória nem található: \"%s\"", -"seconds ago" => "pár másodperce", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "ma", -"yesterday" => "tegnap", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "múlt hónapban", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "tavaly", -"years ago" => "több éve", -"Caused by:" => "Okozta:" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/hy.php b/lib/private/l10n/hy.php deleted file mode 100644 index 15f78e0bce6..00000000000 --- a/lib/private/l10n/hy.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/ia.php b/lib/private/l10n/ia.php deleted file mode 100644 index 34f43bc424a..00000000000 --- a/lib/private/l10n/ia.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Adjuta", -"Personal" => "Personal", -"Settings" => "Configurationes", -"Users" => "Usatores", -"Admin" => "Administration", -"web services under your control" => "servicios web sub tu controlo", -"Files" => "Files", -"Text" => "Texto", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/id.php b/lib/private/l10n/id.php deleted file mode 100644 index 080faddb321..00000000000 --- a/lib/private/l10n/id.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Bantuan", -"Personal" => "Pribadi", -"Settings" => "Setelan", -"Users" => "Pengguna", -"Admin" => "Admin", -"web services under your control" => "layanan web dalam kontrol Anda", -"ZIP download is turned off." => "Pengunduhan ZIP dimatikan.", -"Files need to be downloaded one by one." => "Berkas harus diunduh satu persatu.", -"Back to Files" => "Kembali ke Daftar Berkas", -"Selected files too large to generate zip file." => "Berkas yang dipilih terlalu besar untuk dibuat berkas zip-nya.", -"Application is not enabled" => "Aplikasi tidak diaktifkan", -"Authentication error" => "Galat saat autentikasi", -"Token expired. Please reload page." => "Token kedaluwarsa. Silakan muat ulang halaman.", -"Files" => "Berkas", -"Text" => "Teks", -"Images" => "Gambar", -"%s enter the database username." => "%s masukkan nama pengguna basis data.", -"%s enter the database name." => "%s masukkan nama basis data.", -"%s you may not use dots in the database name" => "%sAnda tidak boleh menggunakan karakter titik pada nama basis data", -"MS SQL username and/or password not valid: %s" => "Nama pengguna dan/atau sandi MySQL tidak valid: %s", -"You need to enter either an existing account or the administrator." => "Anda harus memasukkan akun yang sudah ada atau administrator.", -"MySQL username and/or password not valid" => "Nama pengguna dan/atau sandi MySQL tidak valid", -"DB Error: \"%s\"" => "Galat Basis Data: \"%s\"", -"Offending command was: \"%s\"" => "Perintah yang bermasalah: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Pengguna MySQL '%s'@'localhost' sudah ada.", -"Drop this user from MySQL" => "Hapus pengguna ini dari MySQL", -"MySQL user '%s'@'%%' already exists" => "Pengguna MySQL '%s'@'%%' sudah ada.", -"Drop this user from MySQL." => "Hapus pengguna ini dari MySQL.", -"Oracle username and/or password not valid" => "Nama pengguna dan/atau sandi Oracle tidak valid", -"Offending command was: \"%s\", name: %s, password: %s" => "Perintah yang bermasalah: \"%s\", nama pengguna: %s, sandi: %s", -"PostgreSQL username and/or password not valid" => "Nama pengguna dan/atau sandi PostgreSQL tidak valid", -"Set an admin username." => "Setel nama pengguna admin.", -"Set an admin password." => "Setel sandi admin.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Web server Anda belum dikonfigurasikan dengan baik untuk mengizinkan sinkronisasi berkas karena tampaknya antarmuka WebDAV rusak.", -"Please double check the <a href='%s'>installation guides</a>." => "Silakan periksa ulang <a href='%s'>panduan instalasi</a>.", -"seconds ago" => "beberapa detik yang lalu", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "hari ini", -"yesterday" => "kemarin", -"_%n day go_::_%n days ago_" => array(""), -"last month" => "bulan kemarin", -"_%n month ago_::_%n months ago_" => array(""), -"last year" => "tahun kemarin", -"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/private/l10n/is.php b/lib/private/l10n/is.php deleted file mode 100644 index 7512d278fb8..00000000000 --- a/lib/private/l10n/is.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Hjálp", -"Personal" => "Um mig", -"Settings" => "Stillingar", -"Users" => "Notendur", -"Admin" => "Stjórnun", -"web services under your control" => "vefþjónusta undir þinni stjórn", -"ZIP download is turned off." => "Slökkt á ZIP niðurhali.", -"Files need to be downloaded one by one." => "Skrárnar verður að sækja eina og eina", -"Back to Files" => "Aftur í skrár", -"Selected files too large to generate zip file." => "Valdar skrár eru of stórar til að búa til ZIP skrá.", -"Application is not enabled" => "Forrit ekki virkt", -"Authentication error" => "Villa við auðkenningu", -"Token expired. Please reload page." => "Auðkenning útrunnin. Vinsamlegast skráðu þig aftur inn.", -"Files" => "Skrár", -"Text" => "Texti", -"Images" => "Myndir", -"seconds ago" => "sek.", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "í dag", -"yesterday" => "í gær", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "síðasta mánuði", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "síðasta ári", -"years ago" => "einhverjum árum", -"Could not find category \"%s\"" => "Fann ekki flokkinn \"%s\"" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/it.php b/lib/private/l10n/it.php deleted file mode 100644 index b00789bc86f..00000000000 --- a/lib/private/l10n/it.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "L'applicazione \"%s\" non può essere installata poiché non è compatibile con questa versione di ownCloud.", -"No app name specified" => "Il nome dell'applicazione non è specificato", -"Help" => "Aiuto", -"Personal" => "Personale", -"Settings" => "Impostazioni", -"Users" => "Utenti", -"Admin" => "Admin", -"Failed to upgrade \"%s\"." => "Aggiornamento non riuscito \"%s\".", -"Custom profile pictures don't work with encryption yet" => "Le immagini personalizzate del profilo non funzionano ancora con la cifratura", -"Unknown filetype" => "Tipo di file sconosciuto", -"Invalid image" => "Immagine non valida", -"web services under your control" => "servizi web nelle tue mani", -"cannot open \"%s\"" => "impossibile aprire \"%s\"", -"ZIP download is turned off." => "Lo scaricamento in formato ZIP è stato disabilitato.", -"Files need to be downloaded one by one." => "I file devono essere scaricati uno alla volta.", -"Back to Files" => "Torna ai file", -"Selected files too large to generate zip file." => "I file selezionati sono troppo grandi per generare un file zip.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Scarica i file in blocchi più piccoli, separatamente o chiedi al tuo amministratore.", -"No source specified when installing app" => "Nessuna fonte specificata durante l'installazione dell'applicazione", -"No href specified when installing app from http" => "Nessun href specificato durante l'installazione dell'applicazione da http", -"No path specified when installing app from local file" => "Nessun percorso specificato durante l'installazione dell'applicazione da file locale", -"Archives of type %s are not supported" => "Gli archivi di tipo %s non sono supportati", -"Failed to open archive when installing app" => "Apertura archivio non riuscita durante l'installazione dell'applicazione", -"App does not provide an info.xml file" => "L'applicazione non fornisce un file info.xml", -"App can't be installed because of not allowed code in the App" => "L'applicazione non può essere installata a causa di codice non consentito al suo interno", -"App can't be installed because it is not compatible with this version of ownCloud" => "L'applicazione non può essere installata poiché non è compatibile con questa versione di ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "L'applicazione non può essere installata poiché contiene il tag <shipped>true<shipped> che non è permesso alle applicazioni non shipped", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "L'applicazione non può essere installata poiché la versione in info.xml/version non è la stessa riportata dall'app store", -"App directory already exists" => "La cartella dell'applicazione esiste già", -"Can't create app folder. Please fix permissions. %s" => "Impossibile creare la cartella dell'applicazione. Correggi i permessi. %s", -"Application is not enabled" => "L'applicazione non è abilitata", -"Authentication error" => "Errore di autenticazione", -"Token expired. Please reload page." => "Token scaduto. Ricarica la pagina.", -"Files" => "File", -"Text" => "Testo", -"Images" => "Immagini", -"%s enter the database username." => "%s digita il nome utente del database.", -"%s enter the database name." => "%s digita il nome del database.", -"%s you may not use dots in the database name" => "%s non dovresti utilizzare punti nel nome del database", -"MS SQL username and/or password not valid: %s" => "Nome utente e/o password MS SQL non validi: %s", -"You need to enter either an existing account or the administrator." => "È necessario inserire un account esistente o l'amministratore.", -"MySQL username and/or password not valid" => "Nome utente e/o password di MySQL non validi", -"DB Error: \"%s\"" => "Errore DB: \"%s\"", -"Offending command was: \"%s\"" => "Il comando non consentito era: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "L'utente MySQL '%s'@'localhost' esiste già.", -"Drop this user from MySQL" => "Elimina questo utente da MySQL", -"MySQL user '%s'@'%%' already exists" => "L'utente MySQL '%s'@'%%' esiste già", -"Drop this user from MySQL." => "Elimina questo utente da MySQL.", -"Oracle connection could not be established" => "La connessione a Oracle non può essere stabilita", -"Oracle username and/or password not valid" => "Nome utente e/o password di Oracle non validi", -"Offending command was: \"%s\", name: %s, password: %s" => "Il comando non consentito era: \"%s\", nome: %s, password: %s", -"PostgreSQL username and/or password not valid" => "Nome utente e/o password di PostgreSQL non validi", -"Set an admin username." => "Imposta un nome utente di amministrazione.", -"Set an admin password." => "Imposta una password di amministrazione.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Il tuo server web non è configurato correttamente per consentire la sincronizzazione dei file poiché l'interfaccia WebDAV sembra essere danneggiata.", -"Please double check the <a href='%s'>installation guides</a>." => "Leggi attentamente le <a href='%s'>guide d'installazione</a>.", -"seconds ago" => "secondi fa", -"_%n minute ago_::_%n minutes ago_" => array("%n minuto fa","%n minuti fa"), -"_%n hour ago_::_%n hours ago_" => array("%n ora fa","%n ore fa"), -"today" => "oggi", -"yesterday" => "ieri", -"_%n day go_::_%n days ago_" => array("%n giorno fa","%n giorni fa"), -"last month" => "mese scorso", -"_%n month ago_::_%n months ago_" => array("%n mese fa","%n mesi fa"), -"last year" => "anno scorso", -"years ago" => "anni fa", -"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/private/l10n/ja_JP.php b/lib/private/l10n/ja_JP.php deleted file mode 100644 index b9e6a0e6924..00000000000 --- a/lib/private/l10n/ja_JP.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => " \"%s\" アプリは、このバージョンのownCloudと互換性がない為、インストールできません。", -"No app name specified" => "アプリ名が未指定", -"Help" => "ヘルプ", -"Personal" => "個人", -"Settings" => "設定", -"Users" => "ユーザ", -"Admin" => "管理", -"Failed to upgrade \"%s\"." => "\"%s\" へのアップグレードに失敗しました。", -"Custom profile pictures don't work with encryption yet" => "暗号無しでは利用不可なカスタムプロフィール画像", -"Unknown filetype" => "不明なファイルタイプ", -"Invalid image" => "無効な画像", -"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." => "ファイルは、小さいファイルに分割されてダウンロードされます。もしくは、管理者にお尋ねください。", -"No source specified when installing app" => "アプリインストール時のソースが未指定", -"No href specified when installing app from http" => "アプリインストール時のhttpの URL が未指定", -"No path specified when installing app from local file" => "アプリインストール時のローカルファイルのパスが未指定", -"Archives of type %s are not supported" => "\"%s\"タイプのアーカイブ形式は未サポート", -"Failed to open archive when installing app" => "アプリをインストール中にアーカイブファイルを開けませんでした。", -"App does not provide an info.xml file" => "アプリにinfo.xmlファイルが入っていません", -"App can't be installed because of not allowed code in the App" => "アプリで許可されないコードが入っているのが原因でアプリがインストールできません", -"App can't be installed because it is not compatible with this version of ownCloud" => "アプリは、このバージョンのownCloudと互換性がない為、インストールできません。", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "非shippedアプリには許可されない<shipped>true</shipped>タグが含まれているためにアプリをインストール出来ません。", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "info.xml/versionのバージョンがアプリストアのバージョンと合っていない為、アプリはインストールされません", -"App directory already exists" => "アプリディレクトリは既に存在します", -"Can't create app folder. Please fix permissions. %s" => "アプリフォルダを作成出来ませんでした。%s のパーミッションを修正してください。", -"Application is not enabled" => "アプリケーションは無効です", -"Authentication error" => "認証エラー", -"Token expired. Please reload page." => "トークンが無効になりました。ページを再読込してください。", -"Files" => "ファイル", -"Text" => "TTY TDD", -"Images" => "画像", -"%s enter the database username." => "%s のデータベースのユーザ名を入力してください。", -"%s enter the database name." => "%s のデータベース名を入力してください。", -"%s you may not use dots in the database name" => "%s ではデータベース名にドットを利用できないかもしれません。", -"MS SQL username and/or password not valid: %s" => "MS SQL サーバーのユーザー名/パスワードが正しくありません: %s", -"You need to enter either an existing account or the administrator." => "既存のアカウントもしくは管理者のどちらかを入力する必要があります。", -"MySQL username and/or password not valid" => "MySQLのユーザ名もしくはパスワードは有効ではありません", -"DB Error: \"%s\"" => "DBエラー: \"%s\"", -"Offending command was: \"%s\"" => "違反コマンド: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQLのユーザ '%s'@'localhost' はすでに存在します。", -"Drop this user from MySQL" => "MySQLからこのユーザを削除", -"MySQL user '%s'@'%%' already exists" => "MySQLのユーザ '%s'@'%%' はすでに存在します。", -"Drop this user from MySQL." => "MySQLからこのユーザを削除する。", -"Oracle connection could not be established" => "Oracleへの接続が確立できませんでした。", -"Oracle username and/or password not valid" => "Oracleのユーザ名もしくはパスワードは有効ではありません", -"Offending command was: \"%s\", name: %s, password: %s" => "違反コマンド: \"%s\"、名前: %s、パスワード: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQLのユーザ名もしくはパスワードは有効ではありません", -"Set an admin username." => "管理者のユーザ名を設定。", -"Set an admin password." => "管理者のパスワードを設定。", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "WebDAVインタフェースが動作していないと考えられるため、あなたのWEBサーバはまだファイルの同期を許可するように適切な設定がされていません。", -"Please double check the <a href='%s'>installation guides</a>." => "<a href='%s'>インストールガイド</a>をよく確認してください。", -"seconds ago" => "数秒前", -"_%n minute ago_::_%n minutes ago_" => array("%n 分前"), -"_%n hour ago_::_%n hours ago_" => array("%n 時間後"), -"today" => "今日", -"yesterday" => "昨日", -"_%n day go_::_%n days ago_" => array("%n 日後"), -"last month" => "一月前", -"_%n month ago_::_%n months ago_" => array("%n カ月後"), -"last year" => "一年前", -"years ago" => "年前", -"Caused by:" => "原因は以下:", -"Could not find category \"%s\"" => "カテゴリ \"%s\" が見つかりませんでした" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/ka.php b/lib/private/l10n/ka.php deleted file mode 100644 index 04fefe8bdf1..00000000000 --- a/lib/private/l10n/ka.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "შველა", -"Personal" => "პერსონა", -"Users" => "მომხმარებლები", -"Admin" => "ადმინისტრატორი", -"ZIP download is turned off." => "ZIP გადმოწერა გამორთულია", -"Files" => "ფაილები", -"seconds ago" => "წამის წინ", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "დღეს", -"yesterday" => "გუშინ", -"_%n day go_::_%n days ago_" => array(""), -"_%n month ago_::_%n months ago_" => array("") -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/ka_GE.php b/lib/private/l10n/ka_GE.php deleted file mode 100644 index 8fbe34e6786..00000000000 --- a/lib/private/l10n/ka_GE.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "დახმარება", -"Personal" => "პირადი", -"Settings" => "პარამეტრები", -"Users" => "მომხმარებელი", -"Admin" => "ადმინისტრატორი", -"web services under your control" => "web services under your control", -"ZIP download is turned off." => "ZIP download–ი გათიშულია", -"Files need to be downloaded one by one." => "ფაილები უნდა გადმოიტვირთოს სათითაოდ.", -"Back to Files" => "უკან ფაილებში", -"Selected files too large to generate zip file." => "არჩეული ფაილები ძალიან დიდია zip ფაილის გენერაციისთვის.", -"Application is not enabled" => "აპლიკაცია არ არის აქტიური", -"Authentication error" => "ავთენტიფიკაციის შეცდომა", -"Token expired. Please reload page." => "Token–ს ვადა გაუვიდა. გთხოვთ განაახლოთ გვერდი.", -"Files" => "ფაილები", -"Text" => "ტექსტი", -"Images" => "სურათები", -"%s enter the database username." => "%s შეიყვანეთ ბაზის იუზერნეიმი.", -"%s enter the database name." => "%s შეიყვანეთ ბაზის სახელი.", -"%s you may not use dots in the database name" => "%s არ მიუთითოთ წერტილი ბაზის სახელში", -"MS SQL username and/or password not valid: %s" => "MS SQL მომხმარებელი და/ან პაროლი არ არის მართებული: %s", -"You need to enter either an existing account or the administrator." => "თქვენ უნდა შეიყვანოთ არსებული მომხმარებელის სახელი ან ადმინისტრატორი.", -"MySQL username and/or password not valid" => "MySQL იუზერნეიმი და/ან პაროლი არ არის სწორი", -"DB Error: \"%s\"" => "DB შეცდომა: \"%s\"", -"Offending command was: \"%s\"" => "Offending ბრძანება იყო: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL მომხმარებელი '%s'@'localhost' უკვე არსებობს.", -"Drop this user from MySQL" => "წაშალე ეს მომხამრებელი MySQL–იდან", -"MySQL user '%s'@'%%' already exists" => "MySQL მომხმარებელი '%s'@'%%' უკვე არსებობს", -"Drop this user from MySQL." => "წაშალე ეს მომხამრებელი MySQL–იდან", -"Oracle username and/or password not valid" => "Oracle იუზერნეიმი და/ან პაროლი არ არის სწორი", -"Offending command was: \"%s\", name: %s, password: %s" => "Offending ბრძანება იყო: \"%s\", სახელი: %s, პაროლი: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL იუზერნეიმი და/ან პაროლი არ არის სწორი", -"Set an admin username." => "დააყენეთ ადმინისტრატორის სახელი.", -"Set an admin password." => "დააყენეთ ადმინისტრატორის პაროლი.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "თქვენი web სერვერი არ არის კონფიგურირებული ფაილ სინქრონიზაციისთვის, რადგან WebDAV ინტერფეისი შეიძლება იყოს გატეხილი.", -"Please double check the <a href='%s'>installation guides</a>." => "გთხოვთ გადაათვალიეროთ <a href='%s'>ინსტალაციის გზამკვლევი</a>.", -"seconds ago" => "წამის წინ", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "დღეს", -"yesterday" => "გუშინ", -"_%n day go_::_%n days ago_" => array(""), -"last month" => "გასულ თვეში", -"_%n month ago_::_%n months ago_" => array(""), -"last year" => "ბოლო წელს", -"years ago" => "წლის წინ", -"Could not find category \"%s\"" => "\"%s\" კატეგორიის მოძებნა ვერ მოხერხდა" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/km.php b/lib/private/l10n/km.php deleted file mode 100644 index e7b09649a24..00000000000 --- a/lib/private/l10n/km.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"_%n day go_::_%n days ago_" => array(""), -"_%n month ago_::_%n months ago_" => array("") -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/kn.php b/lib/private/l10n/kn.php deleted file mode 100644 index e7b09649a24..00000000000 --- a/lib/private/l10n/kn.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"_%n day go_::_%n days ago_" => array(""), -"_%n month ago_::_%n months ago_" => array("") -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/ko.php b/lib/private/l10n/ko.php deleted file mode 100644 index 3ef39fefa60..00000000000 --- a/lib/private/l10n/ko.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "현재 ownCloud 버전과 호환되지 않기 때문에 \"%s\" 앱을 설치할 수 없습니다.", -"No app name specified" => "앱 이름이 지정되지 않았습니다.", -"Help" => "도움말", -"Personal" => "개인", -"Settings" => "설정", -"Users" => "사용자", -"Admin" => "관리자", -"Failed to upgrade \"%s\"." => "\"%s\" 업그레이드에 실패했습니다.", -"Custom profile pictures don't work with encryption yet" => "개개인의 프로필 사진은 아직은 암호화 되지 않습니다", -"Unknown filetype" => "알수없는 파일형식", -"Invalid image" => "잘못된 그림", -"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." => "작은 조각들 안에 들어있는 파일들을 받고자 하신다면, 나누어서 받으시거나 혹은 시스템 관리자에게 정중하게 물어보십시오", -"No source specified when installing app" => "앱을 설치할 때 소스가 지정되지 않았습니다.", -"No href specified when installing app from http" => "http에서 앱을 설치할 대 href가 지정되지 않았습니다.", -"No path specified when installing app from local file" => "로컬 파일에서 앱을 설치할 때 경로가 지정되지 않았습니다.", -"Archives of type %s are not supported" => "%s 타입 아카이브는 지원되지 않습니다.", -"Failed to open archive when installing app" => "앱을 설치할 때 아카이브를 열지 못했습니다.", -"App does not provide an info.xml file" => "앱에서 info.xml 파일이 제공되지 않았습니다.", -"App can't be installed because of not allowed code in the App" => "앱에 허용되지 않는 코드가 있어서 앱을 설치할 수 없습니다. ", -"App can't be installed because it is not compatible with this version of ownCloud" => "현재 ownCloud 버전과 호환되지 않기 때문에 앱을 설치할 수 없습니다.", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "출하되지 않은 앱에 허용되지 않는 <shipped>true</shipped> 태그를 포함하고 있기 때문에 앱을 설치할 수 없습니다.", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "info.xml/version에 포함된 버전과 앱 스토어에 보고된 버전이 같지 않아서 앱을 설치할 수 없습니다. ", -"App directory already exists" => "앱 디렉토리가 이미 존재합니다. ", -"Can't create app folder. Please fix permissions. %s" => "앱 폴더를 만들 수 없습니다. 권한을 수정하십시오. %s ", -"Application is not enabled" => "앱이 활성화되지 않았습니다", -"Authentication error" => "인증 오류", -"Token expired. Please reload page." => "토큰이 만료되었습니다. 페이지를 새로 고치십시오.", -"Files" => "파일", -"Text" => "텍스트", -"Images" => "그림", -"%s enter the database username." => "데이터베이스 사용자 명을 %s 에 입력해주십시오", -"%s enter the database name." => "데이터베이스 명을 %s 에 입력해주십시오", -"%s you may not use dots in the database name" => "%s 에 적으신 데이터베이스 이름에는 점을 사용할수 없습니다", -"MS SQL username and/or password not valid: %s" => "MS SQL 사용자 이름이나 암호가 잘못되었습니다: %s", -"You need to enter either an existing account or the administrator." => "기존 계정이나 administrator(관리자)를 입력해야 합니다.", -"MySQL username and/or password not valid" => "MySQL 사용자 이름이나 암호가 잘못되었습니다.", -"DB Error: \"%s\"" => "DB 오류: \"%s\"", -"Offending command was: \"%s\"" => "잘못된 명령: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL 사용자 '%s'@'localhost'이(가) 이미 존재합니다.", -"Drop this user from MySQL" => "이 사용자를 MySQL에서 뺍니다.", -"MySQL user '%s'@'%%' already exists" => "MySQL 사용자 '%s'@'%%'이(가) 이미 존재합니다. ", -"Drop this user from MySQL." => "이 사용자를 MySQL에서 뺍니다.", -"Oracle connection could not be established" => "Oracle 연결을 수립할 수 없습니다.", -"Oracle username and/or password not valid" => "Oracle 사용자 이름이나 암호가 잘못되었습니다.", -"Offending command was: \"%s\", name: %s, password: %s" => "잘못된 명령: \"%s\", 이름: %s, 암호: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL의 사용자 명 혹은 비밀번호가 잘못되었습니다", -"Set an admin username." => "관리자 이름 설정", -"Set an admin password." => "관리자 비밀번호 설정", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "WebDAV 인터페이스가 제대로 작동하지 않습니다. 웹 서버에서 파일 동기화를 사용할 수 있도록 설정이 제대로 되지 않은 것 같습니다.", -"Please double check the <a href='%s'>installation guides</a>." => "<a href='%s'>설치 가이드</a>를 다시 한 번 확인하십시오.", -"Could not find category \"%s\"" => "분류 \"%s\"을(를) 찾을 수 없습니다.", -"seconds ago" => "초 전", -"_%n minute ago_::_%n minutes ago_" => array("%n분 전 "), -"_%n hour ago_::_%n hours ago_" => array("%n시간 전 "), -"today" => "오늘", -"yesterday" => "어제", -"_%n day go_::_%n days ago_" => array("%n일 전 "), -"last month" => "지난 달", -"_%n month ago_::_%n months ago_" => array("%n달 전 "), -"last year" => "작년", -"years ago" => "년 전", -"Caused by:" => "원인: " -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/ku_IQ.php b/lib/private/l10n/ku_IQ.php deleted file mode 100644 index c99f9dd2a12..00000000000 --- a/lib/private/l10n/ku_IQ.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "یارمەتی", -"Settings" => "دهستكاری", -"Users" => "بهكارهێنهر", -"Admin" => "بهڕێوهبهری سهرهكی", -"web services under your control" => "ڕاژهی وێب لهژێر چاودێریت دایه", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/lb.php b/lib/private/l10n/lb.php deleted file mode 100644 index c25f5b55bd5..00000000000 --- a/lib/private/l10n/lb.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Hëllef", -"Personal" => "Perséinlech", -"Settings" => "Astellungen", -"Users" => "Benotzer", -"Admin" => "Admin", -"web services under your control" => "Web-Servicer ënnert denger Kontroll", -"Authentication error" => "Authentifikatioun's Fehler", -"Files" => "Dateien", -"Text" => "SMS", -"seconds ago" => "Sekonnen hir", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "haut", -"yesterday" => "gëschter", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "Läschte Mount", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "Läscht Joer", -"years ago" => "Joren hier" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/lt_LT.php b/lib/private/l10n/lt_LT.php deleted file mode 100644 index db8d96c1018..00000000000 --- a/lib/private/l10n/lt_LT.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Programa „%s“ negali būti įdiegta, nes yra nesuderinama su šia ownCloud versija.", -"No app name specified" => "Nenurodytas programos pavadinimas", -"Help" => "Pagalba", -"Personal" => "Asmeniniai", -"Settings" => "Nustatymai", -"Users" => "Vartotojai", -"Admin" => "Administravimas", -"Failed to upgrade \"%s\"." => "Nepavyko pakelti „%s“ versijos.", -"Custom profile pictures don't work with encryption yet" => "Saviti profilio paveiksliukai dar neveikia su šifravimu", -"Unknown filetype" => "Nežinomas failo tipas", -"Invalid image" => "Netinkamas paveikslėlis", -"web services under your control" => "jūsų valdomos web paslaugos", -"cannot open \"%s\"" => "nepavyksta atverti „%s“", -"ZIP download is turned off." => "ZIP atsisiuntimo galimybė yra išjungta.", -"Files need to be downloaded one by one." => "Failai turi būti parsiunčiami vienas po kito.", -"Back to Files" => "Atgal į Failus", -"Selected files too large to generate zip file." => "Pasirinkti failai per dideli archyvavimui į ZIP.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Atsisiųskite failus mažesnėmis dalimis atskirai, arba mandagiai prašykite savo administratoriaus.", -"No source specified when installing app" => "Nenurodytas šaltinis diegiant programą", -"No href specified when installing app from http" => "Nenurodytas href diegiant programą iš http", -"No path specified when installing app from local file" => "Nenurodytas kelias diegiant programą iš vietinio failo", -"Archives of type %s are not supported" => "%s tipo archyvai nepalaikomi", -"Failed to open archive when installing app" => "Nepavyko atverti archyvo diegiant programą", -"App does not provide an info.xml file" => "Programa nepateikia info.xml failo", -"App can't be installed because of not allowed code in the App" => "Programa negali būti įdiegta, nes turi neleistiną kodą", -"App can't be installed because it is not compatible with this version of ownCloud" => "Programa negali būti įdiegta, nes yra nesuderinama su šia ownCloud versija", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Programa negali būti įdiegta, nes turi <shipped>true</shipped> žymę, kuri yra neleistina ne kartu platinamoms programoms", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Programa negali būti įdiegta, nes versija pateikta info.xml/version nesutampa su versija deklaruota programų saugykloje", -"App directory already exists" => "Programos aplankas jau egzistuoja", -"Can't create app folder. Please fix permissions. %s" => "Nepavyksta sukurti aplanko. Prašome pataisyti leidimus. %s", -"Application is not enabled" => "Programa neįjungta", -"Authentication error" => "Autentikacijos klaida", -"Token expired. Please reload page." => "Sesija baigėsi. Prašome perkrauti puslapį.", -"Files" => "Failai", -"Text" => "Žinučių", -"Images" => "Paveikslėliai", -"%s enter the database username." => "%s įrašykite duombazės naudotojo vardą.", -"%s enter the database name." => "%s įrašykite duombazės pavadinimą.", -"%s you may not use dots in the database name" => "%s negalite naudoti taškų duombazės pavadinime", -"MS SQL username and/or password not valid: %s" => "MS SQL naudotojo vardas ir/arba slaptažodis netinka: %s", -"You need to enter either an existing account or the administrator." => "Turite prisijungti su egzistuojančia paskyra arba su administratoriumi.", -"MySQL username and/or password not valid" => "Neteisingas MySQL naudotojo vardas ir/arba slaptažodis", -"DB Error: \"%s\"" => "DB klaida: \"%s\"", -"Offending command was: \"%s\"" => "Vykdyta komanda buvo: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL naudotojas '%s'@'localhost' jau egzistuoja.", -"Drop this user from MySQL" => "Pašalinti šį naudotoją iš MySQL", -"MySQL user '%s'@'%%' already exists" => "MySQL naudotojas '%s'@'%%' jau egzistuoja", -"Drop this user from MySQL." => "Pašalinti šį naudotoją iš MySQL.", -"Oracle connection could not be established" => "Nepavyko sukurti Oracle ryšio", -"Oracle username and/or password not valid" => "Neteisingas Oracle naudotojo vardas ir/arba slaptažodis", -"Offending command was: \"%s\", name: %s, password: %s" => "Vykdyta komanda buvo: \"%s\", name: %s, password: %s", -"PostgreSQL username and/or password not valid" => "Neteisingas PostgreSQL naudotojo vardas ir/arba slaptažodis", -"Set an admin username." => "Nustatyti administratoriaus naudotojo vardą.", -"Set an admin password." => "Nustatyti administratoriaus slaptažodį.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Jūsų serveris nėra tvarkingai nustatytas leisti failų sinchronizaciją, nes WebDAV sąsaja panašu, kad yra sugadinta.", -"Please double check the <a href='%s'>installation guides</a>." => "Prašome pažiūrėkite dar kartą <a href='%s'>diegimo instrukcijas</a>.", -"seconds ago" => "prieš sekundę", -"_%n minute ago_::_%n minutes ago_" => array("prieš %n min.","Prieš % minutes","Prieš %n minučių"), -"_%n hour ago_::_%n hours ago_" => array("Prieš %n valandą","Prieš %n valandas","Prieš %n valandų"), -"today" => "šiandien", -"yesterday" => "vakar", -"_%n day go_::_%n days ago_" => array("Prieš %n dieną","Prieš %n dienas","Prieš %n dienų"), -"last month" => "praeitą mėnesį", -"_%n month ago_::_%n months ago_" => array("Prieš %n mėnesį","Prieš %n mėnesius","Prieš %n mėnesių"), -"last year" => "praeitais metais", -"years ago" => "prieš metus", -"Caused by:" => "Iššaukė:", -"Could not find category \"%s\"" => "Nepavyko rasti kategorijos „%s“" -); -$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/private/l10n/lv.php b/lib/private/l10n/lv.php deleted file mode 100644 index 4090a36edcc..00000000000 --- a/lib/private/l10n/lv.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Palīdzība", -"Personal" => "Personīgi", -"Settings" => "Iestatījumi", -"Users" => "Lietotāji", -"Admin" => "Administratori", -"Failed to upgrade \"%s\"." => "Kļūda atjauninot \"%s\"", -"web services under your control" => "tīmekļa servisi tavā varā", -"cannot open \"%s\"" => "Nevar atvērt \"%s\"", -"ZIP download is turned off." => "ZIP lejupielādēšana ir izslēgta.", -"Files need to be downloaded one by one." => "Datnes var lejupielādēt tikai katru atsevišķi.", -"Back to Files" => "Atpakaļ pie datnēm", -"Selected files too large to generate zip file." => "Izvēlētās datnes ir pārāk lielas, lai izveidotu zip datni.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Lejupielādējiet savus failus mazākās daļās, atsevišķi vai palūdziet tos administratoram.", -"Application is not enabled" => "Lietotne nav aktivēta", -"Authentication error" => "Autentifikācijas kļūda", -"Token expired. Please reload page." => "Pilnvarai ir beidzies termiņš. Lūdzu, pārlādējiet lapu.", -"Files" => "Datnes", -"Text" => "Teksts", -"Images" => "Attēli", -"%s enter the database username." => "%s ievadiet datubāzes lietotājvārdu.", -"%s enter the database name." => "%s ievadiet datubāzes nosaukumu.", -"%s you may not use dots in the database name" => "%s datubāžu nosaukumos nedrīkst izmantot punktus", -"MS SQL username and/or password not valid: %s" => "Nav derīga MySQL parole un/vai lietotājvārds — %s", -"You need to enter either an existing account or the administrator." => "Jums jāievada vai nu esošs vai administratora konts.", -"MySQL username and/or password not valid" => "Nav derīga MySQL parole un/vai lietotājvārds", -"DB Error: \"%s\"" => "DB kļūda — “%s”", -"Offending command was: \"%s\"" => "Vainīgā komanda bija “%s”", -"MySQL user '%s'@'localhost' exists already." => "MySQL lietotājs %s'@'localhost' jau eksistē.", -"Drop this user from MySQL" => "Izmest šo lietotāju no MySQL", -"MySQL user '%s'@'%%' already exists" => "MySQL lietotājs '%s'@'%%' jau eksistē", -"Drop this user from MySQL." => "Izmest šo lietotāju no MySQL.", -"Oracle connection could not be established" => "Nevar izveidot savienojumu ar Oracle", -"Oracle username and/or password not valid" => "Nav derīga Oracle parole un/vai lietotājvārds", -"Offending command was: \"%s\", name: %s, password: %s" => "Vainīgā komanda bija \"%s\", vārds: %s, parole: %s", -"PostgreSQL username and/or password not valid" => "Nav derīga PostgreSQL parole un/vai lietotājvārds", -"Set an admin username." => "Iestatiet administratora lietotājvārdu.", -"Set an admin password." => "Iestatiet administratora paroli.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Jūsu serveris vēl nav pareizi iestatīts, lai ļautu sinhronizēt datnes, jo izskatās, ka WebDAV saskarne ir salauzta.", -"Please double check the <a href='%s'>installation guides</a>." => "Lūdzu, vēlreiz pārbaudiet <a href='%s'>instalēšanas palīdzību</a>.", -"seconds ago" => "sekundes atpakaļ", -"_%n minute ago_::_%n minutes ago_" => array("","","Pirms %n minūtēm"), -"_%n hour ago_::_%n hours ago_" => array("","","Pirms %n stundām"), -"today" => "šodien", -"yesterday" => "vakar", -"_%n day go_::_%n days ago_" => array("","","Pirms %n dienām"), -"last month" => "pagājušajā mēnesī", -"_%n month ago_::_%n months ago_" => array("","","Pirms %n mēnešiem"), -"last year" => "gājušajā gadā", -"years ago" => "gadus atpakaļ", -"Caused by:" => "Cēlonis:", -"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/private/l10n/mk.php b/lib/private/l10n/mk.php deleted file mode 100644 index 69d4a1cb694..00000000000 --- a/lib/private/l10n/mk.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Помош", -"Personal" => "Лично", -"Settings" => "Подесувања", -"Users" => "Корисници", -"Admin" => "Админ", -"web services under your control" => "веб сервиси под Ваша контрола", -"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.", -"Application is not enabled" => "Апликацијата не е овозможена", -"Authentication error" => "Грешка во автентикација", -"Token expired. Please reload page." => "Жетонот е истечен. Ве молам превчитајте ја страницата.", -"Files" => "Датотеки", -"Text" => "Текст", -"Images" => "Слики", -"seconds ago" => "пред секунди", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "денеска", -"yesterday" => "вчера", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "минатиот месец", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "минатата година", -"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/private/l10n/ml_IN.php b/lib/private/l10n/ml_IN.php deleted file mode 100644 index 15f78e0bce6..00000000000 --- a/lib/private/l10n/ml_IN.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/ms_MY.php b/lib/private/l10n/ms_MY.php deleted file mode 100644 index 17ef07f83dd..00000000000 --- a/lib/private/l10n/ms_MY.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Bantuan", -"Personal" => "Peribadi", -"Settings" => "Tetapan", -"Users" => "Pengguna", -"Admin" => "Admin", -"web services under your control" => "Perkhidmatan web di bawah kawalan anda", -"Authentication error" => "Ralat pengesahan", -"Files" => "Fail-fail", -"Text" => "Teks", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"_%n day go_::_%n days ago_" => array(""), -"_%n month ago_::_%n months ago_" => array("") -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/my_MM.php b/lib/private/l10n/my_MM.php deleted file mode 100644 index 5f4b6ddc820..00000000000 --- a/lib/private/l10n/my_MM.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "အကူအညီ", -"Users" => "သုံးစွဲသူ", -"Admin" => "အက်ဒမင်", -"web services under your control" => "သင်၏ထိန်းချုပ်မှု့အောက်တွင်ရှိသော Web services", -"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 ဖိုင်အဖြစ်ပြုလုပ်ရန် ရွေးချယ်ထားသောဖိုင်များသည် အရမ်းကြီးလွန်းသည်", -"Authentication error" => "ခွင့်ပြုချက်မအောင်မြင်", -"Files" => "ဖိုင်များ", -"Text" => "စာသား", -"Images" => "ပုံရိပ်များ", -"seconds ago" => "စက္ကန့်အနည်းငယ်က", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "ယနေ့", -"yesterday" => "မနေ့က", -"_%n day go_::_%n days ago_" => array(""), -"last month" => "ပြီးခဲ့သောလ", -"_%n month ago_::_%n months ago_" => array(""), -"last year" => "မနှစ်က", -"years ago" => "နှစ် အရင်က", -"Could not find category \"%s\"" => "\"%s\"ခေါင်းစဉ်ကို ရှာမတွေ့ပါ" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/nb_NO.php b/lib/private/l10n/nb_NO.php deleted file mode 100644 index 8e7d095d369..00000000000 --- a/lib/private/l10n/nb_NO.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Hjelp", -"Personal" => "Personlig", -"Settings" => "Innstillinger", -"Users" => "Brukere", -"Admin" => "Admin", -"web services under your control" => "web tjenester du kontrollerer", -"ZIP download is turned off." => "ZIP-nedlasting av avslått", -"Files need to be downloaded one by one." => "Filene må lastes ned en om gangen", -"Back to Files" => "Tilbake til filer", -"Selected files too large to generate zip file." => "De valgte filene er for store til å kunne generere ZIP-fil", -"Application is not enabled" => "Applikasjon er ikke påslått", -"Authentication error" => "Autentikasjonsfeil", -"Token expired. Please reload page." => "Symbol utløpt. Vennligst last inn siden på nytt.", -"Files" => "Filer", -"Text" => "Tekst", -"Images" => "Bilder", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Din nettservev er ikke konfigurert korrekt for filsynkronisering. WebDAV ser ut til å ikke funkere.", -"Please double check the <a href='%s'>installation guides</a>." => "Vennligst dobbelsjekk <a href='%s'>installasjonsguiden</a>.", -"seconds ago" => "sekunder siden", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "i dag", -"yesterday" => "i går", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "forrige måned", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "forrige år", -"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/private/l10n/ne.php b/lib/private/l10n/ne.php deleted file mode 100644 index 15f78e0bce6..00000000000 --- a/lib/private/l10n/ne.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/nl.php b/lib/private/l10n/nl.php deleted file mode 100644 index 20374f1f0f8..00000000000 --- a/lib/private/l10n/nl.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "App \"%s\" kan niet worden geïnstalleerd omdat die niet compatible is met deze versie van ownCloud.", -"No app name specified" => "De app naam is niet gespecificeerd.", -"Help" => "Help", -"Personal" => "Persoonlijk", -"Settings" => "Instellingen", -"Users" => "Gebruikers", -"Admin" => "Beheerder", -"Failed to upgrade \"%s\"." => "Upgrade \"%s\" mislukt.", -"Custom profile pictures don't work with encryption yet" => "Maatwerk profielafbeelding werkt nog niet met versleuteling", -"Unknown filetype" => "Onbekend bestandsformaat", -"Invalid image" => "Ongeldige afbeelding", -"web services under your control" => "Webdiensten in eigen beheer", -"cannot open \"%s\"" => "Kon \"%s\" niet openen", -"ZIP download is turned off." => "ZIP download is uitgeschakeld.", -"Files need to be downloaded one by one." => "Bestanden moeten één voor één worden gedownload.", -"Back to Files" => "Terug naar bestanden", -"Selected files too large to generate zip file." => "De geselecteerde bestanden zijn te groot om een zip bestand te maken.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Download de bestanden in kleinere brokken, appart of vraag uw administrator.", -"No source specified when installing app" => "Geen bron opgegeven bij installatie van de app", -"No href specified when installing app from http" => "Geen href opgegeven bij installeren van de app vanaf http", -"No path specified when installing app from local file" => "Geen pad opgegeven bij installeren van de app vanaf een lokaal bestand", -"Archives of type %s are not supported" => "Archiefbestanden van type %s niet ondersteund", -"Failed to open archive when installing app" => "Kon archiefbestand bij installatie van de app niet openen", -"App does not provide an info.xml file" => "De app heeft geen info.xml bestand", -"App can't be installed because of not allowed code in the App" => "De app kan niet worden geïnstalleerd wegens onjuiste code in de app", -"App can't be installed because it is not compatible with this version of ownCloud" => "De app kan niet worden geïnstalleerd omdat die niet compatible is met deze versie van ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "De app kan niet worden geïnstallerd omdat het de <shipped>true</shipped> tag bevat die niet is toegestaan voor niet gepubliceerde apps", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "De app kan niet worden geïnstalleerd omdat de versie in info.xml/version niet dezelfde is als de versie zoals die in de app store staat vermeld", -"App directory already exists" => "App directory bestaat al", -"Can't create app folder. Please fix permissions. %s" => "Kan de app map niet aanmaken, Herstel de permissies. %s", -"Application is not enabled" => "De applicatie is niet actief", -"Authentication error" => "Authenticatie fout", -"Token expired. Please reload page." => "Token verlopen. Herlaad de pagina.", -"Files" => "Bestanden", -"Text" => "Tekst", -"Images" => "Afbeeldingen", -"%s enter the database username." => "%s opgeven database gebruikersnaam.", -"%s enter the database name." => "%s opgeven databasenaam.", -"%s you may not use dots in the database name" => "%s er mogen geen puntjes in de databasenaam voorkomen", -"MS SQL username and/or password not valid: %s" => "MS SQL gebruikersnaam en/of wachtwoord niet geldig: %s", -"You need to enter either an existing account or the administrator." => "Geef of een bestaand account op of het beheerdersaccount.", -"MySQL username and/or password not valid" => "MySQL gebruikersnaam en/of wachtwoord ongeldig", -"DB Error: \"%s\"" => "DB Fout: \"%s\"", -"Offending command was: \"%s\"" => "Onjuiste commande was: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL gebruiker '%s'@'localhost' bestaat al.", -"Drop this user from MySQL" => "Verwijder deze gebruiker uit MySQL", -"MySQL user '%s'@'%%' already exists" => "MySQL gebruiker '%s'@'%%' bestaat al", -"Drop this user from MySQL." => "Verwijder deze gebruiker uit MySQL.", -"Oracle connection could not be established" => "Er kon geen verbinding met Oracle worden bereikt", -"Oracle username and/or password not valid" => "Oracle gebruikersnaam en/of wachtwoord ongeldig", -"Offending command was: \"%s\", name: %s, password: %s" => "Onjuiste commando was: \"%s\", naam: %s, wachtwoord: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL gebruikersnaam en/of wachtwoord ongeldig", -"Set an admin username." => "Stel de gebruikersnaam van de beheerder in.", -"Set an admin password." => "Stel een beheerderswachtwoord in.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Uw webserver is nog niet goed ingesteld voor bestandssynchronisatie omdat de WebDAV interface verbroken lijkt.", -"Please double check the <a href='%s'>installation guides</a>." => "Controleer de <a href='%s'>installatiehandleiding</a> goed.", -"seconds ago" => "seconden geleden", -"_%n minute ago_::_%n minutes ago_" => array("%n minuut geleden","%n minuten geleden"), -"_%n hour ago_::_%n hours ago_" => array("%n uur geleden","%n uur geleden"), -"today" => "vandaag", -"yesterday" => "gisteren", -"_%n day go_::_%n days ago_" => array("%n dag terug","%n dagen geleden"), -"last month" => "vorige maand", -"_%n month ago_::_%n months ago_" => array("%n maand geleden","%n maanden geleden"), -"last year" => "vorig jaar", -"years ago" => "jaar geleden", -"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/private/l10n/nn_NO.php b/lib/private/l10n/nn_NO.php deleted file mode 100644 index e8bf8dfdef4..00000000000 --- a/lib/private/l10n/nn_NO.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Hjelp", -"Personal" => "Personleg", -"Settings" => "Innstillingar", -"Users" => "Brukarar", -"Admin" => "Administrer", -"Unknown filetype" => "Ukjend filtype", -"Invalid image" => "Ugyldig bilete", -"web services under your control" => "Vev tjenester under din kontroll", -"Authentication error" => "Feil i autentisering", -"Files" => "Filer", -"Text" => "Tekst", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Tenaren din er ikkje enno rett innstilt til å tilby filsynkronisering sidan WebDAV-grensesnittet ser ut til å vera øydelagt.", -"Please double check the <a href='%s'>installation guides</a>." => "Ver venleg og dobbeltsjekk <a href='%s'>installasjonsrettleiinga</a>.", -"seconds ago" => "sekund sidan", -"_%n minute ago_::_%n minutes ago_" => array("","%n minutt sidan"), -"_%n hour ago_::_%n hours ago_" => array("","%n timar sidan"), -"today" => "i dag", -"yesterday" => "i går", -"_%n day go_::_%n days ago_" => array("","%n dagar sidan"), -"last month" => "førre månad", -"_%n month ago_::_%n months ago_" => array("","%n månadar sidan"), -"last year" => "i fjor", -"years ago" => "år sidan" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/nqo.php b/lib/private/l10n/nqo.php deleted file mode 100644 index e7b09649a24..00000000000 --- a/lib/private/l10n/nqo.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"_%n day go_::_%n days ago_" => array(""), -"_%n month ago_::_%n months ago_" => array("") -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/oc.php b/lib/private/l10n/oc.php deleted file mode 100644 index 40a527cc76c..00000000000 --- a/lib/private/l10n/oc.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Ajuda", -"Personal" => "Personal", -"Settings" => "Configuracion", -"Users" => "Usancièrs", -"Admin" => "Admin", -"web services under your control" => "Services web jos ton contraròtle", -"ZIP download is turned off." => "Avalcargar los ZIP es inactiu.", -"Files need to be downloaded one by one." => "Los fichièrs devan èsser avalcargats un per un.", -"Back to Files" => "Torna cap als fichièrs", -"Authentication error" => "Error d'autentificacion", -"Files" => "Fichièrs", -"seconds ago" => "segonda a", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "uèi", -"yesterday" => "ièr", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "mes passat", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "an passat", -"years ago" => "ans a" -); -$PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/lib/private/l10n/pa.php b/lib/private/l10n/pa.php deleted file mode 100644 index 069fea6e710..00000000000 --- a/lib/private/l10n/pa.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Settings" => "ਸੈਟਿੰਗ", -"Files" => "ਫਾਇਲਾਂ", -"seconds ago" => "ਸਕਿੰਟ ਪਹਿਲਾਂ", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "ਅੱਜ", -"yesterday" => "ਕੱਲ੍ਹ", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "ਪਿਛਲੇ ਮਹੀਨੇ", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "ਪਿਛਲੇ ਸਾਲ", -"years ago" => "ਸਾਲਾਂ ਪਹਿਲਾਂ" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/pl.php b/lib/private/l10n/pl.php deleted file mode 100644 index 270559b4e50..00000000000 --- a/lib/private/l10n/pl.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Aplikacja \"%s\" nie może zostać zainstalowana, ponieważ nie jest zgodna z tą wersją ownCloud.", -"No app name specified" => "Nie określono nazwy aplikacji", -"Help" => "Pomoc", -"Personal" => "Osobiste", -"Settings" => "Ustawienia", -"Users" => "Użytkownicy", -"Admin" => "Administrator", -"Failed to upgrade \"%s\"." => "Błąd przy aktualizacji \"%s\".", -"Custom profile pictures don't work with encryption yet" => "Domyślny profil zdjęć nie działa z szyfrowaniem jeszcze", -"Unknown filetype" => "Nieznany typ pliku", -"Invalid image" => "Błędne zdjęcie", -"web services under your control" => "Kontrolowane serwisy", -"cannot open \"%s\"" => "Nie można otworzyć \"%s\"", -"ZIP download is turned off." => "Pobieranie ZIP jest wyłączone.", -"Files need to be downloaded one by one." => "Pliki muszą zostać pobrane pojedynczo.", -"Back to Files" => "Wróć do plików", -"Selected files too large to generate zip file." => "Wybrane pliki są zbyt duże, aby wygenerować plik zip.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Pobierz pliki w mniejszy kawałkach, oddzielnie lub poproś administratora o zwiększenie limitu.", -"No source specified when installing app" => "Nie określono źródła podczas instalacji aplikacji", -"No href specified when installing app from http" => "Nie określono linku skąd aplikacja ma być zainstalowana", -"No path specified when installing app from local file" => "Nie określono lokalnego pliku z którego miała być instalowana aplikacja", -"Archives of type %s are not supported" => "Typ archiwum %s nie jest obsługiwany", -"Failed to open archive when installing app" => "Nie udało się otworzyć archiwum podczas instalacji aplikacji", -"App does not provide an info.xml file" => "Aplikacja nie posiada pliku info.xml", -"App can't be installed because of not allowed code in the App" => "Aplikacja nie może być zainstalowany ponieważ nie dopuszcza kod w aplikacji", -"App can't be installed because it is not compatible with this version of ownCloud" => "Aplikacja nie może zostać zainstalowana ponieważ jest niekompatybilna z tą wersja ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Aplikacja nie może być zainstalowana ponieważ true tag nie jest <shipped>true</shipped> , co nie jest dozwolone dla aplikacji nie wysłanych", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Nie można zainstalować aplikacji, ponieważ w wersji info.xml/version nie jest taka sama, jak wersja z app store", -"App directory already exists" => "Katalog aplikacji już isnieje", -"Can't create app folder. Please fix permissions. %s" => "Nie mogę utworzyć katalogu aplikacji. Proszę popraw uprawnienia. %s", -"Application is not enabled" => "Aplikacja nie jest włączona", -"Authentication error" => "Błąd uwierzytelniania", -"Token expired. Please reload page." => "Token wygasł. Proszę ponownie załadować stronę.", -"Files" => "Pliki", -"Text" => "Połączenie tekstowe", -"Images" => "Obrazy", -"%s enter the database username." => "%s wpisz nazwę użytkownika do bazy", -"%s enter the database name." => "%s wpisz nazwę bazy.", -"%s you may not use dots in the database name" => "%s nie można używać kropki w nazwie bazy danych", -"MS SQL username and/or password not valid: %s" => "Nazwa i/lub hasło serwera MS SQL jest niepoprawne: %s.", -"You need to enter either an existing account or the administrator." => "Należy wprowadzić istniejące konto użytkownika lub administratora.", -"MySQL username and/or password not valid" => "MySQL: Nazwa użytkownika i/lub hasło jest niepoprawne", -"DB Error: \"%s\"" => "Błąd DB: \"%s\"", -"Offending command was: \"%s\"" => "Niepoprawna komenda: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Użytkownik MySQL '%s'@'localhost' już istnieje", -"Drop this user from MySQL" => "Usuń tego użytkownika z MySQL", -"MySQL user '%s'@'%%' already exists" => "Użytkownik MySQL '%s'@'%%t' już istnieje", -"Drop this user from MySQL." => "Usuń tego użytkownika z MySQL.", -"Oracle connection could not be established" => "Nie można ustanowić połączenia z bazą Oracle", -"Oracle username and/or password not valid" => "Oracle: Nazwa użytkownika i/lub hasło jest niepoprawne", -"Offending command was: \"%s\", name: %s, password: %s" => "Niepoprawne polecania: \"%s\", nazwa: %s, hasło: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL: Nazwa użytkownika i/lub hasło jest niepoprawne", -"Set an admin username." => "Ustaw nazwę administratora.", -"Set an admin password." => "Ustaw hasło administratora.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Serwer internetowy nie jest jeszcze poprawnie skonfigurowany, aby umożliwić synchronizację plików, ponieważ interfejs WebDAV wydaje się być uszkodzony.", -"Please double check the <a href='%s'>installation guides</a>." => "Sprawdź ponownie <a href='%s'>przewodniki instalacji</a>.", -"Could not find category \"%s\"" => "Nie można odnaleźć kategorii \"%s\"", -"seconds ago" => "sekund temu", -"_%n minute ago_::_%n minutes ago_" => array("%n minute temu","%n minut temu","%n minut temu"), -"_%n hour ago_::_%n hours ago_" => array("%n godzinę temu","%n godzin temu","%n godzin temu"), -"today" => "dziś", -"yesterday" => "wczoraj", -"_%n day go_::_%n days ago_" => array("%n dzień temu","%n dni temu","%n dni temu"), -"last month" => "w zeszłym miesiącu", -"_%n month ago_::_%n months ago_" => array("%n miesiąc temu","%n miesięcy temu","%n miesięcy temu"), -"last year" => "w zeszłym roku", -"years ago" => "lat temu", -"Caused by:" => "Spowodowane przez:" -); -$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/private/l10n/pl_PL.php b/lib/private/l10n/pl_PL.php deleted file mode 100644 index 5494e3dab25..00000000000 --- a/lib/private/l10n/pl_PL.php +++ /dev/null @@ -1,5 +0,0 @@ -<?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/private/l10n/pt_BR.php b/lib/private/l10n/pt_BR.php deleted file mode 100644 index 7a580799701..00000000000 --- a/lib/private/l10n/pt_BR.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "O aplicativo \"%s\" não pode ser instalado porque não é compatível com esta versão do ownCloud.", -"No app name specified" => "O nome do aplicativo não foi especificado.", -"Help" => "Ajuda", -"Personal" => "Pessoal", -"Settings" => "Ajustes", -"Users" => "Usuários", -"Admin" => "Admin", -"Failed to upgrade \"%s\"." => "Falha na atualização de \"%s\".", -"Custom profile pictures don't work with encryption yet" => "Fotos de perfil personalizados ainda não funcionam com criptografia", -"Unknown filetype" => "Tipo de arquivo desconhecido", -"Invalid image" => "Imagem inválida", -"web services under your control" => "serviços web sob seu controle", -"cannot open \"%s\"" => "não pode abrir \"%s\"", -"ZIP download is turned off." => "Download ZIP está desligado.", -"Files need to be downloaded one by one." => "Arquivos precisam ser baixados um de cada vez.", -"Back to Files" => "Voltar para Arquivos", -"Selected files too large to generate zip file." => "Arquivos selecionados são muito grandes para gerar arquivo zip.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Baixe os arquivos em pedaços menores, separadamente ou solicite educadamente ao seu administrador.", -"No source specified when installing app" => "Nenhuma fonte foi especificada enquanto instalava o aplicativo", -"No href specified when installing app from http" => "Nenhuma href foi especificada enquanto instalava o aplicativo de httml", -"No path specified when installing app from local file" => "Nenhum caminho foi especificado enquanto instalava o aplicativo do arquivo local", -"Archives of type %s are not supported" => "Arquivos do tipo %s não são suportados", -"Failed to open archive when installing app" => "Falha para abrir o arquivo enquanto instalava o aplicativo", -"App does not provide an info.xml file" => "O aplicativo não fornece um arquivo info.xml", -"App can't be installed because of not allowed code in the App" => "O aplicativo não pode ser instalado por causa do código não permitido no Aplivativo", -"App can't be installed because it is not compatible with this version of ownCloud" => "O aplicativo não pode ser instalado porque não é compatível com esta versão do ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "O aplicativo não pode ser instalado porque ele contém a marca <shipped>verdadeiro</shipped> que não é permitido para aplicações não embarcadas", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "O aplicativo não pode ser instalado porque a versão em info.xml /versão não é a mesma que a versão relatada na App Store", -"App directory already exists" => "Diretório App já existe", -"Can't create app folder. Please fix permissions. %s" => "Não é possível criar pasta app. Corrija as permissões. %s", -"Application is not enabled" => "Aplicação não está habilitada", -"Authentication error" => "Erro de autenticação", -"Token expired. Please reload page." => "Token expirou. Por favor recarregue a página.", -"Files" => "Arquivos", -"Text" => "Texto", -"Images" => "Imagens", -"%s enter the database username." => "%s insira o nome de usuário do banco de dados.", -"%s enter the database name." => "%s insira o nome do banco de dados.", -"%s you may not use dots in the database name" => "%s você não pode usar pontos no nome do banco de dados", -"MS SQL username and/or password not valid: %s" => "Nome de usuário e/ou senha MS SQL inválido(s): %s", -"You need to enter either an existing account or the administrator." => "Você precisa inserir uma conta existente ou o administrador.", -"MySQL username and/or password not valid" => "Nome de usuário e/ou senha MySQL inválido(s)", -"DB Error: \"%s\"" => "Erro no BD: \"%s\"", -"Offending command was: \"%s\"" => "Comando ofensivo era: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "O usuário MySQL '%s'@'localhost' já existe.", -"Drop this user from MySQL" => "Derrubar este usuário do MySQL", -"MySQL user '%s'@'%%' already exists" => "Usuário MySQL '%s'@'%%' já existe", -"Drop this user from MySQL." => "Derrube este usuário do MySQL.", -"Oracle connection could not be established" => "Conexão Oracle não pode ser estabelecida", -"Oracle username and/or password not valid" => "Nome de usuário e/ou senha Oracle inválido(s)", -"Offending command was: \"%s\", name: %s, password: %s" => "Comando ofensivo era: \"%s\", nome: %s, senha: %s", -"PostgreSQL username and/or password not valid" => "Nome de usuário e/ou senha PostgreSQL inválido(s)", -"Set an admin username." => "Defina um nome de usuário de administrador.", -"Set an admin password." => "Defina uma senha de administrador.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Seu servidor web não está configurado corretamente para permitir sincronização de arquivos porque a interface WebDAV parece estar quebrada.", -"Please double check the <a href='%s'>installation guides</a>." => "Por favor, confira os <a href='%s'>guias de instalação</a>.", -"seconds ago" => "segundos atrás", -"_%n minute ago_::_%n minutes ago_" => array("","ha %n minutos"), -"_%n hour ago_::_%n hours ago_" => array("","ha %n horas"), -"today" => "hoje", -"yesterday" => "ontem", -"_%n day go_::_%n days ago_" => array("","ha %n dias"), -"last month" => "último mês", -"_%n month ago_::_%n months ago_" => array("","ha %n meses"), -"last year" => "último ano", -"years ago" => "anos atrás", -"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/private/l10n/pt_PT.php b/lib/private/l10n/pt_PT.php deleted file mode 100644 index 6e2bcba7b10..00000000000 --- a/lib/private/l10n/pt_PT.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Ajuda", -"Personal" => "Pessoal", -"Settings" => "Configurações", -"Users" => "Utilizadores", -"Admin" => "Admin", -"Failed to upgrade \"%s\"." => "A actualização \"%s\" falhou.", -"Unknown filetype" => "Ficheiro desconhecido", -"Invalid image" => "Imagem inválida", -"web services under your control" => "serviços web sob o seu controlo", -"cannot open \"%s\"" => "Não foi possível abrir \"%s\"", -"ZIP download is turned off." => "Descarregamento em ZIP está desligado.", -"Files need to be downloaded one by one." => "Os ficheiros precisam de ser descarregados um por um.", -"Back to Files" => "Voltar a Ficheiros", -"Selected files too large to generate zip file." => "Os ficheiros seleccionados são grandes demais para gerar um ficheiro zip.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Descarregue os ficheiros em partes menores, separados ou peça gentilmente ao seu administrador.", -"Application is not enabled" => "A aplicação não está activada", -"Authentication error" => "Erro na autenticação", -"Token expired. Please reload page." => "O token expirou. Por favor recarregue a página.", -"Files" => "Ficheiros", -"Text" => "Texto", -"Images" => "Imagens", -"%s enter the database username." => "%s introduza o nome de utilizador da base de dados", -"%s enter the database name." => "%s introduza o nome da base de dados", -"%s you may not use dots in the database name" => "%s não é permitido utilizar pontos (.) no nome da base de dados", -"MS SQL username and/or password not valid: %s" => "Nome de utilizador/password do MySQL é inválido: %s", -"You need to enter either an existing account or the administrator." => "Precisa de introduzir uma conta existente ou de administrador", -"MySQL username and/or password not valid" => "Nome de utilizador/password do MySQL inválida", -"DB Error: \"%s\"" => "Erro na BD: \"%s\"", -"Offending command was: \"%s\"" => "O comando gerador de erro foi: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "O utilizador '%s'@'localhost' do MySQL já existe.", -"Drop this user from MySQL" => "Eliminar este utilizador do MySQL", -"MySQL user '%s'@'%%' already exists" => "O utilizador '%s'@'%%' do MySQL já existe", -"Drop this user from MySQL." => "Eliminar este utilizador do MySQL", -"Oracle connection could not be established" => "Não foi possível estabelecer a ligação Oracle", -"Oracle username and/or password not valid" => "Nome de utilizador/password do Oracle inválida", -"Offending command was: \"%s\", name: %s, password: %s" => "O comando gerador de erro foi: \"%s\", nome: %s, password: %s", -"PostgreSQL username and/or password not valid" => "Nome de utilizador/password do PostgreSQL inválido", -"Set an admin username." => "Definir um nome de utilizador de administrador", -"Set an admin password." => "Definiar uma password de administrador", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "O seu servidor web não está configurado correctamente para autorizar sincronização de ficheiros, pois o interface WebDAV parece estar com problemas.", -"Please double check the <a href='%s'>installation guides</a>." => "Por favor verifique <a href='%s'>installation guides</a>.", -"seconds ago" => "Minutos atrás", -"_%n minute ago_::_%n minutes ago_" => array("","%n minutos atrás"), -"_%n hour ago_::_%n hours ago_" => array("","%n horas atrás"), -"today" => "hoje", -"yesterday" => "ontem", -"_%n day go_::_%n days ago_" => array("","%n dias atrás"), -"last month" => "ultímo mês", -"_%n month ago_::_%n months ago_" => array("","%n meses atrás"), -"last year" => "ano passado", -"years ago" => "anos atrás", -"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/private/l10n/ro.php b/lib/private/l10n/ro.php deleted file mode 100644 index 76dafcd03e0..00000000000 --- a/lib/private/l10n/ro.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Ajutor", -"Personal" => "Personal", -"Settings" => "Setări", -"Users" => "Utilizatori", -"Admin" => "Admin", -"Unknown filetype" => "Tip fișier necunoscut", -"Invalid image" => "Imagine invalidă", -"web services under your control" => "servicii web controlate de tine", -"ZIP download is turned off." => "Descărcarea ZIP este dezactivată.", -"Files need to be downloaded one by one." => "Fișierele trebuie descărcate unul câte unul.", -"Back to Files" => "Înapoi la fișiere", -"Selected files too large to generate zip file." => "Fișierele selectate sunt prea mari pentru a genera un fișier zip.", -"Application is not enabled" => "Aplicația nu este activată", -"Authentication error" => "Eroare la autentificare", -"Token expired. Please reload page." => "Token expirat. Te rugăm să reîncarci pagina.", -"Files" => "Fișiere", -"Text" => "Text", -"Images" => "Imagini", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Serverul de web nu este încă setat corespunzător pentru a permite sincronizarea fișierelor deoarece interfața WebDAV pare a fi întreruptă.", -"Please double check the <a href='%s'>installation guides</a>." => "Vă rugăm să verificați <a href='%s'>ghiduri de instalare</a>.", -"seconds ago" => "secunde în urmă", -"_%n minute ago_::_%n minutes ago_" => array("","","acum %n minute"), -"_%n hour ago_::_%n hours ago_" => array("","","acum %n ore"), -"today" => "astăzi", -"yesterday" => "ieri", -"_%n day go_::_%n days ago_" => array("","","acum %n zile"), -"last month" => "ultima lună", -"_%n month ago_::_%n months ago_" => array("","",""), -"last year" => "ultimul an", -"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/private/l10n/ru.php b/lib/private/l10n/ru.php deleted file mode 100644 index 501065f8b5f..00000000000 --- a/lib/private/l10n/ru.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Приложение \"%s\" нельзя установить, так как оно не совместимо с текущей версией ownCloud.", -"No app name specified" => "Не выбрано имя приложения", -"Help" => "Помощь", -"Personal" => "Личное", -"Settings" => "Конфигурация", -"Users" => "Пользователи", -"Admin" => "Admin", -"Failed to upgrade \"%s\"." => "Не смог обновить \"%s\".", -"Custom profile pictures don't work with encryption yet" => "Пользовательские картинки профиля ещё не поддерживают шифрование", -"Unknown filetype" => "Неизвестный тип файла", -"Invalid image" => "Изображение повреждено", -"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." => "Загрузите файл маленьшими порциями, раздельно или вежливо попросите Вашего администратора.", -"No source specified when installing app" => "Не указан источник при установке приложения", -"No href specified when installing app from http" => "Не указан атрибут href при установке приложения через http", -"No path specified when installing app from local file" => "Не указан путь при установке приложения из локального файла", -"Archives of type %s are not supported" => "Архивы %s не поддерживаются", -"Failed to open archive when installing app" => "Не возможно открыть архив при установке приложения", -"App does not provide an info.xml file" => "Приложение не имеет файла info.xml", -"App can't be installed because of not allowed code in the App" => "Приложение невозможно установить. В нем содержится запрещенный код.", -"App can't be installed because it is not compatible with this version of ownCloud" => "Приложение невозможно установить. Не совместимо с текущей версией ownCloud.", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Приложение невозможно установить. Оно содержит параметр <shipped>true</shipped> который не допустим для приложений, не входящих в поставку.", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Приложение невозможно установить. Версия в info.xml/version не совпадает с версией заявленной в магазине приложений", -"App directory already exists" => "Папка приложения уже существует", -"Can't create app folder. Please fix permissions. %s" => "Не удалось создать директорию. Исправьте права доступа. %s", -"Application is not enabled" => "Приложение не разрешено", -"Authentication error" => "Ошибка аутентификации", -"Token expired. Please reload page." => "Токен просрочен. Перезагрузите страницу.", -"Files" => "Файлы", -"Text" => "Текст", -"Images" => "Изображения", -"%s enter the database username." => "%s введите имя пользователя базы данных.", -"%s enter the database name." => "%s введите имя базы данных.", -"%s you may not use dots in the database name" => "%s Вы не можете использовать точки в имени базы данных", -"MS SQL username and/or password not valid: %s" => "Имя пользователя и/или пароль MS SQL не подходит: %s", -"You need to enter either an existing account or the administrator." => "Вы должны войти или в существующий аккаунт или под администратором.", -"MySQL username and/or password not valid" => "Неверное имя пользователя и/или пароль MySQL", -"DB Error: \"%s\"" => "Ошибка БД: \"%s\"", -"Offending command was: \"%s\"" => "Вызываемая команда была: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Пользователь MySQL '%s'@'localhost' уже существует.", -"Drop this user from MySQL" => "Удалить этого пользователя из MySQL", -"MySQL user '%s'@'%%' already exists" => "Пользователь MySQL '%s'@'%%' уже существует", -"Drop this user from MySQL." => "Удалить этого пользователя из MySQL.", -"Oracle connection could not be established" => "соединение с Oracle не может быть установлено", -"Oracle username and/or password not valid" => "Неверное имя пользователя и/или пароль Oracle", -"Offending command was: \"%s\", name: %s, password: %s" => "Вызываемая команда была: \"%s\", имя: %s, пароль: %s", -"PostgreSQL username and/or password not valid" => "Неверное имя пользователя и/или пароль PostgreSQL", -"Set an admin username." => "Установить имя пользователя для admin.", -"Set an admin password." => "становит пароль для admin.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Ваш веб сервер до сих пор не настроен правильно для возможности синхронизации файлов, похоже что проблема в неисправности интерфейса WebDAV.", -"Please double check the <a href='%s'>installation guides</a>." => "Пожалуйста, дважды просмотрите <a href='%s'>инструкции по установке</a>.", -"seconds ago" => "несколько секунд назад", -"_%n minute ago_::_%n minutes ago_" => array("%n минута назад","%n минуты назад","%n минут назад"), -"_%n hour ago_::_%n hours ago_" => array("%n час назад","%n часа назад","%n часов назад"), -"today" => "сегодня", -"yesterday" => "вчера", -"_%n day go_::_%n days ago_" => array("%n день назад","%n дня назад","%n дней назад"), -"last month" => "в прошлом месяце", -"_%n month ago_::_%n months ago_" => array("%n месяц назад","%n месяца назад","%n месяцев назад"), -"last year" => "в прошлом году", -"years ago" => "несколько лет назад", -"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/private/l10n/si_LK.php b/lib/private/l10n/si_LK.php deleted file mode 100644 index d10804cae69..00000000000 --- a/lib/private/l10n/si_LK.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "උදව්", -"Personal" => "පෞද්ගලික", -"Settings" => "සිටුවම්", -"Users" => "පරිශීලකයන්", -"Admin" => "පරිපාලක", -"web services under your control" => "ඔබට පාලනය කළ හැකි වෙබ් සේවාවන්", -"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 ගොනුවක් තැනීමට විශාල වැඩිය.", -"Application is not enabled" => "යෙදුම සක්රිය කර නොමැත", -"Authentication error" => "සත්යාපන දෝෂයක්", -"Token expired. Please reload page." => "ටෝකනය කල් ඉකුත් වී ඇත. පිටුව නැවුම් කරන්න", -"Files" => "ගොනු", -"Text" => "පෙළ", -"Images" => "අනු රූ", -"seconds ago" => "තත්පරයන්ට පෙර", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "අද", -"yesterday" => "ඊයේ", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "පෙර මාසයේ", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "පෙර අවුරුද්දේ", -"years ago" => "අවුරුදු කීපයකට පෙර" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/sk.php b/lib/private/l10n/sk.php deleted file mode 100644 index 54812b15a6f..00000000000 --- a/lib/private/l10n/sk.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("","",""), -"_%n hour ago_::_%n hours ago_" => array("","",""), -"_%n day go_::_%n days ago_" => array("","",""), -"_%n month ago_::_%n months ago_" => array("","","") -); -$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/lib/private/l10n/sk_SK.php b/lib/private/l10n/sk_SK.php deleted file mode 100644 index 13487b039d6..00000000000 --- a/lib/private/l10n/sk_SK.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Aplikácia \"%s\" nemôže byť nainštalovaná kvôli nekompatibilite z danou verziou ownCloudu.", -"No app name specified" => "Nešpecifikované meno aplikácie", -"Help" => "Pomoc", -"Personal" => "Osobné", -"Settings" => "Nastavenia", -"Users" => "Používatelia", -"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.", -"No source specified when installing app" => "Nešpecifikovaný zdroj pri inštalácii aplikácie", -"No href specified when installing app from http" => "Nešpecifikovaný atribút \"href\" pri inštalácii aplikácie pomocou protokolu \"http\"", -"No path specified when installing app from local file" => "Nešpecifikovaná cesta pri inštalácii aplikácie z lokálneho súboru", -"Archives of type %s are not supported" => "Typ archívu %s nie je podporovaný", -"Failed to open archive when installing app" => "Zlyhanie pri otváraní archívu počas inštalácie aplikácie", -"App does not provide an info.xml file" => "Aplikácia neposkytuje súbor info.xml", -"App can't be installed because of not allowed code in the App" => "Aplikácia nemôže byť inštalovaná pre nepovolený kód v aplikácii", -"App can't be installed because it is not compatible with this version of ownCloud" => "Aplikácia nemôže byť inštalovaná pre nekompatibilitu z danou verziou ownCloudu", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Aplikácia nemôže byť inštalovaná pretože obsahuje <shipped>pravý</shipped> štítok, ktorý nie je povolený pre zaslané \"shipped\" aplikácie", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Aplikácia nemôže byť inštalovaná pretože verzia v info.xml/version nezodpovedá verzii špecifikovanej v aplikačnom obchode", -"App directory already exists" => "Aplikačný adresár už existuje", -"Can't create app folder. Please fix permissions. %s" => "Nemožno vytvoriť aplikačný priečinok. Prosím upravte povolenia. %s", -"Application is not enabled" => "Aplikácia nie je zapnutá", -"Authentication error" => "Chyba autentifikácie", -"Token expired. Please reload page." => "Token vypršal. Obnovte, prosím, stránku.", -"Files" => "Súbory", -"Text" => "Text", -"Images" => "Obrázky", -"%s enter the database username." => "Zadajte používateľské meno %s databázy..", -"%s enter the database name." => "Zadajte názov databázy pre %s databázy.", -"%s you may not use dots in the database name" => "V názve databázy %s nemôžete používať bodky", -"MS SQL username and/or password not valid: %s" => "Používateľské meno, alebo heslo MS SQL nie je platné: %s", -"You need to enter either an existing account or the administrator." => "Musíte zadať jestvujúci účet alebo administrátora.", -"MySQL username and/or password not valid" => "Používateľské meno a/alebo heslo pre MySQL databázu je neplatné", -"DB Error: \"%s\"" => "Chyba DB: \"%s\"", -"Offending command was: \"%s\"" => "Podozrivý príkaz bol: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Používateľ '%s'@'localhost' už v MySQL existuje.", -"Drop this user from MySQL" => "Zahodiť používateľa z MySQL.", -"MySQL user '%s'@'%%' already exists" => "Používateľ '%s'@'%%' už v MySQL existuje", -"Drop this user from MySQL." => "Zahodiť používateľa z MySQL.", -"Oracle connection could not be established" => "Nie je možné pripojiť sa k Oracle", -"Oracle username and/or password not valid" => "Používateľské meno a/alebo heslo pre Oracle databázu je neplatné", -"Offending command was: \"%s\", name: %s, password: %s" => "Podozrivý príkaz bol: \"%s\", meno: %s, heslo: %s", -"PostgreSQL username and/or password not valid" => "Používateľské meno a/alebo heslo pre PostgreSQL databázu je neplatné", -"Set an admin username." => "Zadajte používateľské meno administrátora.", -"Set an admin password." => "Zadajte heslo administrátora.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Váš webový server nie je správne nastavený na synchronizáciu, pretože rozhranie WebDAV je poškodené.", -"Please double check the <a href='%s'>installation guides</a>." => "Prosím skontrolujte <a href='%s'>inštalačnú príručku</a>.", -"seconds ago" => "pred sekundami", -"_%n minute ago_::_%n minutes ago_" => array("","","pred %n minútami"), -"_%n hour ago_::_%n hours ago_" => array("","","pred %n hodinami"), -"today" => "dnes", -"yesterday" => "včera", -"_%n day go_::_%n days ago_" => array("","","pred %n dňami"), -"last month" => "minulý mesiac", -"_%n month ago_::_%n months ago_" => array("","","pred %n 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/private/l10n/sl.php b/lib/private/l10n/sl.php deleted file mode 100644 index 5722191aedf..00000000000 --- a/lib/private/l10n/sl.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Pomoč", -"Personal" => "Osebno", -"Settings" => "Nastavitve", -"Users" => "Uporabniki", -"Admin" => "Skrbništvo", -"web services under your control" => "spletne storitve pod vašim nadzorom", -"ZIP download is turned off." => "Prejemanje datotek v paketu ZIP je onemogočeno.", -"Files need to be downloaded one by one." => "Datoteke je mogoče prejeti le posamično.", -"Back to Files" => "Nazaj na datoteke", -"Selected files too large to generate zip file." => "Izbrane datoteke so prevelike za ustvarjanje datoteke arhiva zip.", -"Application is not enabled" => "Program ni omogočen", -"Authentication error" => "Napaka pri overjanju", -"Token expired. Please reload page." => "Žeton je potekel. Stran je treba ponovno naložiti.", -"Files" => "Datoteke", -"Text" => "Besedilo", -"Images" => "Slike", -"%s enter the database username." => "%s - vnos uporabniškega imena podatkovne zbirke.", -"%s enter the database name." => "%s - vnos imena podatkovne zbirke.", -"%s you may not use dots in the database name" => "%s - v imenu podatkovne zbirke ni dovoljeno uporabljati pik.", -"MS SQL username and/or password not valid: %s" => "Uporabniško ime ali geslo MS SQL ni veljavno: %s", -"You need to enter either an existing account or the administrator." => "Prijaviti se je treba v obstoječi ali pa skrbniški račun.", -"MySQL username and/or password not valid" => "Uporabniško ime ali geslo MySQL ni veljavno", -"DB Error: \"%s\"" => "Napaka podatkovne zbirke: \"%s\"", -"Offending command was: \"%s\"" => "Napačni ukaz je: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Uporabnik MySQL '%s'@'localhost' že obstaja.", -"Drop this user from MySQL" => "Odstrani uporabnika s podatkovne zbirke MySQL", -"MySQL user '%s'@'%%' already exists" => "Uporabnik MySQL '%s'@'%%' že obstaja.", -"Drop this user from MySQL." => "Odstrani uporabnika s podatkovne zbirke MySQL", -"Oracle connection could not be established" => "Povezava z bazo Oracle ni uspela.", -"Oracle username and/or password not valid" => "Uporabniško ime ali geslo Oracle ni veljavno", -"Offending command was: \"%s\", name: %s, password: %s" => "Napačni ukaz je: \"%s\", ime: %s, geslo: %s", -"PostgreSQL username and/or password not valid" => "Uporabniško ime ali geslo PostgreSQL ni veljavno", -"Set an admin username." => "Nastavi uporabniško ime skrbnika.", -"Set an admin password." => "Nastavi geslo skrbnika.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Spletni stražnik še ni ustrezno nastavljen in ne omogoča usklajevanja, saj je nastavitev WebDAV okvarjena.", -"Please double check the <a href='%s'>installation guides</a>." => "Preverite <a href='%s'>navodila namestitve</a>.", -"seconds ago" => "pred nekaj sekundami", -"_%n minute ago_::_%n minutes ago_" => array("","","",""), -"_%n hour ago_::_%n hours ago_" => array("","","",""), -"today" => "danes", -"yesterday" => "včeraj", -"_%n day go_::_%n days ago_" => array("","","",""), -"last month" => "zadnji mesec", -"_%n month ago_::_%n months ago_" => array("","","",""), -"last year" => "lansko leto", -"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/private/l10n/sq.php b/lib/private/l10n/sq.php deleted file mode 100644 index edaa1df2b86..00000000000 --- a/lib/private/l10n/sq.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Ndihmë", -"Personal" => "Personale", -"Settings" => "Parametra", -"Users" => "Përdoruesit", -"Admin" => "Admin", -"web services under your control" => "shërbime web nën kontrollin tënd", -"ZIP download is turned off." => "Shkarimi i skedarëve ZIP është i çaktivizuar.", -"Files need to be downloaded one by one." => "Skedarët duhet të shkarkohen një nga një.", -"Back to Files" => "Kthehu tek skedarët", -"Selected files too large to generate zip file." => "Skedarët e selektuar janë shumë të mëdhenj për të krijuar një skedar ZIP.", -"Application is not enabled" => "Programi nuk është i aktivizuar.", -"Authentication error" => "Veprim i gabuar gjatë vërtetimit të identitetit", -"Token expired. Please reload page." => "Përmbajtja ka skaduar. Ju lutemi ringarkoni faqen.", -"Files" => "Skedarët", -"Text" => "Tekst", -"Images" => "Foto", -"%s enter the database username." => "% shkruani përdoruesin e database-it.", -"%s enter the database name." => "%s shkruani emrin e database-it.", -"%s you may not use dots in the database name" => "%s nuk mund të përdorni pikat tek emri i database-it", -"MS SQL username and/or password not valid: %s" => "Përdoruesi dhe/apo kodi i MS SQL i pavlefshëm: %s", -"You need to enter either an existing account or the administrator." => "Duhet të përdorni një llogari ekzistuese ose llogarinë e administratorit.", -"MySQL username and/or password not valid" => "Përdoruesi dhe/apo kodi i MySQL-it i pavlefshëm.", -"DB Error: \"%s\"" => "Veprim i gabuar i DB-it: \"%s\"", -"Offending command was: \"%s\"" => "Komanda e gabuar ishte: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Përdoruesi MySQL '%s'@'localhost' ekziston.", -"Drop this user from MySQL" => "Eliminoni këtë përdorues nga MySQL", -"MySQL user '%s'@'%%' already exists" => "Përdoruesi MySQL '%s'@'%%' ekziston", -"Drop this user from MySQL." => "Eliminoni këtë përdorues nga MySQL.", -"Oracle username and/or password not valid" => "Përdoruesi dhe/apo kodi i Oracle-it i pavlefshëm", -"Offending command was: \"%s\", name: %s, password: %s" => "Komanda e gabuar ishte: \"%s\", përdoruesi: %s, kodi: %s", -"PostgreSQL username and/or password not valid" => "Përdoruesi dhe/apo kodi i PostgreSQL i pavlefshëm", -"Set an admin username." => "Cakto emrin e administratorit.", -"Set an admin password." => "Cakto kodin e administratorit.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Serveri web i juaji nuk është konfiguruar akoma për të lejuar sinkronizimin e skedarëve sepse ndërfaqja WebDAV mund të jetë e dëmtuar.", -"Please double check the <a href='%s'>installation guides</a>." => "Ju lutemi kontrolloni mirë <a href='%s'>shoqëruesin e instalimit</a>.", -"seconds ago" => "sekonda më parë", -"_%n minute ago_::_%n minutes ago_" => array("","%n minuta më parë"), -"_%n hour ago_::_%n hours ago_" => array("","%n orë më parë"), -"today" => "sot", -"yesterday" => "dje", -"_%n day go_::_%n days ago_" => array("","%n ditë më parë"), -"last month" => "muajin e shkuar", -"_%n month ago_::_%n months ago_" => array("","%n muaj më parë"), -"last year" => "vitin e shkuar", -"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/private/l10n/sr.php b/lib/private/l10n/sr.php deleted file mode 100644 index 9441d0578fc..00000000000 --- a/lib/private/l10n/sr.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Помоћ", -"Personal" => "Лично", -"Settings" => "Поставке", -"Users" => "Корисници", -"Admin" => "Администратор", -"web services under your control" => "веб сервиси под контролом", -"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 датотеку.", -"Application is not enabled" => "Апликација није омогућена", -"Authentication error" => "Грешка при провери идентитета", -"Token expired. Please reload page." => "Жетон је истекао. Поново учитајте страницу.", -"Files" => "Датотеке", -"Text" => "Текст", -"Images" => "Слике", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Ваш веб сервер тренутно не подржава синхронизацију датотека јер се чини да је WebDAV сучеље неисправно.", -"Please double check the <a href='%s'>installation guides</a>." => "Погледајте <a href='%s'>водиче за инсталацију</a>.", -"seconds ago" => "пре неколико секунди", -"_%n minute ago_::_%n minutes ago_" => array("","",""), -"_%n hour ago_::_%n hours ago_" => array("","",""), -"today" => "данас", -"yesterday" => "јуче", -"_%n day go_::_%n days ago_" => array("","",""), -"last month" => "прошлог месеца", -"_%n month ago_::_%n months ago_" => array("","",""), -"last year" => "прошле године", -"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/private/l10n/sr@latin.php b/lib/private/l10n/sr@latin.php deleted file mode 100644 index d8fa9289221..00000000000 --- a/lib/private/l10n/sr@latin.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Pomoć", -"Personal" => "Lično", -"Settings" => "Podešavanja", -"Users" => "Korisnici", -"Admin" => "Adninistracija", -"Authentication error" => "Greška pri autentifikaciji", -"Files" => "Fajlovi", -"Text" => "Tekst", -"seconds ago" => "Pre par sekundi", -"_%n minute ago_::_%n minutes ago_" => array("","",""), -"_%n hour ago_::_%n hours ago_" => array("","",""), -"today" => "Danas", -"yesterday" => "juče", -"_%n day go_::_%n days ago_" => array("","",""), -"last month" => "prošlog meseca", -"_%n month ago_::_%n months ago_" => array("","",""), -"last year" => "prošle godine", -"years ago" => "pre nekoliko 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/private/l10n/sv.php b/lib/private/l10n/sv.php deleted file mode 100644 index e7c3420a85b..00000000000 --- a/lib/private/l10n/sv.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Appen \"%s\" kan inte installeras eftersom att den inte är kompatibel med denna version av ownCloud.", -"No app name specified" => "Inget appnamn angivet", -"Help" => "Hjälp", -"Personal" => "Personligt", -"Settings" => "Inställningar", -"Users" => "Användare", -"Admin" => "Admin", -"Failed to upgrade \"%s\"." => "Misslyckades med att uppgradera \"%s\".", -"web services under your control" => "webbtjänster under din kontroll", -"cannot open \"%s\"" => "Kan inte öppna \"%s\"", -"ZIP download is turned off." => "Nerladdning av ZIP är avstängd.", -"Files need to be downloaded one by one." => "Filer laddas ner en åt gången.", -"Back to Files" => "Tillbaka till Filer", -"Selected files too large to generate zip file." => "Valda filer är för stora för att skapa zip-fil.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Ladda ner filerna i mindre bitar, separat eller fråga din administratör.", -"No source specified when installing app" => "Ingen källa angiven vid installation av app ", -"No href specified when installing app from http" => "Ingen href angiven vid installation av app från http", -"No path specified when installing app from local file" => "Ingen sökväg angiven vid installation av app från lokal fil", -"Archives of type %s are not supported" => "Arkiv av typen %s stöds ej", -"Failed to open archive when installing app" => "Kunde inte öppna arkivet när appen skulle installeras", -"App does not provide an info.xml file" => "Appen har ingen info.xml fil", -"App can't be installed because of not allowed code in the App" => "Appen kan inte installeras eftersom att den innehåller otillåten kod", -"App can't be installed because it is not compatible with this version of ownCloud" => "Appen kan inte installeras eftersom att den inte är kompatibel med denna version av ownCloud", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Appen kan inte installeras eftersom att den innehåller etiketten <shipped>true</shipped> vilket inte är tillåtet för icke inkluderade appar", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Appen kan inte installeras eftersom versionen i info.xml inte är samma som rapporteras från app store", -"App directory already exists" => "Appens mapp finns redan", -"Can't create app folder. Please fix permissions. %s" => "Kan inte skapa appens mapp. Var god åtgärda rättigheterna. %s", -"Application is not enabled" => "Applikationen är inte aktiverad", -"Authentication error" => "Fel vid autentisering", -"Token expired. Please reload page." => "Ogiltig token. Ladda om sidan.", -"Files" => "Filer", -"Text" => "Text", -"Images" => "Bilder", -"%s enter the database username." => "%s ange databasanvändare.", -"%s enter the database name." => "%s ange databasnamn", -"%s you may not use dots in the database name" => "%s du får inte använda punkter i databasnamnet", -"MS SQL username and/or password not valid: %s" => "MS SQL-användaren och/eller lösenordet var inte giltigt: %s", -"You need to enter either an existing account or the administrator." => "Du måste antingen ange ett befintligt konto eller administratör.", -"MySQL username and/or password not valid" => "MySQL-användarnamnet och/eller lösenordet är felaktigt", -"DB Error: \"%s\"" => "DB error: \"%s\"", -"Offending command was: \"%s\"" => "Det felaktiga kommandot var: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL-användaren '%s'@'localhost' existerar redan.", -"Drop this user from MySQL" => "Radera denna användare från MySQL", -"MySQL user '%s'@'%%' already exists" => "MySQl-användare '%s'@'%%' existerar redan", -"Drop this user from MySQL." => "Radera denna användare från MySQL.", -"Oracle connection could not be established" => "Oracle-anslutning kunde inte etableras", -"Oracle username and/or password not valid" => "Oracle-användarnamnet och/eller lösenordet är felaktigt", -"Offending command was: \"%s\", name: %s, password: %s" => "Det felande kommandot var: \"%s\", name: %s, password: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL-användarnamnet och/eller lösenordet är felaktigt", -"Set an admin username." => "Ange ett användarnamn för administratören.", -"Set an admin password." => "Ange ett administratörslösenord.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Din webbserver är inte korrekt konfigurerad för att tillåta filsynkronisering eftersom WebDAV inte verkar fungera.", -"Please double check the <a href='%s'>installation guides</a>." => "Var god kontrollera <a href='%s'>installationsguiden</a>.", -"seconds ago" => "sekunder sedan", -"_%n minute ago_::_%n minutes ago_" => array("%n minut sedan","%n minuter sedan"), -"_%n hour ago_::_%n hours ago_" => array("%n timme sedan","%n timmar sedan"), -"today" => "i dag", -"yesterday" => "i går", -"_%n day go_::_%n days ago_" => array("%n dag sedan","%n dagar sedan"), -"last month" => "förra månaden", -"_%n month ago_::_%n months ago_" => array("%n månad sedan","%n månader sedan"), -"last year" => "förra året", -"years ago" => "år sedan", -"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/private/l10n/sw_KE.php b/lib/private/l10n/sw_KE.php deleted file mode 100644 index 15f78e0bce6..00000000000 --- a/lib/private/l10n/sw_KE.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/ta_LK.php b/lib/private/l10n/ta_LK.php deleted file mode 100644 index e70e65845be..00000000000 --- a/lib/private/l10n/ta_LK.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "உதவி", -"Personal" => "தனிப்பட்ட", -"Settings" => "அமைப்புகள்", -"Users" => "பயனாளர்", -"Admin" => "நிர்வாகம்", -"web services under your control" => "வலைய சேவைகள் உங்களுடைய கட்டுப்பாட்டின் கீழ் உள்ளது", -"ZIP download is turned off." => "வீசொலிப் பூட்டு பதிவிறக்கம் நிறுத்தப்பட்டுள்ளது.", -"Files need to be downloaded one by one." => "கோப்புகள்ஒன்றன் பின் ஒன்றாக பதிவிறக்கப்படவேண்டும்.", -"Back to Files" => "கோப்புகளுக்கு செல்க", -"Selected files too large to generate zip file." => "வீ சொலிக் கோப்புகளை உருவாக்குவதற்கு தெரிவுசெய்யப்பட்ட கோப்புகள் மிகப்பெரியவை", -"Application is not enabled" => "செயலி இயலுமைப்படுத்தப்படவில்லை", -"Authentication error" => "அத்தாட்சிப்படுத்தலில் வழு", -"Token expired. Please reload page." => "அடையாளவில்லை காலாவதியாகிவிட்டது. தயவுசெய்து பக்கத்தை மீள் ஏற்றுக.", -"Files" => "கோப்புகள்", -"Text" => "உரை", -"Images" => "படங்கள்", -"seconds ago" => "செக்கன்களுக்கு முன்", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "இன்று", -"yesterday" => "நேற்று", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "கடந்த மாதம்", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "கடந்த வருடம்", -"years ago" => "வருடங்களுக்கு முன்", -"Could not find category \"%s\"" => "பிரிவு \"%s\" ஐ கண்டுப்பிடிக்க முடியவில்லை" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/te.php b/lib/private/l10n/te.php deleted file mode 100644 index 524ea0c6024..00000000000 --- a/lib/private/l10n/te.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "సహాయం", -"Settings" => "అమరికలు", -"Users" => "వాడుకరులు", -"seconds ago" => "క్షణాల క్రితం", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"today" => "ఈరోజు", -"yesterday" => "నిన్న", -"_%n day go_::_%n days ago_" => array("",""), -"last month" => "పోయిన నెల", -"_%n month ago_::_%n months ago_" => array("",""), -"last year" => "పోయిన సంవత్సరం", -"years ago" => "సంవత్సరాల క్రితం" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/th_TH.php b/lib/private/l10n/th_TH.php deleted file mode 100644 index 3344d0bb18e..00000000000 --- a/lib/private/l10n/th_TH.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "ช่วยเหลือ", -"Personal" => "ส่วนตัว", -"Settings" => "ตั้งค่า", -"Users" => "ผู้ใช้งาน", -"Admin" => "ผู้ดูแล", -"web services under your control" => "เว็บเซอร์วิสที่คุณควบคุมการใช้งานได้", -"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", -"Application is not enabled" => "แอพพลิเคชั่นดังกล่าวยังไม่ได้เปิดใช้งาน", -"Authentication error" => "เกิดข้อผิดพลาดในสิทธิ์การเข้าใช้งาน", -"Token expired. Please reload page." => "รหัสยืนยันความถูกต้องหมดอายุแล้ว กรุณาโหลดหน้าเว็บใหม่อีกครั้ง", -"Files" => "ไฟล์", -"Text" => "ข้อความ", -"Images" => "รูปภาพ", -"seconds ago" => "วินาที ก่อนหน้านี้", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "วันนี้", -"yesterday" => "เมื่อวานนี้", -"_%n day go_::_%n days ago_" => array(""), -"last month" => "เดือนที่แล้ว", -"_%n month ago_::_%n months ago_" => array(""), -"last year" => "ปีที่แล้ว", -"years ago" => "ปี ที่ผ่านมา", -"Could not find category \"%s\"" => "ไม่พบหมวดหมู่ \"%s\"" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/tr.php b/lib/private/l10n/tr.php deleted file mode 100644 index b63c37c7240..00000000000 --- a/lib/private/l10n/tr.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Owncloud yazılımının bu sürümü ile uyumlu olmadığı için \"%s\" uygulaması kurulamaz.", -"No app name specified" => "Uygulama adı belirtimedli", -"Help" => "Yardım", -"Personal" => "Kişisel", -"Settings" => "Ayarlar", -"Users" => "Kullanıcılar", -"Admin" => "Yönetici", -"Failed to upgrade \"%s\"." => "\"%s\" yükseltme başarısız oldu.", -"web services under your control" => "Bilgileriniz güvenli ve şifreli", -"cannot open \"%s\"" => "\"%s\" açılamıyor", -"ZIP download is turned off." => "ZIP indirmeleri kapatılmıştır.", -"Files need to be downloaded one by one." => "Dosyaların birer birer indirilmesi gerekmektedir.", -"Back to Files" => "Dosyalara dön", -"Selected files too large to generate zip file." => "Seçilen dosyalar bir zip dosyası oluşturmak için fazla büyüktür.", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Dosyaları ayrı ayrı, küçük parçalar halinde indirin ya da yöneticinizden yardım isteyin. ", -"No source specified when installing app" => "Uygulama kurulurken bir kaynak belirtilmedi", -"No href specified when installing app from http" => "Uygulama kuruluyorken http'de href belirtilmedi.", -"No path specified when installing app from local file" => "Uygulama yerel dosyadan kuruluyorken dosya yolu belirtilmedi", -"Archives of type %s are not supported" => "%s arşiv tipi desteklenmiyor", -"Failed to open archive when installing app" => "Uygulama kuruluyorken arşiv dosyası açılamadı", -"App does not provide an info.xml file" => "Uygulama info.xml dosyası sağlamıyor", -"App can't be installed because of not allowed code in the App" => "Uygulamada izin verilmeyeden kodlar olduğu için kurulamıyor.", -"App can't be installed because it is not compatible with this version of ownCloud" => "Owncloud versiyonunuz ile uyumsuz olduğu için uygulama kurulamıyor.", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Uygulama kurulamıyor. Çünkü \"non shipped\" uygulamalar için <shipped>true</shipped> tag içermektedir.", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Uygulama kurulamıyor çünkü info.xml/version ile uygulama marketde belirtilen sürüm aynı değil.", -"App directory already exists" => "App dizini zaten mevcut", -"Can't create app folder. Please fix permissions. %s" => "app dizini oluşturulamıyor. Lütfen izinleri düzeltin. %s", -"Application is not enabled" => "Uygulama etkinleştirilmedi", -"Authentication error" => "Kimlik doğrulama hatası", -"Token expired. Please reload page." => "Jetonun süresi geçti. Lütfen sayfayı yenileyin.", -"Files" => "Dosyalar", -"Text" => "Metin", -"Images" => "Resimler", -"%s enter the database username." => "%s veritabanı kullanıcı adını gir.", -"%s enter the database name." => "%s veritabanı adını gir.", -"%s you may not use dots in the database name" => "%s veritabanı adında nokta kullanamayabilirsiniz", -"MS SQL username and/or password not valid: %s" => "MS SQL kullanıcı adı ve/veya parolası geçersiz: %s", -"You need to enter either an existing account or the administrator." => "Bir konto veya kullanici birlemek ihtiyacin. ", -"MySQL username and/or password not valid" => "MySQL kullanıcı adı ve/veya parolası geçerli değil", -"DB Error: \"%s\"" => "DB Hata: ''%s''", -"Offending command was: \"%s\"" => "Komut rahasiz ''%s''. ", -"MySQL user '%s'@'localhost' exists already." => "MySQL kullanici '%s @local host zatan var. ", -"Drop this user from MySQL" => "Bu kullanici MySQLden list disari koymak. ", -"MySQL user '%s'@'%%' already exists" => "MySQL kullanici '%s @ % % zaten var (zaten yazili)", -"Drop this user from MySQL." => "Bu kulanıcıyı MySQL veritabanından kaldır", -"Oracle connection could not be established" => "Oracle bağlantısı kurulamadı", -"Oracle username and/or password not valid" => "Adi klullanici ve/veya parola Oracle mantikli değildir. ", -"Offending command was: \"%s\", name: %s, password: %s" => "Hatalı komut: \"%s\", ad: %s, parola: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL adi kullanici ve/veya parola yasal degildir. ", -"Set an admin username." => "Bir adi kullanici vermek. ", -"Set an admin password." => "Parola yonetici birlemek. ", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Web sunucunuz dosya transferi için düzgün bir şekilde yapılandırılmamış. WevDAV arabirimini sorunlu gözüküyor.", -"Please double check the <a href='%s'>installation guides</a>." => "Lütfen <a href='%s'>kurulum kılavuzlarını</a> iki kez kontrol edin.", -"seconds ago" => "saniye önce", -"_%n minute ago_::_%n minutes ago_" => array("","%n dakika önce"), -"_%n hour ago_::_%n hours ago_" => array("","%n saat önce"), -"today" => "bugün", -"yesterday" => "dün", -"_%n day go_::_%n days ago_" => array("","%n gün önce"), -"last month" => "geçen ay", -"_%n month ago_::_%n months ago_" => array("","%n ay önce"), -"last year" => "geçen yıl", -"years ago" => "yıl önce", -"Caused by:" => "Neden olan:", -"Could not find category \"%s\"" => "\"%s\" kategorisi bulunamadı" -); -$PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/lib/private/l10n/ug.php b/lib/private/l10n/ug.php deleted file mode 100644 index e2cf38ecc8c..00000000000 --- a/lib/private/l10n/ug.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "ياردەم", -"Personal" => "شەخسىي", -"Settings" => "تەڭشەكلەر", -"Users" => "ئىشلەتكۈچىلەر", -"Authentication error" => "سالاھىيەت دەلىللەش خاتالىقى", -"Files" => "ھۆججەتلەر", -"Text" => "قىسقا ئۇچۇر", -"Images" => "سۈرەتلەر", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "سىزنىڭ تور مۇلازىمېتىرىڭىز ھۆججەت قەدەمداشلاشقا يول قويىدىغان قىلىپ توغرا تەڭشەلمەپتۇ، چۈنكى WebDAV نىڭ ئېغىزى بۇزۇلغاندەك تۇرىدۇ.", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "بۈگۈن", -"yesterday" => "تۈنۈگۈن", -"_%n day go_::_%n days ago_" => array(""), -"_%n month ago_::_%n months ago_" => array("") -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/uk.php b/lib/private/l10n/uk.php deleted file mode 100644 index c1513c5bb79..00000000000 --- a/lib/private/l10n/uk.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Допомога", -"Personal" => "Особисте", -"Settings" => "Налаштування", -"Users" => "Користувачі", -"Admin" => "Адмін", -"web services under your control" => "підконтрольні Вам веб-сервіси", -"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 файлу.", -"Application is not enabled" => "Додаток не увімкнений", -"Authentication error" => "Помилка автентифікації", -"Token expired. Please reload page." => "Строк дії токена скінчився. Будь ласка, перезавантажте сторінку.", -"Files" => "Файли", -"Text" => "Текст", -"Images" => "Зображення", -"%s enter the database username." => "%s введіть ім'я користувача бази даних.", -"%s enter the database name." => "%s введіть назву бази даних.", -"%s you may not use dots in the database name" => "%s не можна використовувати крапки в назві бази даних", -"MS SQL username and/or password not valid: %s" => "MS SQL ім'я користувача та/або пароль не дійсні: %s", -"You need to enter either an existing account or the administrator." => "Вам потрібно ввести або існуючий обліковий запис або administrator.", -"MySQL username and/or password not valid" => "MySQL ім'я користувача та/або пароль не дійсні", -"DB Error: \"%s\"" => "Помилка БД: \"%s\"", -"Offending command was: \"%s\"" => "Команда, що викликала проблему: \"%s\"", -"MySQL user '%s'@'localhost' exists already." => "Користувач MySQL '%s'@'localhost' вже існує.", -"Drop this user from MySQL" => "Видалити цього користувача з MySQL", -"MySQL user '%s'@'%%' already exists" => "Користувач MySQL '%s'@'%%' вже існує", -"Drop this user from MySQL." => "Видалити цього користувача з MySQL.", -"Oracle username and/or password not valid" => "Oracle ім'я користувача та/або пароль не дійсні", -"Offending command was: \"%s\", name: %s, password: %s" => "Команда, що викликала проблему: \"%s\", ім'я: %s, пароль: %s", -"PostgreSQL username and/or password not valid" => "PostgreSQL ім'я користувача та/або пароль не дійсні", -"Set an admin username." => "Встановіть ім'я адміністратора.", -"Set an admin password." => "Встановіть пароль адміністратора.", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Ваш Web-сервер ще не налаштований належним чином для того, щоб дозволити синхронізацію файлів, через те що інтерфейс WebDAV, здається, зламаний.", -"Please double check the <a href='%s'>installation guides</a>." => "Будь ласка, перевірте <a href='%s'>інструкції по встановленню</a>.", -"seconds ago" => "секунди тому", -"_%n minute ago_::_%n minutes ago_" => array("","",""), -"_%n hour ago_::_%n hours ago_" => array("","",""), -"today" => "сьогодні", -"yesterday" => "вчора", -"_%n day go_::_%n days ago_" => array("","",""), -"last month" => "минулого місяця", -"_%n month ago_::_%n months ago_" => array("","",""), -"last year" => "минулого року", -"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/private/l10n/ur_PK.php b/lib/private/l10n/ur_PK.php deleted file mode 100644 index 7dc967ccd93..00000000000 --- a/lib/private/l10n/ur_PK.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "مدد", -"Personal" => "ذاتی", -"Settings" => "سیٹینگز", -"Users" => "یوزرز", -"Admin" => "ایڈمن", -"web services under your control" => "آپ کے اختیار میں ویب سروسیز", -"_%n minute ago_::_%n minutes ago_" => array("",""), -"_%n hour ago_::_%n hours ago_" => array("",""), -"_%n day go_::_%n days ago_" => array("",""), -"_%n month ago_::_%n months ago_" => array("","") -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/private/l10n/vi.php b/lib/private/l10n/vi.php deleted file mode 100644 index dc0045c35ca..00000000000 --- a/lib/private/l10n/vi.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "Giúp đỡ", -"Personal" => "Cá nhân", -"Settings" => "Cài đặt", -"Users" => "Người dùng", -"Admin" => "Quản trị", -"web services under your control" => "dịch vụ web dưới sự kiểm soát của bạn", -"ZIP download is turned off." => "Tải về ZIP đã bị tắt.", -"Files need to be downloaded one by one." => "Tập tin cần phải được tải về từng người một.", -"Back to Files" => "Trở lại tập tin", -"Selected files too large to generate zip file." => "Tập tin được chọn quá lớn để tạo tập tin ZIP.", -"Application is not enabled" => "Ứng dụng không được BẬT", -"Authentication error" => "Lỗi xác thực", -"Token expired. Please reload page." => "Mã Token đã hết hạn. Hãy tải lại trang.", -"Files" => "Tập tin", -"Text" => "Văn bản", -"Images" => "Hình ảnh", -"seconds ago" => "vài giây trước", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "hôm nay", -"yesterday" => "hôm qua", -"_%n day go_::_%n days ago_" => array(""), -"last month" => "tháng trước", -"_%n month ago_::_%n months ago_" => array(""), -"last year" => "năm trước", -"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/private/l10n/zh_CN.php b/lib/private/l10n/zh_CN.php deleted file mode 100644 index 2c34356ea10..00000000000 --- a/lib/private/l10n/zh_CN.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "帮助", -"Personal" => "个人", -"Settings" => "设置", -"Users" => "用户", -"Admin" => "管理", -"web services under your control" => "您控制的web服务", -"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 文件。", -"App does not provide an info.xml file" => "应用未提供 info.xml 文件", -"Application is not enabled" => "应用程序未启用", -"Authentication error" => "认证出错", -"Token expired. Please reload page." => "Token 过期,请刷新页面。", -"Files" => "文件", -"Text" => "文本", -"Images" => "图片", -"%s enter the database username." => "%s 输入数据库用户名。", -"%s enter the database name." => "%s 输入数据库名称。", -"%s you may not use dots in the database name" => "%s 您不能在数据库名称中使用英文句号。", -"MS SQL username and/or password not valid: %s" => "MS SQL 用户名和/或密码无效:%s", -"You need to enter either an existing account or the administrator." => "你需要输入一个数据库中已有的账户或管理员账户。", -"MySQL username and/or password not valid" => "MySQL 数据库用户名和/或密码无效", -"DB Error: \"%s\"" => "数据库错误:\"%s\"", -"Offending command was: \"%s\"" => "冲突命令为:\"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL 用户 '%s'@'localhost' 已存在。", -"Drop this user from MySQL" => "建议从 MySQL 数据库中丢弃 Drop 此用户", -"MySQL user '%s'@'%%' already exists" => "MySQL 用户 '%s'@'%%' 已存在", -"Drop this user from MySQL." => "建议从 MySQL 数据库中丢弃 Drop 此用户。", -"Oracle connection could not be established" => "不能建立甲骨文连接", -"Oracle username and/or password not valid" => "Oracle 数据库用户名和/或密码无效", -"Offending command was: \"%s\", name: %s, password: %s" => "冲突命令为:\"%s\",名称:%s,密码:%s", -"PostgreSQL username and/or password not valid" => "PostgreSQL 数据库用户名和/或密码无效", -"Set an admin username." => "请设置一个管理员用户名。", -"Set an admin password." => "请设置一个管理员密码。", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "您的Web服务器尚未正确设置以允许文件同步, 因为WebDAV的接口似乎已损坏.", -"Please double check the <a href='%s'>installation guides</a>." => "请认真检查<a href='%s'>安装指南</a>.", -"seconds ago" => "秒前", -"_%n minute ago_::_%n minutes ago_" => array("%n 分钟前"), -"_%n hour ago_::_%n hours ago_" => array("%n 小时前"), -"today" => "今天", -"yesterday" => "昨天", -"_%n day go_::_%n days ago_" => array("%n 天前"), -"last month" => "上月", -"_%n month ago_::_%n months ago_" => array("%n 月前"), -"last year" => "去年", -"years ago" => "年前", -"Could not find category \"%s\"" => "无法找到分类 \"%s\"" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/zh_HK.php b/lib/private/l10n/zh_HK.php deleted file mode 100644 index ca3e6d504e7..00000000000 --- a/lib/private/l10n/zh_HK.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "幫助", -"Personal" => "個人", -"Settings" => "設定", -"Users" => "用戶", -"Admin" => "管理", -"Files" => "文件", -"Text" => "文字", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "今日", -"yesterday" => "昨日", -"_%n day go_::_%n days ago_" => array(""), -"last month" => "前一月", -"_%n month ago_::_%n months ago_" => array("") -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/l10n/zh_TW.php b/lib/private/l10n/zh_TW.php deleted file mode 100644 index 210c766aa59..00000000000 --- a/lib/private/l10n/zh_TW.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -$TRANSLATIONS = array( -"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "無法安裝應用程式 %s 因為它和此版本的 ownCloud 不相容。", -"No app name specified" => "沒有指定應用程式名稱", -"Help" => "說明", -"Personal" => "個人", -"Settings" => "設定", -"Users" => "使用者", -"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." => "選擇的檔案太大以致於無法產生壓縮檔。", -"Download the files in smaller chunks, seperately or kindly ask your administrator." => "以小分割下載您的檔案,請詢問您的系統管理員。", -"No source specified when installing app" => "沒有指定應用程式安裝來源", -"No href specified when installing app from http" => "從 http 安裝應用程式,找不到 href 屬性", -"No path specified when installing app from local file" => "從本地檔案安裝應用程式時沒有指定路徑", -"Archives of type %s are not supported" => "不支援 %s 格式的壓縮檔", -"Failed to open archive when installing app" => "安裝應用程式時無法開啓壓縮檔", -"App does not provide an info.xml file" => "應用程式沒有提供 info.xml 檔案", -"App can't be installed because of not allowed code in the App" => "無法安裝應用程式因為在當中找到危險的代碼", -"App can't be installed because it is not compatible with this version of ownCloud" => "無法安裝應用程式因為它和此版本的 ownCloud 不相容。", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "無法安裝應用程式,因為它包含了 <shipped>true</shipped> 標籤,在未發行的應用程式當中這是不允許的", -"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "無法安裝應用程式,因為它在 info.xml/version 宣告的版本與 app store 當中記載的版本不同", -"App directory already exists" => "應用程式目錄已經存在", -"Can't create app folder. Please fix permissions. %s" => "無法建立應用程式目錄,請檢查權限:%s", -"Application is not enabled" => "應用程式未啟用", -"Authentication error" => "認證錯誤", -"Token expired. Please reload page." => "Token 過期,請重新整理頁面。", -"Files" => "檔案", -"Text" => "文字", -"Images" => "圖片", -"%s enter the database username." => "%s 輸入資料庫使用者名稱。", -"%s enter the database name." => "%s 輸入資料庫名稱。", -"%s you may not use dots in the database name" => "%s 資料庫名稱不能包含小數點", -"MS SQL username and/or password not valid: %s" => "MS SQL 使用者和/或密碼無效:%s", -"You need to enter either an existing account or the administrator." => "您必須輸入一個現有的帳號或管理員帳號。", -"MySQL username and/or password not valid" => "MySQL 用戶名和/或密碼無效", -"DB Error: \"%s\"" => "資料庫錯誤:\"%s\"", -"Offending command was: \"%s\"" => "有問題的指令是:\"%s\"", -"MySQL user '%s'@'localhost' exists already." => "MySQL 使用者 '%s'@'localhost' 已經存在。", -"Drop this user from MySQL" => "在 MySQL 移除這個使用者", -"MySQL user '%s'@'%%' already exists" => "MySQL 使用者 '%s'@'%%' 已經存在", -"Drop this user from MySQL." => "在 MySQL 移除這個使用者。", -"Oracle connection could not be established" => "無法建立 Oracle 資料庫連線", -"Oracle username and/or password not valid" => "Oracle 用戶名和/或密碼無效", -"Offending command was: \"%s\", name: %s, password: %s" => "有問題的指令是:\"%s\" ,使用者:\"%s\",密碼:\"%s\"", -"PostgreSQL username and/or password not valid" => "PostgreSQL 用戶名和/或密碼無效", -"Set an admin username." => "設定管理員帳號。", -"Set an admin password." => "設定管理員密碼。", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "您的網頁伺服器尚未被正確設定來進行檔案同步,因為您的 WebDAV 界面似乎無法使用。", -"Please double check the <a href='%s'>installation guides</a>." => "請參考<a href='%s'>安裝指南</a>。", -"seconds ago" => "幾秒前", -"_%n minute ago_::_%n minutes ago_" => array("%n 分鐘前"), -"_%n hour ago_::_%n hours ago_" => array("%n 小時前"), -"today" => "今天", -"yesterday" => "昨天", -"_%n day go_::_%n days ago_" => array("%n 天前"), -"last month" => "上個月", -"_%n month ago_::_%n months ago_" => array("%n 個月前"), -"last year" => "去年", -"years ago" => "幾年前", -"Caused by:" => "原因:", -"Could not find category \"%s\"" => "找不到分類:\"%s\"" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/legacy/appconfig.php b/lib/private/legacy/appconfig.php index 0ca6d4150ef..46a8068c3b4 100644 --- a/lib/private/legacy/appconfig.php +++ b/lib/private/legacy/appconfig.php @@ -25,9 +25,14 @@ * This class provides an easy way for apps to store config values in the * database. */ -OC_Appconfig::$object = new \OC\AppConfig(OC_DB::getConnection()); -class OC_Appconfig{ - public static $object; +class OC_Appconfig { + /** + * @return \OCP\IAppConfig + */ + private static function getAppConfig() { + return \OC::$server->getAppConfig(); + } + /** * @brief Get all apps using the config * @return array with app ids @@ -36,7 +41,7 @@ class OC_Appconfig{ * entry in the appconfig table. */ public static function getApps() { - return self::$object->getApps(); + return self::getAppConfig()->getApps(); } /** @@ -47,8 +52,8 @@ class OC_Appconfig{ * This function gets all keys of an app. Please note that the values are * not returned. */ - public static function getKeys( $app ) { - return self::$object->getKeys( $app ); + public static function getKeys($app) { + return self::getAppConfig()->getKeys($app); } /** @@ -61,8 +66,8 @@ class OC_Appconfig{ * This function gets a value from the appconfig table. If the key does * not exist the default value will be returned */ - public static function getValue( $app, $key, $default = null ) { - return self::$object->getValue($app, $key, $default); + public static function getValue($app, $key, $default = null) { + return self::getAppConfig()->getValue($app, $key, $default); } /** @@ -72,7 +77,7 @@ class OC_Appconfig{ * @return bool */ public static function hasKey($app, $key) { - return self::$object->hasKey($app, $key); + return self::getAppConfig()->hasKey($app, $key); } /** @@ -83,8 +88,8 @@ class OC_Appconfig{ * * Sets a value. If the key did not exist before it will be created. */ - public static function setValue( $app, $key, $value ) { - self::$object->setValue( $app, $key, $value ); + public static function setValue($app, $key, $value) { + self::getAppConfig()->setValue($app, $key, $value); } /** @@ -94,8 +99,8 @@ class OC_Appconfig{ * * Deletes a key. */ - public static function deleteKey( $app, $key ) { - self::$object->deleteKey( $app, $key ); + public static function deleteKey($app, $key) { + self::getAppConfig()->deleteKey($app, $key); } /** @@ -104,17 +109,18 @@ class OC_Appconfig{ * * Removes all keys in appconfig belonging to the app. */ - public static function deleteApp( $app ) { - self::$object->deleteApp( $app ); + public static function deleteApp($app) { + self::getAppConfig()->deleteApp($app); } /** * get multiply values, either the app or key can be used as wildcard by setting it to false + * * @param app * @param key * @return array */ public static function getValues($app, $key) { - return self::$object->getValues($app, $key); + return self::getAppConfig()->getValues($app, $key); } } diff --git a/lib/private/legacy/cache/fileglobalgc.php b/lib/private/legacy/cache/fileglobalgc.php new file mode 100644 index 00000000000..385f6406673 --- /dev/null +++ b/lib/private/legacy/cache/fileglobalgc.php @@ -0,0 +1,4 @@ +<?php + +class OC_Cache_FileGlobalGC extends OC\Cache\FileGlobalGC{ +} diff --git a/lib/private/legacy/config.php b/lib/private/legacy/config.php index 7e498013737..ab67c8d3020 100644 --- a/lib/private/legacy/config.php +++ b/lib/private/legacy/config.php @@ -38,7 +38,6 @@ * This class is responsible for reading and writing config.php, the very basic * configuration file of ownCloud. */ -OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/'); class OC_Config { /** @@ -83,11 +82,7 @@ class OC_Config { * */ public static function setValue($key, $value) { - try { - self::$object->setValue($key, $value); - } catch (\OC\HintException $e) { - \OC_Template::printErrorPage($e->getMessage(), $e->getHint()); - } + self::$object->setValue($key, $value); } /** @@ -98,10 +93,6 @@ class OC_Config { * */ public static function deleteKey($key) { - try { - self::$object->deleteKey($key); - } catch (\OC\HintException $e) { - \OC_Template::printErrorPage($e->getMessage(), $e->getHint()); - } + self::$object->deleteKey($key); } } diff --git a/lib/private/log/errorhandler.php b/lib/private/log/errorhandler.php index 69cb960de91..1dde6b507fc 100644 --- a/lib/private/log/errorhandler.php +++ b/lib/private/log/errorhandler.php @@ -14,10 +14,23 @@ class ErrorHandler { /** @var LoggerInterface */ private static $logger; - public static function register() { + /** + * @brief remove password in URLs + * @param string $msg + * @return string + */ + protected static function removePassword($msg) { + return preg_replace('/\/\/(.*):(.*)@/', '//xxx:xxx@', $msg); + } + + public static function register($debug=false) { $handler = new ErrorHandler(); - set_error_handler(array($handler, 'onError')); + if ($debug) { + set_error_handler(array($handler, 'onAll'), E_ALL); + } else { + set_error_handler(array($handler, 'onError')); + } register_shutdown_function(array($handler, 'onShutdown')); set_exception_handler(array($handler, 'onException')); } @@ -32,14 +45,14 @@ class ErrorHandler { if($error && self::$logger) { //ob_end_clean(); $msg = $error['message'] . ' at ' . $error['file'] . '#' . $error['line']; - self::$logger->critical($msg, array('app' => 'PHP')); + self::$logger->critical(self::removePassword($msg), array('app' => 'PHP')); } } // Uncaught exception handler public static function onException($exception) { $msg = $exception->getMessage() . ' at ' . $exception->getFile() . '#' . $exception->getLine(); - self::$logger->critical($msg, array('app' => 'PHP')); + self::$logger->critical(self::removePassword($msg), array('app' => 'PHP')); } //Recoverable errors handler @@ -48,7 +61,15 @@ class ErrorHandler { return; } $msg = $message . ' at ' . $file . '#' . $line; - self::$logger->warning($msg, array('app' => 'PHP')); + self::$logger->error(self::removePassword($msg), array('app' => 'PHP')); + + } + + //Recoverable handler which catch all errors, warnings and notices + public static function onAll($number, $message, $file, $line) { + $msg = $message . ' at ' . $file . '#' . $line; + self::$logger->debug(self::removePassword($msg), array('app' => 'PHP')); } + } diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index d16b9537a16..3590bbd436d 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -35,7 +35,17 @@ class OC_Log_Owncloud { public static function init() { $defaultLogFile = OC_Config::getValue("datadirectory", OC::$SERVERROOT.'/data').'/owncloud.log'; self::$logFile = OC_Config::getValue("logfile", $defaultLogFile); - if (!file_exists(self::$logFile)) { + + /* + * Fall back to default log file if specified logfile does not exist + * and can not be created. Error suppression is required in order to + * not end up in the error handler which will try to log the error. + * A better solution (compared to error suppression) would be checking + * !is_writable(dirname(self::$logFile)) before touch(), but + * is_writable() on directories used to be pretty unreliable on Windows + * for at least some time. + */ + if (!file_exists(self::$logFile) && !@touch(self::$logFile)) { self::$logFile = $defaultLogFile; } } @@ -51,12 +61,24 @@ class OC_Log_Owncloud { if($level>=$minLevel) { // default to ISO8601 $format = OC_Config::getValue('logdateformat', 'c'); - $time = date($format, time()); - $entry=array('app'=>$app, 'message'=>$message, 'level'=>$level, 'time'=> $time); + $logtimezone=OC_Config::getValue( "logtimezone", 'UTC' ); + try { + $timezone = new DateTimeZone($logtimezone); + } catch (Exception $e) { + $timezone = new DateTimeZone('UTC'); + } + $time = new DateTime(null, $timezone); + // remove username/passswords from URLs before writing the to the log file + $entry=array('app'=>$app, 'message'=>$message, 'level'=>$level, 'time'=> $time->format($format)); + $entry = json_encode($entry); $handle = @fopen(self::$logFile, 'a'); + @chmod(self::$logFile, 0640); if ($handle) { - fwrite($handle, json_encode($entry)."\n"); + fwrite($handle, $entry."\n"); fclose($handle); + } else { + // Fall back to error_log + error_log($entry); } } } diff --git a/lib/private/memcache/apc.php b/lib/private/memcache/apc.php index 575ee4427db..332bbfead00 100644 --- a/lib/private/memcache/apc.php +++ b/lib/private/memcache/apc.php @@ -9,15 +9,8 @@ namespace OC\Memcache; class APC extends Cache { - /** - * entries in APC gets namespaced to prevent collisions between owncloud instances and users - */ - protected function getNameSpace() { - return $this->prefix; - } - public function get($key) { - $result = apc_fetch($this->getNamespace() . $key, $success); + $result = apc_fetch($this->getPrefix() . $key, $success); if (!$success) { return null; } @@ -25,31 +18,29 @@ class APC extends Cache { } public function set($key, $value, $ttl = 0) { - return apc_store($this->getNamespace() . $key, $value, $ttl); + return apc_store($this->getPrefix() . $key, $value, $ttl); } public function hasKey($key) { - return apc_exists($this->getNamespace() . $key); + return apc_exists($this->getPrefix() . $key); } public function remove($key) { - return apc_delete($this->getNamespace() . $key); + return apc_delete($this->getPrefix() . $key); } public function clear($prefix = '') { - $ns = $this->getNamespace() . $prefix; - $cache = apc_cache_info('user'); - foreach ($cache['cache_list'] as $entry) { - if (strpos($entry['info'], $ns) === 0) { - apc_delete($entry['info']); - } - } - return true; + $ns = $this->getPrefix() . $prefix; + $ns = preg_quote($ns, '/'); + $iter = new \APCIterator('user', '/^' . $ns . '/'); + return apc_delete($iter); } static public function isAvailable() { if (!extension_loaded('apc')) { return false; + } elseif (!ini_get('apc.enabled')) { + return false; } elseif (!ini_get('apc.enable_cli') && \OC::$CLI) { return false; } else { diff --git a/lib/private/memcache/apcu.php b/lib/private/memcache/apcu.php index ccc1aa6e562..7f780f32718 100644 --- a/lib/private/memcache/apcu.php +++ b/lib/private/memcache/apcu.php @@ -9,13 +9,6 @@ namespace OC\Memcache; class APCu extends APC { - public function clear($prefix = '') { - $ns = $this->getNamespace() . $prefix; - $ns = preg_quote($ns, '/'); - $iter = new \APCIterator('/^'.$ns.'/'); - return apc_delete($iter); - } - static public function isAvailable() { if (!extension_loaded('apcu')) { return false; diff --git a/lib/private/memcache/cache.php b/lib/private/memcache/cache.php index 0ad1cc7ec03..03671b3f240 100644 --- a/lib/private/memcache/cache.php +++ b/lib/private/memcache/cache.php @@ -18,7 +18,7 @@ abstract class Cache implements \ArrayAccess { * @param string $prefix */ public function __construct($prefix = '') { - $this->prefix = \OC_Util::getInstanceId() . '/' . $prefix; + $this->prefix = $prefix; } public function getPrefix() { diff --git a/lib/private/memcache/factory.php b/lib/private/memcache/factory.php index fde7d947567..334cf9a1f0e 100644 --- a/lib/private/memcache/factory.php +++ b/lib/private/memcache/factory.php @@ -8,7 +8,21 @@ namespace OC\Memcache; -class Factory { +use \OCP\ICacheFactory; + +class Factory implements ICacheFactory { + /** + * @var string $globalPrefix + */ + private $globalPrefix; + + /** + * @param string $globalPrefix + */ + public function __construct($globalPrefix) { + $this->globalPrefix = $globalPrefix; + } + /** * get a cache instance, will return null if no backend is available * @@ -16,6 +30,7 @@ class Factory { * @return \OC\Memcache\Cache */ function create($prefix = '') { + $prefix = $this->globalPrefix . '/' . $prefix; if (XCache::isAvailable()) { return new XCache($prefix); } elseif (APCu::isAvailable()) { diff --git a/lib/private/memcache/xcache.php b/lib/private/memcache/xcache.php index 33de30562f9..1337a7ad612 100644 --- a/lib/private/memcache/xcache.php +++ b/lib/private/memcache/xcache.php @@ -8,9 +8,13 @@ namespace OC\Memcache; +/** + * See http://xcache.lighttpd.net/wiki/XcacheApi for provided constants and + * functions etc. + */ class XCache extends Cache { /** - * entries in XCache gets namespaced to prevent collisions between owncloud instances and users + * entries in XCache gets namespaced to prevent collisions between ownCloud instances and users */ protected function getNameSpace() { return $this->prefix; @@ -37,24 +41,32 @@ class XCache extends Cache { } public function clear($prefix='') { - xcache_unset_by_prefix($this->getNamespace().$prefix); + if (function_exists('xcache_unset_by_prefix')) { + return xcache_unset_by_prefix($this->getNamespace().$prefix); + } else { + // Since we can not clear by prefix, we just clear the whole cache. + xcache_clear_cache(\XC_TYPE_VAR, 0); + } return true; } static public function isAvailable(){ if (!extension_loaded('xcache')) { return false; - } elseif (\OC::$CLI) { + } + if (\OC::$CLI) { return false; - }else{ - return true; } - } -} - -if(!function_exists('xcache_unset_by_prefix')) { - function xcache_unset_by_prefix($prefix) { - // Since we can't clear targetted cache, we'll clear all. :( - xcache_clear_cache(\XC_TYPE_VAR, 0); + if (!function_exists('xcache_unset_by_prefix') && ini_get('xcache.admin.enable_auth')) { + // We do not want to use XCache if we can not clear it without + // using the administration function xcache_clear_cache() + // AND administration functions are password-protected. + return false; + } + $var_size = (int) ini_get('xcache.var_size'); + if (!$var_size) { + return false; + } + return true; } } diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index 8ab8ac81bd8..40fb1d2d97d 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -21,87 +21,91 @@ */ /** - * list of mimetypes by extension + * Array mapping file extensions to mimetypes (in alphabetical order). */ - return array( + 'accdb'=>'application/msaccess', + 'ai' => 'application/illustrator', + 'avi'=>'video/x-msvideo', + 'bash' => 'text/x-shellscript', + 'blend'=>'application/x-blender', + 'cc' => 'text/x-c', + 'cdr' => 'application/coreldraw', + 'cpp' => 'text/x-c++src', 'css'=>'text/css', + 'c' => 'text/x-c', + 'c++' => 'text/x-c++src', + 'doc'=>'application/msword', + 'docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dot'=>'application/msword', + 'dotx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'dv'=>'video/dv', + 'epub' => 'application/epub+zip', + 'exe'=>'application/x-ms-dos-executable', 'flac'=>'audio/flac', 'gif'=>'image/gif', - 'gzip'=>'application/x-gzip', 'gz'=>'application/x-gzip', + 'gzip'=>'application/x-gzip', 'html'=>'text/html', 'htm'=>'text/html', - 'ics'=>'text/calendar', 'ical'=>'text/calendar', + 'ics'=>'text/calendar', + 'impress' => 'text/impress', 'jpeg'=>'image/jpeg', 'jpg'=>'image/jpeg', 'js'=>'application/javascript', + 'keynote'=>'application/x-iwork-keynote-sffkey', + 'kra'=>'application/x-krita', + 'm2t'=>'video/mp2t', + 'm4v'=>'video/mp4', + 'markdown' => 'text/markdown', + 'mdown' => 'text/markdown', + 'md' => 'text/markdown', + 'mdb'=>'application/msaccess', + 'mdwn' => 'text/markdown', + 'mobi' => 'application/x-mobipocket-ebook', + 'mov'=>'video/quicktime', + 'mp3'=>'audio/mpeg', + 'mp4'=>'video/mp4', + 'mpeg'=>'video/mpeg', + 'mpg'=>'video/mpeg', + 'msi'=>'application/x-msi', + 'numbers'=>'application/x-iwork-numbers-sffnumbers', + 'odg'=>'application/vnd.oasis.opendocument.graphics', + 'odp'=>'application/vnd.oasis.opendocument.presentation', + 'ods'=>'application/vnd.oasis.opendocument.spreadsheet', + 'odt'=>'application/vnd.oasis.opendocument.text', 'oga'=>'audio/ogg', 'ogg'=>'audio/ogg', 'ogv'=>'video/ogg', + 'pages'=>'application/x-iwork-pages-sffpages', 'pdf'=>'application/pdf', + 'php'=>'application/x-php', + 'pl'=>'application/x-pearl', 'png'=>'image/png', + 'ppt'=>'application/mspowerpoint', + 'pptx'=>'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'psd'=>'application/x-photoshop', + 'py'=>'text/x-script.python', + 'reveal' => 'text/reveal', + 'sgf' => 'application/sgf', + 'sh-lib' => 'text/x-shellscript', + 'sh' => 'text/x-shellscript', 'svg'=>'image/svg+xml', 'tar'=>'application/x-tar', - 'tgz'=>'application/x-compressed', 'tar.gz'=>'application/x-compressed', - 'tif'=>'image/tiff', + 'tgz'=>'application/x-compressed', 'tiff'=>'image/tiff', + 'tif'=>'image/tiff', 'txt'=>'text/plain', - 'zip'=>'application/zip', + 'vcard' => 'text/vcard', + 'vcf' => 'text/vcard', 'wav'=>'audio/wav', - 'odt'=>'application/vnd.oasis.opendocument.text', - 'ods'=>'application/vnd.oasis.opendocument.spreadsheet', - 'odg'=>'application/vnd.oasis.opendocument.graphics', - 'odp'=>'application/vnd.oasis.opendocument.presentation', - 'pages'=>'application/x-iwork-pages-sffpages', - 'numbers'=>'application/x-iwork-numbers-sffnumbers', - 'keynote'=>'application/x-iwork-keynote-sffkey', - 'kra'=>'application/x-krita', - 'mp3'=>'audio/mpeg', - 'doc'=>'application/msword', - 'docx'=>'application/msword', - 'xls'=>'application/msexcel', - 'xlsx'=>'application/msexcel', - 'php'=>'application/x-php', - 'exe'=>'application/x-ms-dos-executable', - 'pl'=>'application/x-pearl', - 'py'=>'application/x-python', - 'blend'=>'application/x-blender', - 'xcf'=>'application/x-gimp', - 'psd'=>'application/x-photoshop', - 'xml'=>'application/xml', - 'avi'=>'video/x-msvideo', - 'dv'=>'video/dv', - 'm2t'=>'video/mp2t', - 'mp4'=>'video/mp4', - 'm4v'=>'video/mp4', - 'mpg'=>'video/mpeg', - 'mpeg'=>'video/mpeg', - 'mov'=>'video/quicktime', 'webm'=>'video/webm', 'wmv'=>'video/x-ms-asf', - 'py'=>'text/x-script.phyton', - 'vcf' => 'text/vcard', - 'vcard' => 'text/vcard', - 'doc'=>'application/msword', - 'docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xcf'=>'application/x-gimp', 'xls'=>'application/msexcel', 'xlsx'=>'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'ppt'=>'application/mspowerpoint', - 'pptx'=>'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'sgf' => 'application/sgf', - 'cdr' => 'application/coreldraw', - 'impress' => 'text/impress', - 'ai' => 'application/illustrator', - 'epub' => 'application/epub+zip', - 'mobi' => 'application/x-mobipocket-ebook', - 'exe' => 'application', - 'msi' => 'application', - 'md' => 'text/markdown', - 'markdown' => 'text/markdown', - 'mdown' => 'text/markdown', - 'mdwn' => 'text/markdown', - 'reveal' => 'text/reveal' + 'xml'=>'application/xml', + 'zip'=>'application/zip', ); diff --git a/lib/private/ocs.php b/lib/private/ocs.php index 93e8931ce2e..e067196cf11 100644 --- a/lib/private/ocs.php +++ b/lib/private/ocs.php @@ -228,36 +228,4 @@ class OC_OCS { } } } - - /** - * get private data - * @param string $user - * @param string $app - * @param string $key - * @param bool $like use LIKE instead of = when comparing keys - * @return array - */ - public static function getData($user, $app="", $key="") { - if($app) { - $apps=array($app); - }else{ - $apps=OC_Preferences::getApps($user); - } - if($key) { - $keys=array($key); - }else{ - foreach($apps as $app) { - $keys=OC_Preferences::getKeys($user, $app); - } - } - $result=array(); - foreach($apps as $app) { - foreach($keys as $key) { - $value=OC_Preferences::getValue($user, $app, $key); - $result[]=array('app'=>$app, 'key'=>$key, 'value'=>$value); - } - } - return $result; - } - } diff --git a/lib/private/ocs/cloud.php b/lib/private/ocs/cloud.php index 2dd99319057..cbbf3b626f5 100644 --- a/lib/private/ocs/cloud.php +++ b/lib/private/ocs/cloud.php @@ -64,8 +64,7 @@ class OC_OCS_Cloud { // Check if they are viewing information on themselves if($parameters['userid'] === OC_User::getUser()) { // Self lookup - $quota = array(); - $storage = OC_Helper::getStorageInfo(); + $storage = OC_Helper::getStorageInfo('/'); $quota = array( 'free' => $storage['free'], 'used' => $storage['used'], @@ -79,6 +78,16 @@ class OC_OCS_Cloud { } } + public static function getCurrentUser() { + $email=OC_Preferences::getValue(OC_User::getUser(), 'settings', 'email', ''); + $data = array( + 'id' => OC_User::getUser(), + 'display-name' => OC_User::getDisplayName(), + 'email' => $email, + ); + return new OC_OCS_Result($data); + } + public static function getUserPublickey($parameters) { if(OC_User::userExists($parameters['user'])) { diff --git a/lib/private/ocs/privatedata.php b/lib/private/ocs/privatedata.php index 4dfd0a6e66e..932413711b8 100644 --- a/lib/private/ocs/privatedata.php +++ b/lib/private/ocs/privatedata.php @@ -22,45 +22,87 @@ * */ + class OC_OCS_Privatedata { + /** + * read keys + * test: curl http://login:passwd@oc/core/ocs/v1.php/privatedata/getattribute/testy/123 + * test: curl http://login:passwd@oc/core/ocs/v1.php/privatedata/getattribute/testy + * @param array $parameters The OCS parameter + * @return \OC_OCS_Result + */ public static function get($parameters) { - OC_Util::checkLoggedIn(); $user = OC_User::getUser(); $app = addslashes(strip_tags($parameters['app'])); - $key = addslashes(strip_tags($parameters['key'])); - $result = OC_OCS::getData($user, $app, $key); + $key = isset($parameters['key']) ? addslashes(strip_tags($parameters['key'])) : null; + + if(empty($key)) { + $query = \OCP\DB::prepare('SELECT `key`, `app`, `value` FROM `*PREFIX*privatedata` WHERE `user` = ? AND `app` = ? '); + $result = $query->execute(array($user, $app)); + } else { + $query = \OCP\DB::prepare('SELECT `key`, `app`, `value` FROM `*PREFIX*privatedata` WHERE `user` = ? AND `app` = ? AND `key` = ? '); + $result = $query->execute(array($user, $app, $key)); + } + $xml = array(); - foreach($result as $i=>$log) { - $xml[$i]['key']=$log['key']; - $xml[$i]['app']=$log['app']; - $xml[$i]['value']=$log['value']; + while ($row = $result->fetchRow()) { + $data=array(); + $data['key']=$row['key']; + $data['app']=$row['app']; + $data['value']=$row['value']; + $xml[] = $data; } + return new OC_OCS_Result($xml); - //TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it } + /** + * set a key + * test: curl http://login:passwd@oc/core/ocs/v1.php/privatedata/setattribute/testy/123 --data "value=foobar" + * @param array $parameters The OCS parameter + * @return \OC_OCS_Result + */ public static function set($parameters) { - OC_Util::checkLoggedIn(); $user = OC_User::getUser(); $app = addslashes(strip_tags($parameters['app'])); $key = addslashes(strip_tags($parameters['key'])); $value = OC_OCS::readData('post', 'value', 'text'); - if(OC_Preferences::setValue($user, $app, $key, $value)) { - return new OC_OCS_Result(null, 100); + + // update in DB + $query = \OCP\DB::prepare('UPDATE `*PREFIX*privatedata` SET `value` = ? WHERE `user` = ? AND `app` = ? AND `key` = ?'); + $numRows = $query->execute(array($value, $user, $app, $key)); + + if ($numRows === false || $numRows === 0) { + // store in DB + $query = \OCP\DB::prepare('INSERT INTO `*PREFIX*privatedata` (`user`, `app`, `key`, `value`)' . ' VALUES(?, ?, ?, ?)'); + $query->execute(array($user, $app, $key, $value)); } + + return new OC_OCS_Result(null, 100); } + /** + * delete a key + * test: curl http://login:passwd@oc/core/ocs/v1.php/privatedata/deleteattribute/testy/123 --data "post=1" + * @param array $parameters The OCS parameter + * @return \OC_OCS_Result + */ public static function delete($parameters) { - OC_Util::checkLoggedIn(); $user = OC_User::getUser(); + if (!isset($parameters['app']) or !isset($parameters['key'])) { + //key and app are NOT optional here + return new OC_OCS_Result(null, 101); + } + $app = addslashes(strip_tags($parameters['app'])); $key = addslashes(strip_tags($parameters['key'])); - if($key==="" or $app==="") { - return new OC_OCS_Result(null, 101); //key and app are NOT optional here - } - if(OC_Preferences::deleteKey($user, $app, $key)) { - return new OC_OCS_Result(null, 100); - } + + // delete in DB + $query = \OCP\DB::prepare('DELETE FROM `*PREFIX*privatedata` WHERE `user` = ? AND `app` = ? AND `key` = ? '); + $query->execute(array($user, $app, $key )); + + return new OC_OCS_Result(null, 100); } } + diff --git a/lib/private/preview.php b/lib/private/preview.php index 266f7795f12..ff93f438f73 100755 --- a/lib/private/preview.php +++ b/lib/private/preview.php @@ -9,7 +9,7 @@ * Thumbnails: * structure of filename: * /data/user/thumbnails/pathhash/x-y.png - * + * */ namespace OC; @@ -40,6 +40,7 @@ class Preview { private $maxX; private $maxY; private $scalingup; + private $mimetype; //preview images object /** @@ -59,11 +60,18 @@ class Preview { * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image * @param bool $scalingUp Disable/Enable upscaling of previews - * @return mixed (bool / string) + * @return mixed (bool / string) * false if thumbnail does not exist * path to thumbnail if thumbnail exists */ public function __construct($user='', $root='/', $file='', $maxX=1, $maxY=1, $scalingUp=true) { + //init fileviews + if($user === ''){ + $user = \OC_User::getUser(); + } + $this->fileView = new \OC\Files\View('/' . $user . '/' . $root); + $this->userView = new \OC\Files\View('/' . $user); + //set config $this->configMaxX = \OC_Config::getValue('preview_max_x', null); $this->configMaxY = \OC_Config::getValue('preview_max_y', null); @@ -75,13 +83,6 @@ class Preview { $this->setMaxY($maxY); $this->setScalingUp($scalingUp); - //init fileviews - if($user === ''){ - $user = \OC_User::getUser(); - } - $this->fileView = new \OC\Files\View('/' . $user . '/' . $root); - $this->userView = new \OC\Files\View('/' . $user); - $this->preview = null; //check if there are preview backends @@ -166,10 +167,21 @@ class Preview { */ public function setFile($file) { $this->file = $file; + if ($file !== '') { + $this->mimetype = $this->fileView->getMimeType($this->file); + } return $this; } /** + * @brief set mimetype explicitely + * @param string $mimetype + */ + public function setMimetype($mimetype) { + $this->mimetype = $mimetype; + } + + /** * @brief set the the max width of the preview * @param int $maxX * @return $this @@ -265,7 +277,7 @@ class Preview { $fileInfo = $this->fileView->getFileInfo($file); $fileId = $fileInfo['fileid']; - + $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; $this->userView->deleteAll($previewPath); $this->userView->rmdir($previewPath); @@ -274,7 +286,7 @@ class Preview { /** * @brief check if thumbnail or bigger version of thumbnail of file is cached - * @return mixed (bool / string) + * @return mixed (bool / string) * false if thumbnail does not exist * path to thumbnail if thumbnail exists */ @@ -386,11 +398,10 @@ class Preview { } if(is_null($this->preview)) { - $mimetype = $this->fileView->getMimeType($file); $preview = null; foreach(self::$providers as $supportedMimetype => $provider) { - if(!preg_match($supportedMimetype, $mimetype)) { + if(!preg_match($supportedMimetype, $this->mimetype)) { continue; } @@ -516,7 +527,7 @@ class Preview { $cropY = 0; $image->crop($cropX, $cropY, $x, $y); - + $this->preview = $image; return; } @@ -598,7 +609,7 @@ class Preview { public static function post_write($args) { self::post_delete($args); } - + public static function post_delete($args) { $path = $args['path']; if(substr($path, 0, 1) === '/') { diff --git a/lib/private/preview/image.php b/lib/private/preview/image.php index 9aec967282d..84343df2608 100644 --- a/lib/private/preview/image.php +++ b/lib/private/preview/image.php @@ -21,11 +21,11 @@ class Image extends Provider { return false; } + $image = new \OC_Image(); //check if file is encrypted if($fileInfo['encrypted'] === true) { - $image = new \OC_Image(stream_get_contents($fileview->fopen($path, 'r'))); + $image->loadFromData(stream_get_contents($fileview->fopen($path, 'r'))); }else{ - $image = new \OC_Image(); $image->loadFromFile($fileview->getLocalFile($path)); } diff --git a/lib/private/preview/movies.php b/lib/private/preview/movies.php index c318137ff0e..71cd3bae057 100644 --- a/lib/private/preview/movies.php +++ b/lib/private/preview/movies.php @@ -8,40 +8,83 @@ */ namespace OC\Preview; -$isShellExecEnabled = !in_array('shell_exec', explode(', ', ini_get('disable_functions'))); -$whichAVCONV = shell_exec('which avconv'); -$isAVCONVAvailable = !empty($whichAVCONV); - -if($isShellExecEnabled && $isAVCONVAvailable) { +function findBinaryPath($program) { + exec('which ' . escapeshellarg($program) . ' 2> /dev/null', $output, $returnCode); + if ($returnCode === 0 && count($output) > 0) { + return escapeshellcmd($output[0]); + } + return null; +} - class Movie extends Provider { +// movie preview is currently not supported on Windows +if (!\OC_Util::runningOnWindows()) { + $isExecEnabled = \OC_Helper::is_function_enabled('exec'); + $ffmpegBinary = null; + $avconvBinary = null; - public function getMimeType() { - return '/video\/.*/'; + if ($isExecEnabled) { + $avconvBinary = findBinaryPath('avconv'); + if (!$avconvBinary) { + $ffmpegBinary = findBinaryPath('ffmpeg'); } + } + + if($isExecEnabled && ( $avconvBinary || $ffmpegBinary )) { - public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { - $absPath = \OC_Helper::tmpFile(); - $tmpPath = \OC_Helper::tmpFile(); + class Movie extends Provider { + public static $avconvBinary; + public static $ffmpegBinary; - $handle = $fileview->fopen($path, 'rb'); + public function getMimeType() { + return '/video\/.*/'; + } - $firstmb = stream_get_contents($handle, 1048576); //1024 * 1024 = 1048576 - file_put_contents($absPath, $firstmb); + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + // TODO: use proc_open() and stream the source file ? + $absPath = \OC_Helper::tmpFile(); + $tmpPath = \OC_Helper::tmpFile(); - //$cmd = 'ffmpeg -y -i ' . escapeshellarg($absPath) . ' -f mjpeg -vframes 1 -ss 1 -s ' . escapeshellarg($maxX) . 'x' . escapeshellarg($maxY) . ' ' . $tmpPath; - $cmd = 'avconv -an -y -ss 1 -i ' . escapeshellarg($absPath) . ' -f mjpeg -vframes 1 ' . escapeshellarg($tmpPath); - - shell_exec($cmd); + $handle = $fileview->fopen($path, 'rb'); - $image = new \OC_Image($tmpPath); + // we better use 5MB (1024 * 1024 * 5 = 5242880) instead of 1MB. + // in some cases 1MB was no enough to generate thumbnail + $firstmb = stream_get_contents($handle, 5242880); + file_put_contents($absPath, $firstmb); - unlink($absPath); - unlink($tmpPath); + if (self::$avconvBinary) { + $cmd = self::$avconvBinary . ' -an -y -ss 5'. + ' -i ' . escapeshellarg($absPath) . + ' -f mjpeg -vframes 1 -vsync 1 ' . escapeshellarg($tmpPath) . + ' > /dev/null 2>&1'; + } + else { + $cmd = self::$ffmpegBinary . ' -y -ss 5' . + ' -i ' . escapeshellarg($absPath) . + ' -f mjpeg -vframes 1' . + ' -s ' . escapeshellarg($maxX) . 'x' . escapeshellarg($maxY) . + ' ' . escapeshellarg($tmpPath) . + ' > /dev/null 2>&1'; + } - return $image->valid() ? $image : false; + exec($cmd, $output, $returnCode); + + unlink($absPath); + + if ($returnCode === 0) { + $image = new \OC_Image(); + $image->loadFromFile($tmpPath); + unlink($tmpPath); + return $image->valid() ? $image : false; + } + return false; + } } + + // a bit hacky but didn't want to use subclasses + Movie::$avconvBinary = $avconvBinary; + Movie::$ffmpegBinary = $ffmpegBinary; + + \OC\Preview::registerProvider('OC\Preview\Movie'); } +} - \OC\Preview::registerProvider('OC\Preview\Movie'); -}
\ No newline at end of file diff --git a/lib/private/preview/mp3.php b/lib/private/preview/mp3.php index 1eed566315c..3fc0ab0490c 100644 --- a/lib/private/preview/mp3.php +++ b/lib/private/preview/mp3.php @@ -25,7 +25,8 @@ class MP3 extends Provider { if(isset($tags['id3v2']['APIC'][0]['data'])) { $picture = @$tags['id3v2']['APIC'][0]['data']; unlink($tmpPath); - $image = new \OC_Image($picture); + $image = new \OC_Image(); + $image->loadFromData($picture); return $image->valid() ? $image : $this->getNoCoverThumbnail(); } @@ -39,7 +40,8 @@ class MP3 extends Provider { return false; } - $image = new \OC_Image($icon); + $image = new \OC_Image(); + $image->loadFromFile($icon); return $image->valid() ? $image : false; } diff --git a/lib/private/preview/office-cl.php b/lib/private/preview/office-cl.php index 112909d6523..b11fed13ba1 100644 --- a/lib/private/preview/office-cl.php +++ b/lib/private/preview/office-cl.php @@ -7,128 +7,133 @@ */ namespace OC\Preview; -//we need imagick to convert -class Office extends Provider { +// office preview is currently not supported on Windows +if (!\OC_Util::runningOnWindows()) { - private $cmd; + //we need imagick to convert + class Office extends Provider { - public function getMimeType() { - return null; - } + private $cmd; - public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { - $this->initCmd(); - if(is_null($this->cmd)) { - return false; + public function getMimeType() { + return null; } - $absPath = $fileview->toTmpFile($path); + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { + $this->initCmd(); + if(is_null($this->cmd)) { + return false; + } + + $absPath = $fileview->toTmpFile($path); + + $tmpDir = get_temp_dir(); - $tmpDir = get_temp_dir(); + $defaultParameters = ' --headless --nologo --nofirststartwizard --invisible --norestore -convert-to pdf -outdir '; + $clParameters = \OCP\Config::getSystemValue('preview_office_cl_parameters', $defaultParameters); - $defaultParameters = ' --headless --nologo --nofirststartwizard --invisible --norestore -convert-to pdf -outdir '; - $clParameters = \OCP\Config::getSystemValue('preview_office_cl_parameters', $defaultParameters); + $exec = $this->cmd . $clParameters . escapeshellarg($tmpDir) . ' ' . escapeshellarg($absPath); + $export = 'export HOME=/' . $tmpDir; - $exec = $this->cmd . $clParameters . escapeshellarg($tmpDir) . ' ' . escapeshellarg($absPath); - $export = 'export HOME=/' . $tmpDir; + shell_exec($export . "\n" . $exec); - shell_exec($export . "\n" . $exec); + //create imagick object from pdf + try{ + $pdf = new \imagick($absPath . '.pdf' . '[0]'); + $pdf->setImageFormat('jpg'); + } catch (\Exception $e) { + unlink($absPath); + unlink($absPath . '.pdf'); + \OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR); + return false; + } + + $image = new \OC_Image(); + $image->loadFromData($pdf); - //create imagick object from pdf - try{ - $pdf = new \imagick($absPath . '.pdf' . '[0]'); - $pdf->setImageFormat('jpg'); - } catch (\Exception $e) { unlink($absPath); unlink($absPath . '.pdf'); - \OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR); - return false; + + return $image->valid() ? $image : false; } - $image = new \OC_Image($pdf); + private function initCmd() { + $cmd = ''; - unlink($absPath); - unlink($absPath . '.pdf'); + if(is_string(\OC_Config::getValue('preview_libreoffice_path', null))) { + $cmd = \OC_Config::getValue('preview_libreoffice_path', null); + } - return $image->valid() ? $image : false; - } + $whichLibreOffice = shell_exec('which libreoffice'); + if($cmd === '' && !empty($whichLibreOffice)) { + $cmd = 'libreoffice'; + } - private function initCmd() { - $cmd = ''; + $whichOpenOffice = shell_exec('which openoffice'); + if($cmd === '' && !empty($whichOpenOffice)) { + $cmd = 'openoffice'; + } - if(is_string(\OC_Config::getValue('preview_libreoffice_path', null))) { - $cmd = \OC_Config::getValue('preview_libreoffice_path', null); - } + if($cmd === '') { + $cmd = null; + } - $whichLibreOffice = shell_exec('which libreoffice'); - if($cmd === '' && !empty($whichLibreOffice)) { - $cmd = 'libreoffice'; + $this->cmd = $cmd; } + } - $whichOpenOffice = shell_exec('which openoffice'); - if($cmd === '' && !empty($whichOpenOffice)) { - $cmd = 'openoffice'; - } + //.doc, .dot + class MSOfficeDoc extends Office { - if($cmd === '') { - $cmd = null; + public function getMimeType() { + return '/application\/msword/'; } - $this->cmd = $cmd; - } -} - -//.doc, .dot -class MSOfficeDoc extends Office { - - public function getMimeType() { - return '/application\/msword/'; } -} + \OC\Preview::registerProvider('OC\Preview\MSOfficeDoc'); -\OC\Preview::registerProvider('OC\Preview\MSOfficeDoc'); + //.docm, .dotm, .xls(m), .xlt(m), .xla(m), .ppt(m), .pot(m), .pps(m), .ppa(m) + class MSOffice2003 extends Office { -//.docm, .dotm, .xls(m), .xlt(m), .xla(m), .ppt(m), .pot(m), .pps(m), .ppa(m) -class MSOffice2003 extends Office { + public function getMimeType() { + return '/application\/vnd.ms-.*/'; + } - public function getMimeType() { - return '/application\/vnd.ms-.*/'; } -} + \OC\Preview::registerProvider('OC\Preview\MSOffice2003'); -\OC\Preview::registerProvider('OC\Preview\MSOffice2003'); + //.docx, .dotx, .xlsx, .xltx, .pptx, .potx, .ppsx + class MSOffice2007 extends Office { -//.docx, .dotx, .xlsx, .xltx, .pptx, .potx, .ppsx -class MSOffice2007 extends Office { + public function getMimeType() { + return '/application\/vnd.openxmlformats-officedocument.*/'; + } - public function getMimeType() { - return '/application\/vnd.openxmlformats-officedocument.*/'; } -} + \OC\Preview::registerProvider('OC\Preview\MSOffice2007'); -\OC\Preview::registerProvider('OC\Preview\MSOffice2007'); + //.odt, .ott, .oth, .odm, .odg, .otg, .odp, .otp, .ods, .ots, .odc, .odf, .odb, .odi, .oxt + class OpenDocument extends Office { -//.odt, .ott, .oth, .odm, .odg, .otg, .odp, .otp, .ods, .ots, .odc, .odf, .odb, .odi, .oxt -class OpenDocument extends Office { + public function getMimeType() { + return '/application\/vnd.oasis.opendocument.*/'; + } - public function getMimeType() { - return '/application\/vnd.oasis.opendocument.*/'; } -} + \OC\Preview::registerProvider('OC\Preview\OpenDocument'); -\OC\Preview::registerProvider('OC\Preview\OpenDocument'); + //.sxw, .stw, .sxc, .stc, .sxd, .std, .sxi, .sti, .sxg, .sxm + class StarOffice extends Office { -//.sxw, .stw, .sxc, .stc, .sxd, .std, .sxi, .sti, .sxg, .sxm -class StarOffice extends Office { + public function getMimeType() { + return '/application\/vnd.sun.xml.*/'; + } - public function getMimeType() { - return '/application\/vnd.sun.xml.*/'; } + \OC\Preview::registerProvider('OC\Preview\StarOffice'); } - -\OC\Preview::registerProvider('OC\Preview\StarOffice');
\ No newline at end of file diff --git a/lib/private/preview/office-fallback.php b/lib/private/preview/office-fallback.php index e69ab0ab8cb..f184b3149d5 100644 --- a/lib/private/preview/office-fallback.php +++ b/lib/private/preview/office-fallback.php @@ -80,7 +80,8 @@ class MSOfficeExcel extends Provider { unlink($absPath); unlink($tmpPath); - $image = new \OC_Image($pdf); + $image = new \OC_Image(); + $image->loadFromData($pdf); return $image->valid() ? $image : false; } diff --git a/lib/private/preview/office.php b/lib/private/preview/office.php index 5287bbd6ac1..7a4826c76ec 100644 --- a/lib/private/preview/office.php +++ b/lib/private/preview/office.php @@ -7,16 +7,23 @@ */ //both, libreoffice backend and php fallback, need imagick if (extension_loaded('imagick')) { - $isShellExecEnabled = !in_array('shell_exec', explode(', ', ini_get('disable_functions'))); - $whichLibreOffice = shell_exec('which libreoffice'); - $isLibreOfficeAvailable = !empty($whichLibreOffice); - $whichOpenOffice = shell_exec('which libreoffice'); - $isOpenOfficeAvailable = !empty($whichOpenOffice); - //let's see if there is libreoffice or openoffice on this machine - if($isShellExecEnabled && ($isLibreOfficeAvailable || $isOpenOfficeAvailable || is_string(\OC_Config::getValue('preview_libreoffice_path', null)))) { - require_once('office-cl.php'); - }else{ + $isShellExecEnabled = \OC_Helper::is_function_enabled('shell_exec'); + + // LibreOffice preview is currently not supported on Windows + if (!\OC_Util::runningOnWindows()) { + $whichLibreOffice = ($isShellExecEnabled ? shell_exec('which libreoffice') : ''); + $isLibreOfficeAvailable = !empty($whichLibreOffice); + $whichOpenOffice = ($isShellExecEnabled ? shell_exec('which libreoffice') : ''); + $isOpenOfficeAvailable = !empty($whichOpenOffice); + //let's see if there is libreoffice or openoffice on this machine + if($isShellExecEnabled && ($isLibreOfficeAvailable || $isOpenOfficeAvailable || is_string(\OC_Config::getValue('preview_libreoffice_path', null)))) { + require_once('office-cl.php'); + }else{ + //in case there isn't, use our fallback + require_once('office-fallback.php'); + } + } else { //in case there isn't, use our fallback require_once('office-fallback.php'); } -}
\ No newline at end of file +} diff --git a/lib/private/preview/provider.php b/lib/private/preview/provider.php index e4a730bafc8..65d09705f40 100644 --- a/lib/private/preview/provider.php +++ b/lib/private/preview/provider.php @@ -11,9 +11,15 @@ abstract class Provider { abstract public function getMimeType(); /** - * search for $query - * @param string $query - * @return + * get thumbnail for file at path $path + * @param string $path Path of file + * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image + * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image + * @param bool $scalingUp Disable/Enable upscaling of previews + * @param object $fileview fileview object of user folder + * @return mixed + * false if no preview was generated + * OC_Image object of the preview */ abstract public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview); } diff --git a/lib/private/preview/txt.php b/lib/private/preview/txt.php index 77e728eb364..c9aa20968d8 100644 --- a/lib/private/preview/txt.php +++ b/lib/private/preview/txt.php @@ -9,20 +9,19 @@ namespace OC\Preview; class TXT extends Provider { - private static $blacklist = array( - 'text/calendar', - 'text/vcard', - ); - public function getMimeType() { - return '/text\/.*/'; + return '/text\/plain/'; } + /** + * @param string $path + * @param int $maxX + * @param int $maxY + * @param boolean $scalingup + * @param \OC\Files\View $fileview + * @return bool|\OC_Image + */ public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { - $mimetype = $fileview->getMimeType($path); - if(in_array($mimetype, self::$blacklist)) { - return false; - } $content = $fileview->fopen($path, 'r'); $content = stream_get_contents($content); @@ -62,22 +61,12 @@ class TXT extends Provider { \OC\Preview::registerProvider('OC\Preview\TXT'); -class PHP extends TXT { - - public function getMimeType() { - return '/application\/x-php/'; - } - -} - -\OC\Preview::registerProvider('OC\Preview\PHP'); - -class JavaScript extends TXT { +class MarkDown extends TXT { public function getMimeType() { - return '/application\/javascript/'; + return '/text\/(x-)?markdown/'; } } -\OC\Preview::registerProvider('OC\Preview\JavaScript');
\ No newline at end of file +\OC\Preview::registerProvider('OC\Preview\MarkDown'); diff --git a/lib/private/preview/unknown.php b/lib/private/preview/unknown.php index 9e6cd68d401..4747f9e25ed 100644 --- a/lib/private/preview/unknown.php +++ b/lib/private/preview/unknown.php @@ -20,8 +20,30 @@ class Unknown extends Provider { $path = \OC_Helper::mimetypeIcon($mimetype); $path = \OC::$SERVERROOT . substr($path, strlen(\OC::$WEBROOT)); - return new \OC_Image($path); + $svgPath = substr_replace($path, 'svg', -3); + + if (extension_loaded('imagick') && file_exists($svgPath)) { + + // http://www.php.net/manual/de/imagick.setresolution.php#85284 + $svg = new \Imagick(); + $svg->readImage($svgPath); + $res = $svg->getImageResolution(); + $x_ratio = $res['x'] / $svg->getImageWidth(); + $y_ratio = $res['y'] / $svg->getImageHeight(); + $svg->removeImage(); + $svg->setResolution($maxX * $x_ratio, $maxY * $y_ratio); + $svg->setBackgroundColor(new \ImagickPixel('transparent')); + $svg->readImage($svgPath); + $svg->setImageFormat('png32'); + + $image = new \OC_Image(); + $image->loadFromData($svg); + } else { + $image = new \OC_Image($path); + } + + return $image; } } -\OC\Preview::registerProvider('OC\Preview\Unknown');
\ No newline at end of file +\OC\Preview::registerProvider('OC\Preview\Unknown'); diff --git a/lib/private/repair.php b/lib/private/repair.php new file mode 100644 index 00000000000..e9de3baa7ce --- /dev/null +++ b/lib/private/repair.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC; + +use OC\Hooks\BasicEmitter; + +class Repair extends BasicEmitter { + /** + * run a series of repair steps for common problems + * progress can be reported by emitting \OC\Repair::step events + */ + public function run() { + $this->emit('\OC\Repair', 'step', array('No repair steps configured at the moment')); + } +} diff --git a/lib/private/request.php b/lib/private/request.php index df33217f95d..2c5b907846e 100755 --- a/lib/private/request.php +++ b/lib/private/request.php @@ -7,8 +7,15 @@ */ class OC_Request { + + const USER_AGENT_IE = '/MSIE/'; + // Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent + const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#'; + const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#'; + /** * @brief Check overwrite condition + * @param string $type * @returns bool */ private static function isOverwriteCondition($type = '') { @@ -99,7 +106,7 @@ class OC_Request { public static function scriptName() { $name = $_SERVER['SCRIPT_NAME']; if (OC_Config::getValue('overwritewebroot', '') !== '' and self::isOverwriteCondition()) { - $serverroot = str_replace("\\", '/', substr(__DIR__, 0, -4)); + $serverroot = str_replace("\\", '/', substr(__DIR__, 0, -strlen('lib/private/'))); $suburi = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen($serverroot))); $name = OC_Config::getValue('overwritewebroot', '') . $suburi; } @@ -135,12 +142,40 @@ class OC_Request { * @returns string Path info or false when not found */ public static function getRawPathInfo() { - $path_info = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME'])); + $requestUri = $_SERVER['REQUEST_URI']; + // remove too many leading slashes - can be caused by reverse proxy configuration + if (strpos($requestUri, '/') === 0) { + $requestUri = '/' . ltrim($requestUri, '/'); + } + // Remove the query string from REQUEST_URI - if ($pos = strpos($path_info, '?')) { - $path_info = substr($path_info, 0, $pos); + if ($pos = strpos($requestUri, '?')) { + $requestUri = substr($requestUri, 0, $pos); + } + + $scriptName = $_SERVER['SCRIPT_NAME']; + $path_info = $requestUri; + + // strip off the script name's dir and file name + list($path, $name) = \Sabre_DAV_URLUtil::splitPath($scriptName); + if (!empty($path)) { + if( $path === $path_info || strpos($path_info, $path.'/') === 0) { + $path_info = substr($path_info, strlen($path)); + } else { + throw new Exception("The requested uri($requestUri) cannot be processed by the script '$scriptName')"); + } + } + if (strpos($path_info, '/'.$name) === 0) { + $path_info = substr($path_info, strlen($name) + 1); + } + if (strpos($path_info, $name) === 0) { + $path_info = substr($path_info, strlen($name)); + } + if($path_info === '/'){ + return ''; + } else { + return $path_info; } - return $path_info; } /** @@ -181,4 +216,22 @@ class OC_Request { return false; } } + + /** + * Checks whether the user agent matches a given regex + * @param string|array $agent agent name or array of agent names + * @return boolean true if at least one of the given agent matches, + * false otherwise + */ + static public function isUserAgent($agent) { + if (!is_array($agent)) { + $agent = array($agent); + } + foreach ($agent as $regex) { + if (preg_match($regex, $_SERVER['HTTP_USER_AGENT'])) { + return true; + } + } + return false; + } } diff --git a/lib/private/response.php b/lib/private/response.php index 674176d078b..52dbb9d90f8 100644 --- a/lib/private/response.php +++ b/lib/private/response.php @@ -148,6 +148,24 @@ class OC_Response { } /** + * Sets the content disposition header (with possible workarounds) + * @param string $filename file name + * @param string $type disposition type, either 'attachment' or 'inline' + */ + static public function setContentDispositionHeader( $filename, $type = 'attachment' ) { + if (OC_Request::isUserAgent(array( + OC_Request::USER_AGENT_IE, + OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME, + OC_Request::USER_AGENT_FREEBOX + ))) { + header( 'Content-Disposition: ' . rawurlencode($type) . '; filename="' . rawurlencode( $filename ) . '"' ); + } else { + header( 'Content-Disposition: ' . rawurlencode($type) . '; filename*=UTF-8\'\'' . rawurlencode( $filename ) + . '; filename="' . rawurlencode( $filename ) . '"' ); + } + } + + /** * @brief Send file as response, checking and setting caching headers * @param $filepath of file to send */ diff --git a/lib/private/route.php b/lib/private/route.php index 5901717c094..fb7da456b62 100644 --- a/lib/private/route.php +++ b/lib/private/route.php @@ -52,6 +52,14 @@ class OC_Route extends Route { } /** + * Specify PATCH as the method to use with this route + */ + public function patch() { + $this->method('PATCH'); + return $this; + } + + /** * Defaults to use for this route * * @param array $defaults The defaults diff --git a/lib/private/router.php b/lib/private/router.php index dbaca9e0d5d..19c1e4473ec 100644 --- a/lib/private/router.php +++ b/lib/private/router.php @@ -67,7 +67,8 @@ class OC_Router { $this->useCollection($app); require_once $file; $collection = $this->getCollection($app); - $this->root->addCollection($collection, '/apps/'.$app); + $collection->addPrefix('/apps/'.$app); + $this->root->addCollection($collection); } $this->useCollection('root'); require_once 'settings/routes.php'; @@ -76,7 +77,8 @@ class OC_Router { // include ocs routes require_once 'ocs/routes.php'; $collection = $this->getCollection('ocs'); - $this->root->addCollection($collection, '/ocs'); + $collection->addPrefix('/ocs'); + $this->root->addCollection($collection); } protected function getCollection($name) { diff --git a/lib/private/server.php b/lib/private/server.php index cabb15324ec..fc8f170dc4a 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -5,6 +5,7 @@ namespace OC; use OC\AppFramework\Http\Request; use OC\AppFramework\Utility\SimpleContainer; use OC\Cache\UserCache; +use OC\DB\ConnectionWrapper; use OC\Files\Node\Root; use OC\Files\View; use OCP\IServerContainer; @@ -22,12 +23,16 @@ class Server extends SimpleContainer implements IServerContainer { return new ContactsManager(); }); $this->registerService('Request', function($c) { - $params = array(); + if (isset($c['urlParams'])) { + $urlParams = $c['urlParams']; + } else { + $urlParams = array(); + } - // we json decode the body only in case of content type json - if (isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'],'json') !== false ) { - $params = json_decode(file_get_contents('php://input'), true); - $params = is_array($params) ? $params: array(); + if (\OC::$session->exists('requesttoken')) { + $requesttoken = \OC::$session->get('requesttoken'); + } else { + $requesttoken = false; } return new Request( @@ -41,8 +46,8 @@ class Server extends SimpleContainer implements IServerContainer { 'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD'])) ? $_SERVER['REQUEST_METHOD'] : null, - 'params' => $params, - 'urlParams' => $c['urlParams'] + 'urlParams' => $urlParams, + 'requesttoken' => $requesttoken, ) ); }); @@ -64,10 +69,18 @@ class Server extends SimpleContainer implements IServerContainer { return new Root($manager, $view, $user); }); $this->registerService('UserManager', function($c) { - return new \OC\User\Manager(); + /** + * @var SimpleContainer $c + * @var \OC\AllConfig $config + */ + $config = $c->query('AllConfig'); + return new \OC\User\Manager($config); }); $this->registerService('UserSession', function($c) { - /** @var $c SimpleContainer */ + /** + * @var SimpleContainer $c + * @var \OC\User\Manager $manager + */ $manager = $c->query('UserManager'); $userSession = new \OC\User\Session($manager, \OC::$session); $userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) { @@ -111,9 +124,33 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('AllConfig', function($c) { return new \OC\AllConfig(); }); + $this->registerService('AppConfig', function ($c) { + return new \OC\AppConfig(\OC_DB::getConnection()); + }); + $this->registerService('L10NFactory', function($c) { + return new \OC\L10N\Factory(); + }); + $this->registerService('URLGenerator', function($c) { + /** @var $c SimpleContainer */ + $config = $c->query('AllConfig'); + return new \OC\URLGenerator($config); + }); + $this->registerService('AppHelper', function($c) { + return new \OC\AppHelper(); + }); $this->registerService('UserCache', function($c) { return new UserCache(); }); + $this->registerService('MemCacheFactory', function ($c) { + $instanceId = \OC_Util::getInstanceId(); + return new \OC\Memcache\Factory($instanceId); + }); + $this->registerService('ActivityManager', function($c) { + return new ActivityManager(); + }); + $this->registerService('AvatarManager', function($c) { + return new AvatarManager(); + }); } /** @@ -154,6 +191,15 @@ class Server extends SimpleContainer implements IServerContainer { } /** + * Returns the avatar manager, used for avatar functionality + * + * @return \OCP\IAvatarManager + */ + function getAvatarManager() { + return $this->query('AvatarManager'); + } + + /** * Returns the root folder of ownCloud's data directory * * @return \OCP\Files\Folder @@ -220,13 +266,45 @@ class Server extends SimpleContainer implements IServerContainer { } /** - * @return \OC\Config + * @return \OCP\IConfig */ function getConfig() { return $this->query('AllConfig'); } /** + * Returns the app config manager + * + * @return \OCP\IAppConfig + */ + function getAppConfig(){ + return $this->query('AppConfig'); + } + + /** + * get an L10N instance + * @param $app string appid + * @return \OC_L10N + */ + function getL10N($app) { + return $this->query('L10NFactory')->get($app); + } + + /** + * @return \OC\URLGenerator + */ + function getURLGenerator() { + return $this->query('URLGenerator'); + } + + /** + * @return \OC\Helper + */ + function getHelper() { + return $this->query('AppHelper'); + } + + /** * Returns an ICache instance * * @return \OCP\ICache @@ -236,6 +314,15 @@ class Server extends SimpleContainer implements IServerContainer { } /** + * Returns an \OCP\CacheFactory instance + * + * @return \OCP\CacheFactory + */ + function getMemCacheFactory() { + return $this->query('MemCacheFactory'); + } + + /** * Returns the current session * * @return \OCP\ISession @@ -250,6 +337,15 @@ class Server extends SimpleContainer implements IServerContainer { * @return \OCP\IDBConnection */ function getDatabaseConnection() { - return \OC_DB::getConnection(); + return new ConnectionWrapper(\OC_DB::getConnection()); + } + + /** + * Returns the activity manager + * + * @return \OCP\Activity\IManager + */ + function getActivityManager() { + return $this->query('ActivityManager'); } } diff --git a/lib/private/session/internal.php b/lib/private/session/internal.php index 60aecccc8aa..a7c9e2fdefd 100644 --- a/lib/private/session/internal.php +++ b/lib/private/session/internal.php @@ -26,10 +26,21 @@ class Internal extends Memory { } public function __destruct() { - $_SESSION = $this->data; + $_SESSION = array_merge($_SESSION, $this->data); session_write_close(); } + /** + * @param string $key + */ + public function remove($key) { + // also remove it from $_SESSION to prevent re-setting the old value during the merge + if (isset($_SESSION[$key])) { + unset($_SESSION[$key]); + } + parent::remove($key); + } + public function clear() { session_unset(); @session_regenerate_id(true); diff --git a/lib/private/session/memory.php b/lib/private/session/memory.php index c148ff4b9b9..134cee582ed 100644 --- a/lib/private/session/memory.php +++ b/lib/private/session/memory.php @@ -11,7 +11,7 @@ namespace OC\Session; /** * Class Internal * - * store session data in an in-memory array, not persistance + * store session data in an in-memory array, not persistent * * @package OC\Session */ diff --git a/lib/private/session/session.php b/lib/private/session/session.php index c55001eccac..fe160faa267 100644 --- a/lib/private/session/session.php +++ b/lib/private/session/session.php @@ -8,7 +8,10 @@ namespace OC\Session; -abstract class Session implements \ArrayAccess, \OCP\ISession { +use OCP\ISession; + +abstract class Session implements \ArrayAccess, ISession { + /** * $name serves as a namespace for the session keys * @@ -17,36 +20,6 @@ abstract class Session implements \ArrayAccess, \OCP\ISession { abstract public function __construct($name); /** - * @param string $key - * @param mixed $value - */ - abstract public function set($key, $value); - - /** - * @param string $key - * @return mixed should return null if $key does not exist - */ - abstract public function get($key); - - /** - * @param string $key - * @return bool - */ - abstract public function exists($key); - - /** - * should not throw any errors if $key does not exist - * - * @param string $key - */ - abstract public function remove($key); - - /** - * removes all entries within the cache namespace - */ - abstract public function clear(); - - /** * @param mixed $offset * @return bool */ diff --git a/lib/private/setup.php b/lib/private/setup.php index 6bf3c88370f..5232398d1d7 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -159,14 +159,28 @@ class OC_Setup { $content.= "</IfModule>\n"; $content.= "AddDefaultCharset utf-8\n"; $content.= "Options -Indexes\n"; + $content.= "<IfModule pagespeed_module>\n"; + $content.= "ModPagespeed Off\n"; + $content.= "</IfModule>\n"; @file_put_contents(OC::$SERVERROOT.'/.htaccess', $content); //supress errors in case we don't have permissions for it self::protectDataDirectory(); } public static function protectDataDirectory() { - $content = "deny from all\n"; - $content.= "IndexIgnore *"; + //Require all denied + $now = date('Y-m-d H:i:s'); + $content = "# Generated by ownCloud on $now\n"; + $content.= "# line below if for Apache 2.4\n"; + $content.= "<ifModule mod_authz_core>\n"; + $content.= "Require all denied\n"; + $content.= "</ifModule>\n\n"; + $content.= "# line below if for Apache 2.2\n"; + $content.= "<ifModule !mod_authz_core>\n"; + $content.= "deny from all\n"; + $content.= "</ifModule>\n\n"; + $content.= "# section for Apache 2.2 and 2.4\n"; + $content.= "IndexIgnore *\n"; file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/.htaccess', $content); file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/index.html', ''); } @@ -183,7 +197,7 @@ class OC_Setup { $error = $l->t('Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken.'); $hint = $l->t('Please double check the <a href=\'%s\'>installation guides</a>.', - 'http://doc.owncloud.org/server/5.0/admin_manual/installation.html'); + \OC_Helper::linkToDocs('admin-install')); OC_Template::printErrorPage($error, $hint); exit(); diff --git a/lib/private/setup/abstractdatabase.php b/lib/private/setup/abstractdatabase.php index 0beada7bd29..84625a217ee 100644 --- a/lib/private/setup/abstractdatabase.php +++ b/lib/private/setup/abstractdatabase.php @@ -3,6 +3,10 @@ namespace OC\Setup; abstract class AbstractDatabase { + + /** + * @var \OC_L10N + */ protected $trans; protected $dbDefinitionFile; protected $dbuser; diff --git a/lib/private/setup/oci.php b/lib/private/setup/oci.php index 326d7a00531..24863b9e38a 100644 --- a/lib/private/setup/oci.php +++ b/lib/private/setup/oci.php @@ -29,10 +29,10 @@ class OCI extends AbstractDatabase { \OC_Log::write('setup oracle', 'connect string: ' . $easy_connect_string, \OC_Log::DEBUG); $connection = @oci_connect($this->dbuser, $this->dbpassword, $easy_connect_string); if(!$connection) { - $e = oci_error(); - if (is_array ($e) && isset ($e['message'])) { + $errorMessage = $this->getLastError(); + if ($errorMessage) { throw new \DatabaseSetupException($this->trans->t('Oracle connection could not be established'), - $e['message'].' Check environment: ORACLE_HOME='.getenv('ORACLE_HOME') + $errorMessage.' Check environment: ORACLE_HOME='.getenv('ORACLE_HOME') .' ORACLE_SID='.getenv('ORACLE_SID') .' LD_LIBRARY_PATH='.getenv('LD_LIBRARY_PATH') .' NLS_LANG='.getenv('NLS_LANG') @@ -51,7 +51,7 @@ class OCI extends AbstractDatabase { ." WHERE user_role_privs.granted_role = role_sys_privs.role AND privilege = 'CREATE ROLE'"; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_last_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } @@ -68,25 +68,25 @@ class OCI extends AbstractDatabase { $this->dbpassword=\OC_Util::generateRandomBytes(30); //oracle passwords are treated as identifiers: - // must start with aphanumeric char + // must start with alphanumeric char // needs to be shortened to 30 bytes, as the two " needed to escape the identifier count towards the identifier length. $this->dbpassword=substr($this->dbpassword, 0, 30); $this->createDBUser($connection); - \OC_Config::setValue('dbuser', $this->dbusername); - \OC_Config::setValue('dbname', $this->dbusername); + \OC_Config::setValue('dbuser', $this->dbuser); + \OC_Config::setValue('dbname', $this->dbuser); \OC_Config::setValue('dbpassword', $this->dbpassword); - //create the database not neccessary, oracle implies user = schema - //$this->createDatabase($this->dbname, $this->dbusername, $connection); + //create the database not necessary, oracle implies user = schema + //$this->createDatabase($this->dbname, $this->dbuser, $connection); } else { \OC_Config::setValue('dbuser', $this->dbuser); \OC_Config::setValue('dbname', $this->dbname); \OC_Config::setValue('dbpassword', $this->dbpassword); - //create the database not neccessary, oracle implies user = schema + //create the database not necessary, oracle implies user = schema //$this->createDatabase($this->dbname, $this->dbuser, $connection); } @@ -115,10 +115,10 @@ class OCI extends AbstractDatabase { } $query = "SELECT count(*) FROM user_tables WHERE table_name = :un"; $stmt = oci_parse($connection, $query); - $un = $this->dbtableprefix.'users'; + $un = $this->tableprefix.'users'; oci_bind_by_name($stmt, ':un', $un); if (!$stmt) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } @@ -133,25 +133,22 @@ class OCI extends AbstractDatabase { } /** - * - * @param String $name - * @param String $password * @param resource $connection */ private function createDBUser($connection) { $name = $this->dbuser; - $password = $this->password; + $password = $this->dbpassword; $query = "SELECT * FROM all_users WHERE USERNAME = :un"; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } oci_bind_by_name($stmt, ':un', $name); $result = oci_execute($stmt); if(!$result) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } @@ -162,14 +159,14 @@ class OCI extends AbstractDatabase { $query = 'CREATE USER '.$name.' IDENTIFIED BY "'.$password.'" DEFAULT TABLESPACE '.$this->dbtablespace; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } //oci_bind_by_name($stmt, ':un', $name); $result = oci_execute($stmt); if(!$result) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s', array($query, $name, $password)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); @@ -178,7 +175,7 @@ class OCI extends AbstractDatabase { $query = "ALTER USER :un IDENTIFIED BY :pw"; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } @@ -186,7 +183,7 @@ class OCI extends AbstractDatabase { oci_bind_by_name($stmt, ':pw', $password); $result = oci_execute($stmt); if(!$result) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } @@ -195,16 +192,34 @@ class OCI extends AbstractDatabase { $query = 'GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER, UNLIMITED TABLESPACE TO '.$name; $stmt = oci_parse($connection, $query); if (!$stmt) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } $result = oci_execute($stmt); if(!$result) { - $entry = $this->trans->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; + $entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />'; $entry .= $this->trans->t('Offending command was: "%s", name: %s, password: %s', array($query, $name, $password)) . '<br />'; \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } } + + /** + * @param resource $connection + * @return string + */ + protected function getLastError($connection = null) { + if ($connection) { + $error = oci_error($connection); + } else { + $error = oci_error(); + } + foreach (array('message', 'code') as $key) { + if (isset($error[$key])) { + return $error[$key]; + } + } + return ''; + } } diff --git a/lib/private/tags.php b/lib/private/tags.php index 9fdb35a7d6e..fe7de1073a0 100644 --- a/lib/private/tags.php +++ b/lib/private/tags.php @@ -480,7 +480,7 @@ class Tags implements \OCP\ITags { return $this->getIdsForTag(self::TAG_FAVORITE); } catch(\Exception $e) { \OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(), - \OCP\Util::ERROR); + \OCP\Util::DEBUG); return array(); } } diff --git a/lib/private/template.php b/lib/private/template.php index 9b2c1211e61..b2c3a20f281 100644 --- a/lib/private/template.php +++ b/lib/private/template.php @@ -292,9 +292,8 @@ class OC_Template extends \OC\Template\Base { if (!empty($hint)) { $hint = '<pre>'.$hint.'</pre>'; } - $l = OC_L10N::get('lib'); while (method_exists($exception, 'previous') && $exception = $exception->previous()) { - $error_msg .= '<br/>'.$l->t('Caused by:').' '; + $error_msg .= '<br/>Caused by:' . ' '; if ($exception->getCode()) { $error_msg .= '['.$exception->getCode().'] '; } diff --git a/lib/private/template/functions.php b/lib/private/template/functions.php index 501f8081bff..ce42633b364 100644 --- a/lib/private/template/functions.php +++ b/lib/private/template/functions.php @@ -36,6 +36,14 @@ function link_to( $app, $file, $args = array() ) { } /** + * @param $key + * @return string url to the online documentation + */ +function link_to_docs($key) { + return OC_Helper::linkToDocs($key); +} + +/** * @brief make OC_Helper::imagePath available as a simple function * @param string $app app * @param string $image image @@ -85,22 +93,51 @@ function human_file_size( $bytes ) { return OC_Helper::humanFileSize( $bytes ); } -function relative_modified_date($timestamp) { +/** + * @brief Strips the timestamp of its time value + * @param int $timestamp UNIX timestamp to strip + * @return $timestamp without time value + */ +function strip_time($timestamp){ + $date = new \DateTime("@{$timestamp}"); + $date->setTime(0, 0, 0); + return intval($date->format('U')); +} + +/** + * @brief Formats timestamp relatively to the current time using + * a human-friendly format like "x minutes ago" or "yesterday" + * @param int $timestamp timestamp to format + * @param int $fromTime timestamp to compare from, defaults to current time + * @param bool $dateOnly whether to strip time information + * @return formatted timestamp + */ +function relative_modified_date($timestamp, $fromTime = null, $dateOnly = false) { $l=OC_L10N::get('lib'); - $timediff = time() - $timestamp; + if (!isset($fromTime) || $fromTime === null){ + $fromTime = time(); + } + if ($dateOnly){ + $fromTime = strip_time($fromTime); + $timestamp = strip_time($timestamp); + } + $timediff = $fromTime - $timestamp; $diffminutes = round($timediff/60); $diffhours = round($diffminutes/60); $diffdays = round($diffhours/24); $diffmonths = round($diffdays/31); - if($timediff < 60) { return $l->t('seconds ago'); } - else if($timediff < 3600) { return $l->n('%n minute ago', '%n minutes ago', $diffminutes); } - else if($timediff < 86400) { return $l->n('%n hour ago', '%n hours ago', $diffhours); } - else if((date('G')-$diffhours) > 0) { return $l->t('today'); } - else if((date('G')-$diffhours) > -24) { return $l->t('yesterday'); } + if(!$dateOnly && $timediff < 60) { return $l->t('seconds ago'); } + else if(!$dateOnly && $timediff < 3600) { return $l->n('%n minute ago', '%n minutes ago', $diffminutes); } + else if(!$dateOnly && $timediff < 86400) { return $l->n('%n hour ago', '%n hours ago', $diffhours); } + else if((date('G', $fromTime)-$diffhours) >= 0) { return $l->t('today'); } + else if((date('G', $fromTime)-$diffhours) >= -24) { return $l->t('yesterday'); } + // 86400 * 31 days = 2678400 else if($timediff < 2678400) { return $l->n('%n day go', '%n days ago', $diffdays); } + // 86400 * 60 days = 518400 else if($timediff < 5184000) { return $l->t('last month'); } - else if((date('n')-$diffmonths) > 0) { return $l->n('%n month ago', '%n months ago', $diffmonths); } + else if((date('n', $fromTime)-$diffmonths) > 0) { return $l->n('%n month ago', '%n months ago', $diffmonths); } + // 86400 * 365.25 days * 2 = 63113852 else if($timediff < 63113852) { return $l->t('last year'); } else { return $l->t('years ago'); } } diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index 625f3424a04..d5cd5039753 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -46,6 +46,7 @@ class OC_TemplateLayout extends OC_Template { $user_displayname = OC_User::getDisplayName(); $this->assign( 'user_displayname', $user_displayname ); $this->assign( 'user_uid', OC_User::getUser() ); + $this->assign( 'appsmanagement_active', strpos(OC_Request::requestUri(), OC_Helper::linkToRoute('settings_apps')) === 0 ); $this->assign('enableAvatars', \OC_Config::getValue('enable_avatars', true)); } else if ($renderas == 'guest' || $renderas == 'error') { parent::__construct('core', 'layout.guest'); diff --git a/lib/private/updater.php b/lib/private/updater.php index 9827d8a8c12..764a0f14120 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -37,7 +37,7 @@ class Updater extends BasicEmitter { /** * Check if a new version is available - * @param string $updateUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php' + * @param string $updaterUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php' * @return array | bool */ public function check($updaterUrl) { @@ -58,6 +58,7 @@ class Updater extends BasicEmitter { $version['updated'] = \OC_Appconfig::getValue('core', 'lastupdatedat'); $version['updatechannel'] = \OC_Util::getChannel(); $version['edition'] = \OC_Util::getEditionString(); + $version['build'] = \OC_Util::getBuild(); $versionString = implode('x', $version); //fetch xml data from updater @@ -115,6 +116,10 @@ class Updater extends BasicEmitter { \OC_App::checkAppsRequirements(); // load all apps to also upgrade enabled apps \OC_App::loadApps(); + + $repair = new Repair(); + $repair->run(); + \OC_Config::setValue('maintenance', false); $this->emit('\OC\Updater', 'maintenanceEnd'); } diff --git a/lib/private/urlgenerator.php b/lib/private/urlgenerator.php new file mode 100644 index 00000000000..4e3c1109000 --- /dev/null +++ b/lib/private/urlgenerator.php @@ -0,0 +1,152 @@ +<?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; +use OCP\IURLGenerator; +use RuntimeException; + +/** + * Class to generate URLs + */ +class URLGenerator implements IURLGenerator { + + /** + * @var \OCP\IConfig + */ + private $config; + + /** + * @param \OCP\IConfig $config + */ + public function __construct($config) { + $this->config = $config; + } + + /** + * @brief Creates an url using a defined route + * @param $route + * @param array $parameters + * @return + * @internal param array $args with param=>value, will be appended to the returned url + * @returns string the url + * + * Returns a url to the given app and file. + */ + public function linkToRoute($route, $parameters = array()) { + $urlLinkTo = \OC::getRouter()->generate($route, $parameters); + return $urlLinkTo; + } + + /** + * @brief Creates an url + * @param string $app app + * @param string $file file + * @param array $args array with param=>value, will be appended to the returned url + * The value of $args will be urlencoded + * @return string the url + * + * Returns a url to the given app and file. + */ + public function linkTo( $app, $file, $args = array() ) { + $frontControllerActive=($this->config->getSystemValue('front_controller_active', 'false') == 'true'); + + if( $app != '' ) { + $app_path = \OC_App::getAppPath($app); + // Check if the app is in the app folder + if ($app_path && file_exists($app_path . '/' . $file)) { + if (substr($file, -3) == 'php' || substr($file, -3) == 'css') { + + $urlLinkTo = \OC::$WEBROOT . '/index.php/apps/' . $app; + if ($frontControllerActive) { + $urlLinkTo = \OC::$WEBROOT . '/apps/' . $app; + } + $urlLinkTo .= ($file != 'index.php') ? '/' . $file : ''; + } else { + $urlLinkTo = \OC_App::getAppWebPath($app) . '/' . $file; + } + } else { + $urlLinkTo = \OC::$WEBROOT . '/' . $app . '/' . $file; + } + } else { + if (file_exists(\OC::$SERVERROOT . '/core/' . $file)) { + $urlLinkTo = \OC::$WEBROOT . '/core/' . $file; + } else { + if ($frontControllerActive && $file === 'index.php') { + $urlLinkTo = \OC::$WEBROOT; + } else { + $urlLinkTo = \OC::$WEBROOT . '/' . $file; + } + } + } + + if ($args && $query = http_build_query($args, '', '&')) { + $urlLinkTo .= '?' . $query; + } + + return $urlLinkTo; + } + + /** + * @brief Creates path to an image + * @param string $app app + * @param string $image image name + * @return string the url + * + * Returns the path to the image. + */ + public function imagePath($app, $image) { + // Read the selected theme from the config file + $theme = \OC_Util::getTheme(); + + //if a theme has a png but not an svg always use the png + $basename = substr(basename($image),0,-4); + + // Check if the app is in the app folder + if (file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$image")) { + return \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$image"; + } elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.svg") + && file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.png")) { + return \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$basename.png"; + } elseif (file_exists(\OC_App::getAppPath($app) . "/img/$image")) { + return \OC_App::getAppWebPath($app) . "/img/$image"; + } elseif (!file_exists(\OC_App::getAppPath($app) . "/img/$basename.svg") + && file_exists(\OC_App::getAppPath($app) . "/img/$basename.png")) { + return \OC_App::getAppPath($app) . "/img/$basename.png"; + } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$image")) { + return \OC::$WEBROOT . "/themes/$theme/$app/img/$image"; + } elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$basename.svg") + && file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$basename.png"))) { + return \OC::$WEBROOT . "/themes/$theme/$app/img/$basename.png"; + } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/$app/img/$image")) { + return \OC::$WEBROOT . "/$app/img/$image"; + } elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/$app/img/$basename.svg") + && file_exists(\OC::$SERVERROOT . "/$app/img/$basename.png"))) { + return \OC::$WEBROOT . "/$app/img/$basename.png"; + } elseif (file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$image")) { + return \OC::$WEBROOT . "/themes/$theme/core/img/$image"; + } elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.svg") + && file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.png")) { + return \OC::$WEBROOT . "/themes/$theme/core/img/$basename.png"; + } elseif (file_exists(\OC::$SERVERROOT . "/core/img/$image")) { + return \OC::$WEBROOT . "/core/img/$image"; + } else { + throw new RuntimeException('image not found: image:' . $image . ' webroot:' . \OC::$WEBROOT . ' serverroot:' . \OC::$SERVERROOT); + } + } + + + /** + * Makes an URL absolute + * @param string $url the url in the owncloud host + * @return string the absolute version of the url + */ + public function getAbsoluteURL($url) { + return \OC_Request::serverProtocol() . '://' . \OC_Request::serverHost() . $url; + } +} diff --git a/lib/private/user.php b/lib/private/user.php index 15e807088b4..98ebebbe5c1 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -54,6 +54,9 @@ class OC_User { private static $_setupedBackends = array(); + // bool, stores if a user want to access a resource anonymously, e.g if he opens a public link + private static $incognitoMode = false; + /** * @brief registers backend * @param string $backend name of the backend @@ -187,17 +190,28 @@ class OC_User { public static function deleteUser($uid) { $user = self::getManager()->get($uid); if ($user) { - $user->delete(); + $result = $user->delete(); + + // if delete was successful we clean-up the rest + if ($result) { + + // We have to delete the user from all groups + foreach (OC_Group::getUserGroups($uid) as $i) { + OC_Group::removeFromGroup($uid, $i); + } + // Delete the user's keys in preferences + OC_Preferences::deleteUser($uid); - // We have to delete the user from all groups - foreach (OC_Group::getUserGroups($uid) as $i) { - OC_Group::removeFromGroup($uid, $i); + // Delete user files in /data/ + OC_Helper::rmdirr(\OC_User::getHome($uid)); + + // Remove it from the Cache + self::getManager()->delete($uid); } - // Delete the user's keys in preferences - OC_Preferences::deleteUser($uid); - // Delete user files in /data/ - OC_Helper::rmdirr(OC_Config::getValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $uid . '/'); + return true; + } else { + return false; } } @@ -214,6 +228,57 @@ class OC_User { } /** + * @brief Try to login a user, assuming authentication + * has already happened (e.g. via Single Sign On). + * + * Log in a user and regenerate a new session. + * + * @param \OCP\Authentication\IApacheBackend $backend + * @return bool + */ + public static function loginWithApache(\OCP\Authentication\IApacheBackend $backend) { + + $uid = $backend->getCurrentUserId(); + $run = true; + OC_Hook::emit( "OC_User", "pre_login", array( "run" => &$run, "uid" => $uid )); + + if($uid) { + session_regenerate_id(true); + self::setUserId($uid); + self::setDisplayName($uid); + self::getUserSession()->setLoginName($uid); + + OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>'' )); + return true; + } + return false; + } + + /** + * @brief Verify with Apache whether user is authenticated. + * + * @return boolean|null + * true: authenticated + * false: not authenticated + * null: not handled / no backend available + */ + public static function handleApacheAuth() { + $backend = self::findFirstActiveUsedBackend(); + if ($backend) { + OC_App::loadApps(); + + //setup extra user backends + self::setupBackends(); + self::unsetMagicInCookie(); + + return self::loginWithApache($backend); + } + + return null; + } + + + /** * @brief Sets user id for session and triggers emit */ public static function setUserId($uid) { @@ -251,7 +316,7 @@ class OC_User { * Checks if the user is logged in */ public static function isLoggedIn() { - if (\OC::$session->get('user_id')) { + if (\OC::$session->get('user_id') && self::$incognitoMode === false) { OC_App::loadApps(array('authentication')); self::setupBackends(); return self::userExists(\OC::$session->get('user_id')); @@ -260,12 +325,37 @@ class OC_User { } /** + * @brief set incognito mode, e.g. if a user wants to open a public link + * @param bool $status + */ + public static function setIncognitoMode($status) { + self::$incognitoMode = $status; + + } + + /** + * Supplies an attribute to the logout hyperlink. The default behaviour + * is to return an href with '?logout=true' appended. However, it can + * supply any attribute(s) which are valid for <a>. + * + * @return string with one or more HTML attributes. + */ + public static function getLogoutAttribute() { + $backend = self::findFirstActiveUsedBackend(); + if ($backend) { + return $backend->getLogoutAttribute(); + } + + return 'href="' . link_to('', 'index.php') . '?logout=true"'; + } + + /** * @brief Check if the user is an admin user * @param string $uid uid of the admin * @return bool */ public static function isAdminUser($uid) { - if (OC_Group::inGroup($uid, 'admin')) { + if (OC_Group::inGroup($uid, 'admin') && self::$incognitoMode === false) { return true; } return false; @@ -278,7 +368,7 @@ class OC_User { */ public static function getUser() { $uid = OC::$session ? OC::$session->get('user_id') : null; - if (!is_null($uid)) { + if (!is_null($uid) && self::$incognitoMode === false) { return $uid; } else { return false; @@ -337,6 +427,22 @@ class OC_User { } /** + * @brief Check whether user can change his avatar + * @param string $uid The username + * @return bool + * + * Check whether a specified user can change his avatar + */ + public static function canUserChangeAvatar($uid) { + $user = self::getManager()->get($uid); + if ($user) { + return $user->canChangeAvatar(); + } else { + return false; + } + } + + /** * @brief Check whether user can change his password * @param string $uid The username * @return bool @@ -497,4 +603,20 @@ class OC_User { public static function unsetMagicInCookie() { self::getUserSession()->unsetMagicInCookie(); } + + /** + * @brief Returns the first active backend from self::$_usedBackends. + * @return null if no backend active, otherwise OCP\Authentication\IApacheBackend + */ + private static function findFirstActiveUsedBackend() { + foreach (self::$_usedBackends as $backend) { + if ($backend instanceof OCP\Authentication\IApacheBackend) { + if ($backend->isSessionActive()) { + return $backend; + } + } + } + + return null; + } } diff --git a/lib/private/user/backend.php b/lib/private/user/backend.php index e9be08e429c..f4e5618e04a 100644 --- a/lib/private/user/backend.php +++ b/lib/private/user/backend.php @@ -31,13 +31,15 @@ define('OC_USER_BACKEND_NOT_IMPLEMENTED', -501); /** * actions that user backends can define */ -define('OC_USER_BACKEND_CREATE_USER', 0x000001); -define('OC_USER_BACKEND_SET_PASSWORD', 0x000010); -define('OC_USER_BACKEND_CHECK_PASSWORD', 0x000100); -define('OC_USER_BACKEND_GET_HOME', 0x001000); -define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x010000); -define('OC_USER_BACKEND_SET_DISPLAYNAME', 0x100000); - +define('OC_USER_BACKEND_CREATE_USER', 0x00000001); +define('OC_USER_BACKEND_SET_PASSWORD', 0x00000010); +define('OC_USER_BACKEND_CHECK_PASSWORD', 0x00000100); +define('OC_USER_BACKEND_GET_HOME', 0x00001000); +define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x00010000); +define('OC_USER_BACKEND_SET_DISPLAYNAME', 0x00100000); +define('OC_USER_BACKEND_PROVIDE_AVATAR', 0x01000000); +define('OC_USER_BACKEND_COUNT_USERS', 0x10000000); +//more actions cannot be defined without breaking 32bit platforms! /** * Abstract base class for user management. Provides methods for querying backend @@ -54,6 +56,8 @@ abstract class OC_User_Backend implements OC_User_Interface { OC_USER_BACKEND_GET_HOME => 'getHome', OC_USER_BACKEND_GET_DISPLAYNAME => 'getDisplayName', OC_USER_BACKEND_SET_DISPLAYNAME => 'setDisplayName', + OC_USER_BACKEND_PROVIDE_AVATAR => 'canChangeAvatar', + OC_USER_BACKEND_COUNT_USERS => 'countUsers', ); /** diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 9f00a022d9f..1a63755b980 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -42,13 +42,13 @@ class OC_User_Database extends OC_User_Backend { /** * @var PasswordHash */ - static private $hasher=null; + static private $hasher = null; private function getHasher() { - if(!self::$hasher) { + if (!self::$hasher) { //we don't want to use DES based crypt(), since it doesn't return a hash with a recognisable prefix - $forcePortable=(CRYPT_BLOWFISH!=1); - self::$hasher=new PasswordHash(8, $forcePortable); + $forcePortable = (CRYPT_BLOWFISH != 1); + self::$hasher = new PasswordHash(8, $forcePortable); } return self::$hasher; @@ -63,14 +63,14 @@ class OC_User_Database extends OC_User_Backend { * Creates a new user. Basic checking of username is done in OC_User * itself, not in its subclasses. */ - public function createUser( $uid, $password ) { - if( $this->userExists($uid) ) { + public function createUser($uid, $password) { + if ($this->userExists($uid)) { return false; - }else{ - $hasher=$this->getHasher(); - $hash = $hasher->HashPassword($password.OC_Config::getValue('passwordsalt', '')); - $query = OC_DB::prepare( 'INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )' ); - $result = $query->execute( array( $uid, $hash)); + } else { + $hasher = $this->getHasher(); + $hash = $hasher->HashPassword($password . OC_Config::getValue('passwordsalt', '')); + $query = OC_DB::prepare('INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )'); + $result = $query->execute(array($uid, $hash)); return $result ? true : false; } @@ -83,10 +83,10 @@ class OC_User_Database extends OC_User_Backend { * * Deletes a user */ - public function deleteUser( $uid ) { + public function deleteUser($uid) { // Delete user-group-relation - $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*users` WHERE `uid` = ?' ); - $query->execute( array( $uid )); + $query = OC_DB::prepare('DELETE FROM `*PREFIX*users` WHERE `uid` = ?'); + $query->execute(array($uid)); return true; } @@ -98,15 +98,15 @@ class OC_User_Database extends OC_User_Backend { * * Change the password of a user */ - public function setPassword( $uid, $password ) { - if( $this->userExists($uid) ) { - $hasher=$this->getHasher(); - $hash = $hasher->HashPassword($password.OC_Config::getValue('passwordsalt', '')); - $query = OC_DB::prepare( 'UPDATE `*PREFIX*users` SET `password` = ? WHERE `uid` = ?' ); - $query->execute( array( $hash, $uid )); + public function setPassword($uid, $password) { + if ($this->userExists($uid)) { + $hasher = $this->getHasher(); + $hash = $hasher->HashPassword($password . OC_Config::getValue('passwordsalt', '')); + $query = OC_DB::prepare('UPDATE `*PREFIX*users` SET `password` = ? WHERE `uid` = ?'); + $query->execute(array($hash, $uid)); return true; - }else{ + } else { return false; } } @@ -119,12 +119,12 @@ class OC_User_Database extends OC_User_Backend { * * Change the display name of a user */ - public function setDisplayName( $uid, $displayName ) { - if( $this->userExists($uid) ) { - $query = OC_DB::prepare( 'UPDATE `*PREFIX*users` SET `displayname` = ? WHERE `uid` = ?' ); - $query->execute( array( $displayName, $uid )); + public function setDisplayName($uid, $displayName) { + if ($this->userExists($uid)) { + $query = OC_DB::prepare('UPDATE `*PREFIX*users` SET `displayname` = ? WHERE LOWER(`uid`) = ?'); + $query->execute(array($displayName, $uid)); return true; - }else{ + } else { return false; } } @@ -132,18 +132,16 @@ class OC_User_Database extends OC_User_Backend { /** * @brief get display name of the user * @param $uid user ID of the user - * @return display name + * @return string display name */ public function getDisplayName($uid) { - if( $this->userExists($uid) ) { - $query = OC_DB::prepare( 'SELECT `displayname` FROM `*PREFIX*users` WHERE `uid` = ?' ); - $result = $query->execute( array( $uid ))->fetchAll(); - $displayName = trim($result[0]['displayname'], ' '); - if ( !empty($displayName) ) { - return $displayName; - } else { - return $uid; - } + $query = OC_DB::prepare('SELECT `displayname` FROM `*PREFIX*users` WHERE `uid` = ?'); + $result = $query->execute(array($uid))->fetchAll(); + $displayName = trim($result[0]['displayname'], ' '); + if (!empty($displayName)) { + return $displayName; + } else { + return $uid; } } @@ -156,25 +154,14 @@ class OC_User_Database extends OC_User_Backend { public function getDisplayNames($search = '', $limit = null, $offset = null) { $displayNames = array(); $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users`' - .' WHERE LOWER(`displayname`) LIKE LOWER(?)', $limit, $offset); - $result = $query->execute(array($search.'%')); + . ' WHERE LOWER(`displayname`) LIKE LOWER(?) OR ' + . 'LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); + $result = $query->execute(array($search . '%', $search . '%')); $users = array(); while ($row = $result->fetchRow()) { $displayNames[$row['uid']] = $row['displayname']; } - // let's see if we can also find some users who don't have a display name yet - $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users`' - .' WHERE LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); - $result = $query->execute(array($search.'%')); - while ($row = $result->fetchRow()) { - $displayName = trim($row['displayname'], ' '); - if ( empty($displayName) ) { - $displayNames[$row['uid']] = $row['uid']; - } - } - - return $displayNames; } @@ -187,30 +174,30 @@ class OC_User_Database extends OC_User_Backend { * Check if the password is correct without logging in the user * returns the user id or false */ - public function checkPassword( $uid, $password ) { - $query = OC_DB::prepare( 'SELECT `uid`, `password` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)' ); - $result = $query->execute( array( $uid)); + public function checkPassword($uid, $password) { + $query = OC_DB::prepare('SELECT `uid`, `password` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)'); + $result = $query->execute(array($uid)); - $row=$result->fetchRow(); - if($row) { - $storedHash=$row['password']; - if ($storedHash[0]=='$') {//the new phpass based hashing - $hasher=$this->getHasher(); - if($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), $storedHash)) { + $row = $result->fetchRow(); + if ($row) { + $storedHash = $row['password']; + if ($storedHash[0] == '$') { //the new phpass based hashing + $hasher = $this->getHasher(); + if ($hasher->CheckPassword($password . OC_Config::getValue('passwordsalt', ''), $storedHash)) { return $row['uid']; - }else{ + } else { return false; } - }else{//old sha1 based hashing - if(sha1($password)==$storedHash) { + } else { //old sha1 based hashing + if (sha1($password) == $storedHash) { //upgrade to new hashing $this->setPassword($row['uid'], $password); return $row['uid']; - }else{ + } else { return false; } } - }else{ + } else { return false; } } @@ -223,7 +210,7 @@ class OC_User_Database extends OC_User_Backend { */ public function getUsers($search = '', $limit = null, $offset = null) { $query = OC_DB::prepare('SELECT `uid` FROM `*PREFIX*users` WHERE LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); - $result = $query->execute(array($search.'%')); + $result = $query->execute(array($search . '%')); $users = array(); while ($row = $result->fetchRow()) { $users[] = $row['uid']; @@ -237,8 +224,8 @@ class OC_User_Database extends OC_User_Backend { * @return boolean */ public function userExists($uid) { - $query = OC_DB::prepare( 'SELECT COUNT(*) FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)' ); - $result = $query->execute( array( $uid )); + $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)'); + $result = $query->execute(array($uid)); if (OC_DB::isError($result)) { OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); return false; @@ -247,14 +234,14 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief get the user's home directory - * @param string $uid the username - * @return boolean - */ + * @brief get the user's home directory + * @param string $uid the username + * @return boolean + */ public function getHome($uid) { - if($this->userExists($uid)) { - return OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ) . '/' . $uid; - }else{ + if ($this->userExists($uid)) { + return OC_Config::getValue("datadirectory", OC::$SERVERROOT . "/data") . '/' . $uid; + } else { return false; } } @@ -266,4 +253,19 @@ class OC_User_Database extends OC_User_Backend { return true; } + /** + * counts the users in the database + * + * @return int | bool + */ + public function countUsers() { + $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`'); + $result = $query->execute(); + if (OC_DB::isError($result)) { + OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + return $result->fetchOne(); + } + } diff --git a/lib/private/user/dummy.php b/lib/private/user/dummy.php index b5b7a6c3c7a..fc15a630cf3 100644 --- a/lib/private/user/dummy.php +++ b/lib/private/user/dummy.php @@ -88,8 +88,8 @@ class OC_User_Dummy extends OC_User_Backend { * returns the user id or false */ public function checkPassword($uid, $password) { - if (isset($this->users[$uid])) { - return ($this->users[$uid] == $password); + if (isset($this->users[$uid]) && $this->users[$uid] === $password) { + return $uid; } else { return false; } @@ -123,4 +123,13 @@ class OC_User_Dummy extends OC_User_Backend { public function hasUserListings() { return true; } + + /** + * counts the users in the database + * + * @return int | bool + */ + public function countUsers() { + return 0; + } } diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index 13286bc28a4..90970ef9963 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -35,7 +35,16 @@ class Manager extends PublicEmitter { */ private $cachedUsers = array(); - public function __construct() { + /** + * @var \OC\AllConfig $config + */ + private $config; + + /** + * @param \OC\AllConfig $config + */ + public function __construct($config = null) { + $this->config = $config; $cachedUsers = $this->cachedUsers; $this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) { $i = array_search($user, $cachedUsers); @@ -103,7 +112,7 @@ class Manager extends PublicEmitter { if (isset($this->cachedUsers[$uid])) { return $this->cachedUsers[$uid]; } - $this->cachedUsers[$uid] = new User($uid, $backend, $this); + $this->cachedUsers[$uid] = new User($uid, $backend, $this, $this->config); return $this->cachedUsers[$uid]; } @@ -119,6 +128,20 @@ class Manager extends PublicEmitter { } /** + * remove deleted user from cache + * + * @param string $uid + * @return bool + */ + public function delete($uid) { + if (isset($this->cachedUsers[$uid])) { + unset($this->cachedUsers[$uid]); + return true; + } + return false; + } + + /** * Check if the password is valid for the user * * @param $loginname @@ -127,7 +150,7 @@ class Manager extends PublicEmitter { */ public function checkPassword($loginname, $password) { foreach ($this->backends as $backend) { - if($backend->implementsActions(\OC_USER_BACKEND_CHECK_PASSWORD)) { + if ($backend->implementsActions(\OC_USER_BACKEND_CHECK_PASSWORD)) { $uid = $backend->checkPassword($loginname, $password); if ($uid !== false) { return $this->getUserObject($uid, $backend); @@ -220,7 +243,7 @@ class Manager extends PublicEmitter { // Allowed are: "a-z", "A-Z", "0-9" and "_.@-" if (preg_match('/[^a-zA-Z0-9 _\.@\-]/', $uid)) { throw new \Exception('Only the following characters are allowed in a username:' - . ' "a-z", "A-Z", "0-9", and "_.@-"'); + . ' "a-z", "A-Z", "0-9", and "_.@-"'); } // No empty username if (trim($uid) == '') { @@ -247,4 +270,26 @@ class Manager extends PublicEmitter { } return false; } + + /** + * returns how many users per backend exist (if supported by backend) + * + * @return array with backend class as key and count number as value + */ + public function countUsers() { + $userCountStatistics = array(); + foreach ($this->backends as $backend) { + if ($backend->implementsActions(\OC_USER_BACKEND_COUNT_USERS)) { + $backendusers = $backend->countUsers(); + if($backendusers !== false) { + if(isset($userCountStatistics[get_class($backend)])) { + $userCountStatistics[get_class($backend)] += $backendusers; + } else { + $userCountStatistics[get_class($backend)] = $backendusers; + } + } + } + } + return $userCountStatistics; + } } diff --git a/lib/private/user/session.php b/lib/private/user/session.php index 525c65ab8a1..1e299416fb3 100644 --- a/lib/private/user/session.php +++ b/lib/private/user/session.php @@ -113,6 +113,38 @@ class Session implements Emitter, \OCP\IUserSession { } /** + * set the login name + * + * @param string $loginName for the logged in user + */ + public function setLoginName($loginName) { + if (is_null($loginName)) { + $this->session->remove('loginname'); + } else { + $this->session->set('loginname', $loginName); + } + } + + /** + * get the login name of the current user + * + * @return string + */ + public function getLoginName() { + if ($this->activeUser) { + return $this->session->get('loginname'); + } else { + $uid = $this->session->get('user_id'); + if ($uid) { + $this->activeUser = $this->manager->get($uid); + return $this->session->get('loginname'); + } else { + return null; + } + } + } + + /** * try to login with the provided credentials * * @param string $uid @@ -126,6 +158,7 @@ class Session implements Emitter, \OCP\IUserSession { if (!is_null($user)) { if ($user->isEnabled()) { $this->setUser($user); + $this->setLoginName($uid); $this->manager->emit('\OC\User', 'postLogin', array($user, $password)); return true; } else { @@ -143,6 +176,7 @@ class Session implements Emitter, \OCP\IUserSession { public function logout() { $this->manager->emit('\OC\User', 'logout'); $this->setUser(null); + $this->setLoginName(null); $this->unsetMagicInCookie(); } @@ -170,5 +204,10 @@ class Session implements Emitter, \OCP\IUserSession { setcookie('oc_username', '', time()-3600, \OC::$WEBROOT); setcookie('oc_token', '', time()-3600, \OC::$WEBROOT); setcookie('oc_remember_login', '', time()-3600, \OC::$WEBROOT); + // old cookies might be stored under /webroot/ instead of /webroot + // and Firefox doesn't like it! + setcookie('oc_username', '', time()-3600, \OC::$WEBROOT . '/'); + setcookie('oc_token', '', time()-3600, \OC::$WEBROOT . '/'); + setcookie('oc_remember_login', '', time()-3600, \OC::$WEBROOT . '/'); } } diff --git a/lib/private/user/user.php b/lib/private/user/user.php index e5f842944f1..ef5364cbf7b 100644 --- a/lib/private/user/user.php +++ b/lib/private/user/user.php @@ -38,11 +38,22 @@ class User { private $emitter; /** + * @var string $home + */ + private $home; + + /** + * @var \OC\AllConfig $config + */ + private $config; + + /** * @param string $uid * @param \OC_User_Backend $backend - * @param Emitter $emitter + * @param \OC\Hooks\Emitter $emitter + * @param \OC\AllConfig $config */ - public function __construct($uid, $backend, $emitter = null) { + public function __construct($uid, $backend, $emitter = null, $config = null) { $this->uid = $uid; if ($backend and $backend->implementsActions(OC_USER_BACKEND_GET_DISPLAYNAME)) { $this->displayName = $backend->getDisplayName($uid); @@ -51,8 +62,13 @@ class User { } $this->backend = $backend; $this->emitter = $emitter; - $enabled = \OC_Preferences::getValue($uid, 'core', 'enabled', 'true'); //TODO: DI for OC_Preferences - $this->enabled = ($enabled === 'true'); + $this->config = $config; + if ($this->config) { + $enabled = $this->config->getUserValue($uid, 'core', 'enabled', 'true'); + $this->enabled = ($enabled === 'true'); + } else { + $this->enabled = true; + } } /** @@ -133,10 +149,28 @@ class User { * @return string */ public function getHome() { - if ($this->backend->implementsActions(\OC_USER_BACKEND_GET_HOME) and $home = $this->backend->getHome($this->uid)) { - return $home; + if (!$this->home) { + if ($this->backend->implementsActions(\OC_USER_BACKEND_GET_HOME) and $home = $this->backend->getHome($this->uid)) { + $this->home = $home; + } elseif ($this->config) { + $this->home = $this->config->getSystemValue('datadirectory') . '/' . $this->uid; + } else { + $this->home = \OC::$SERVERROOT . '/data/' . $this->uid; + } + } + return $this->home; + } + + /** + * check if the backend allows the user to change his avatar on Personal page + * + * @return bool + */ + public function canChangeAvatar() { + if ($this->backend->implementsActions(\OC_USER_BACKEND_PROVIDE_AVATAR)) { + return $this->backend->canChangeAvatar($this->uid); } - return \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data") . '/' . $this->uid; //TODO switch to Config object once implemented + return true; } /** @@ -154,7 +188,11 @@ class User { * @return bool */ public function canChangeDisplayName() { - return $this->backend->implementsActions(\OC_USER_BACKEND_SET_DISPLAYNAME); + if ($this->config and $this->config->getSystemValue('allow_user_to_change_display_name') === false) { + return false; + } else { + return $this->backend->implementsActions(\OC_USER_BACKEND_SET_DISPLAYNAME); + } } /** @@ -173,7 +211,9 @@ class User { */ public function setEnabled($enabled) { $this->enabled = $enabled; - $enabled = ($enabled) ? 'true' : 'false'; - \OC_Preferences::setValue($this->uid, 'core', 'enabled', $enabled); + if ($this->config) { + $enabled = ($enabled) ? 'true' : 'false'; + $this->config->setUserValue($this->uid, 'core', 'enabled', $enabled); + } } } diff --git a/lib/private/util.php b/lib/private/util.php index ea2eb98d23c..0585749d615 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -51,23 +51,33 @@ class OC_Util { self::$rootMounted = true; } + if ($user != '' && !OCP\User::userExists($user)) { + return false; + } + //if we aren't logged in, there is no use to set up the filesystem if( $user != "" ) { - $quota = self::getUserQuota($user); - if ($quota !== \OC\Files\SPACE_UNLIMITED) { - \OC\Files\Filesystem::addStorageWrapper(function($mountPoint, $storage) use ($quota, $user) { - if ($mountPoint === '/' . $user . '/'){ + \OC\Files\Filesystem::addStorageWrapper(function($mountPoint, $storage){ + // set up quota for home storages, even for other users + // which can happen when using sharing + + if ($storage instanceof \OC\Files\Storage\Home) { + $user = $storage->getUser()->getUID(); + $quota = OC_Util::getUserQuota($user); + if ($quota !== \OC\Files\SPACE_UNLIMITED) { return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $quota)); - } else { - return $storage; } - }); - } + } + + return $storage; + }); + $userDir = '/'.$user.'/files'; $userRoot = OC_User::getHome($user); $userDirectory = $userRoot . '/files'; if( !is_dir( $userDirectory )) { mkdir( $userDirectory, 0755, true ); + OC_Util::copySkeleton($userDirectory); } //jail the user into his "home" directory \OC\Files\Filesystem::init($user, $userDir); @@ -93,6 +103,35 @@ class OC_Util { } /** + * @brief copies the user skeleton files into the fresh user home files + * @param string $userDirectory + */ + public static function copySkeleton($userDirectory) { + OC_Util::copyr(\OC::$SERVERROOT.'/core/skeleton' , $userDirectory); + } + + /** + * @brief copies a directory recursively + * @param string $source + * @param string $target + * @return void + */ + public static function copyr($source,$target) { + $dir = opendir($source); + @mkdir($target); + while(false !== ( $file = readdir($dir)) ) { + if ( !\OC\Files\Filesystem::isIgnoredDir($file) ) { + if ( is_dir($source . '/' . $file) ) { + OC_Util::copyr($source . '/' . $file , $target . '/' . $file); + } else { + copy($source . '/' . $file,$target . '/' . $file); + } + } + } + closedir($dir); + } + + /** * @return void */ public static function tearDownFS() { @@ -138,7 +177,7 @@ class OC_Util { OC_Util::loadVersion(); return \OC::$server->getSession()->get('OC_Channel'); } - + /** * @description get the build number of the current installed of ownCloud. * @return string @@ -152,9 +191,12 @@ class OC_Util { * @description load the version.php into the session as cache */ private static function loadVersion() { - if(!\OC::$server->getSession()->exists('OC_Version')) { + $timestamp = filemtime(OC::$SERVERROOT.'/version.php'); + if(!\OC::$server->getSession()->exists('OC_Version') or OC::$server->getSession()->get('OC_Version_Timestamp') != $timestamp) { require 'version.php'; $session = \OC::$server->getSession(); + /** @var $timestamp int */ + $session->set('OC_Version_Timestamp', $timestamp); /** @var $OC_Version string */ $session->set('OC_Version', $OC_Version); /** @var $OC_VersionString string */ @@ -270,16 +312,16 @@ class OC_Util { //common hint for all file permissions error messages $permissionsHint = 'Permissions can usually be fixed by ' - .'<a href="' . $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html' - .'#set-the-directory-permissions" target="_blank">giving the webserver write access to the root directory</a>.'; + .'<a href="' . OC_Helper::linkToDocs('admin-dir_permissions') + .'" target="_blank">giving the webserver write access to the root directory</a>.'; // Check if config folder is writable. - if(!is_writable(OC::$SERVERROOT."/config/") or !is_readable(OC::$SERVERROOT."/config/")) { + if(!is_writable(OC::$configDir) or !is_readable(OC::$configDir)) { $errors[] = array( 'error' => "Can't write into config directory", 'hint' => 'This can usually be fixed by ' - .'<a href="' . $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html' - .'#set-the-directory-permissions" target="_blank">giving the webserver write access to the config directory</a>.' + .'<a href="' . OC_Helper::linkToDocs('admin-dir_permissions') + .'" target="_blank">giving the webserver write access to the config directory</a>.' ); } @@ -291,8 +333,8 @@ class OC_Util { $errors[] = array( 'error' => "Can't write into apps directory", 'hint' => 'This can usually be fixed by ' - .'<a href="' . $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html' - .'#set-the-directory-permissions" target="_blank">giving the webserver write access to the apps directory</a> ' + .'<a href="' . OC_Helper::linkToDocs('admin-dir_permissions') + .'" target="_blank">giving the webserver write access to the apps directory</a> ' .'or disabling the appstore in the config file.' ); } @@ -307,8 +349,8 @@ class OC_Util { $errors[] = array( 'error' => "Can't create data directory (".$CONFIG_DATADIRECTORY.")", 'hint' => 'This can usually be fixed by ' - .'<a href="' . $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html' - .'#set-the-directory-permissions" target="_blank">giving the webserver write access to the root directory</a>.' + .'<a href="' . OC_Helper::linkToDocs('admin-dir_permissions') + .'" target="_blank">giving the webserver write access to the root directory</a>.' ); } } else if(!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) { @@ -320,6 +362,13 @@ class OC_Util { $errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY)); } + if(!OC_Util::isSetLocaleWorking()) { + $errors[] = array( + 'error' => 'Setting locale to en_US.UTF-8/fr_FR.UTF-8/es_ES.UTF-8/de_DE.UTF-8/ru_RU.UTF-8/pt_BR.UTF-8/it_IT.UTF-8/ja_JP.UTF-8/zh_CN.UTF-8 failed', + 'hint' => 'Please install one of theses locales on your system and restart your webserver.' + ); + } + $moduleHint = "Please ask your server administrator to install the module."; // check if all required php modules are present if(!class_exists('ZipArchive')) { @@ -392,11 +441,11 @@ class OC_Util { ); $webServerRestart = true; } - if(floatval(phpversion()) < 5.3) { + if(version_compare(phpversion(), '5.3.3', '<')) { $errors[] = array( - 'error'=>'PHP 5.3 is required.', - 'hint'=>'Please ask your server administrator to update PHP to version 5.3 or higher.' - .' PHP 5.2 is no longer supported by ownCloud and the PHP community.' + 'error'=>'PHP 5.3.3 or higher is required.', + 'hint'=>'Please ask your server administrator to update PHP to the latest version.' + .' Your PHP version is no longer supported by ownCloud and the PHP community.' ); $webServerRestart = true; } @@ -535,7 +584,7 @@ class OC_Util { // Check if we are a user if( !OC_User::isLoggedIn()) { header( 'Location: '.OC_Helper::linkToAbsolute( '', 'index.php', - array('redirectUrl' => OC_Request::requestUri()) + array('redirect_url' => OC_Request::requestUri()) )); exit(); } @@ -546,6 +595,7 @@ class OC_Util { * @return void */ public static function checkAdminUser() { + OC_Util::checkLoggedIn(); if( !OC_User::isAdminUser(OC_User::getUser())) { header( 'Location: '.OC_Helper::linkToAbsolute( '', 'index.php' )); exit(); @@ -578,6 +628,7 @@ class OC_Util { * @return array $groups where the current user is subadmin */ public static function checkSubAdminUser() { + OC_Util::checkLoggedIn(); if(!OC_SubAdmin::isSubAdmin(OC_User::getUser())) { header( 'Location: '.OC_Helper::linkToAbsolute( '', 'index.php' )); exit(); @@ -617,7 +668,7 @@ class OC_Util { if(is_null($id)) { // We need to guarantee at least one letter in instanceid so it can be used as the session_name $id = 'oc' . self::generateRandomBytes(10); - OC_Config::setValue('instanceid', $id); + OC_Config::$object->setValue('instanceid', $id); } return $id; } @@ -665,29 +716,7 @@ class OC_Util { * @see OC_Util::callRegister() */ public static function isCallRegistered() { - if(!\OC::$session->exists('requesttoken')) { - return false; - } - - if(isset($_GET['requesttoken'])) { - $token = $_GET['requesttoken']; - } elseif(isset($_POST['requesttoken'])) { - $token = $_POST['requesttoken']; - } elseif(isset($_SERVER['HTTP_REQUESTTOKEN'])) { - $token = $_SERVER['HTTP_REQUESTTOKEN']; - } else { - //no token found. - return false; - } - - // Check if the token is valid - if($token !== \OC::$session->get('requesttoken')) { - // Not valid - return false; - } else { - // Valid token - return true; - } + return \OC::$server->getRequest()->passesCSRFCheck(); } /** @@ -743,6 +772,10 @@ class OC_Util { * file in the data directory and trying to access via http */ public static function isHtAccessWorking() { + if (!\OC_Config::getValue("check_for_working_htaccess", true)) { + return true; + } + // testdata $fileName = '/htaccesstest.txt'; $testContent = 'testcontent'; @@ -755,8 +788,12 @@ class OC_Util { } $fp = @fopen($testFile, 'w'); - @fwrite($fp, $testContent); - @fclose($fp); + if (!$fp) { + throw new OC\HintException('Can\'t create test file to check for working .htaccess file.', + 'Make sure it is possible for the webserver to write to '.$testFile); + } + fwrite($fp, $testContent); + fclose($fp); // accessing the file via http $url = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/data'.$fileName); @@ -791,11 +828,16 @@ class OC_Util { if (!function_exists('curl_init')) { return true; } + if (!\OC_Config::getValue("check_for_working_webdav", true)) { + return true; + } $settings = array( 'baseUri' => OC_Helper::linkToRemote('webdav'), ); - $client = new \Sabre_DAV_Client($settings); + $client = new \OC_DAVClient($settings); + + $client->setRequestTimeout(10); // for this self test we don't care if the ssl certificate is self signed and the peer cannot be verified. $client->setVerifyPeer(false); @@ -825,8 +867,8 @@ class OC_Util { return true; } - $result = setlocale(LC_ALL, 'en_US.UTF-8', 'en_US.UTF8'); - if($result == false) { + \Patchwork\Utf8\Bootup::initLocale(); + if ('' === basename('§')) { return false; } return true; @@ -841,6 +883,14 @@ class OC_Util { } /** + * @brief Check if a PHP version older then 5.3.8 is installed. + * @return bool + */ + public static function isPHPoutdated() { + return version_compare(phpversion(), '5.3.8', '<'); + } + + /** * @brief Check if the ownCloud server can connect to the internet * @return bool */ @@ -850,6 +900,11 @@ class OC_Util { return false; } + // in case the connection is via proxy return true to avoid connecting to owncloud.org + if(OC_Config::getValue('proxy', '') != '') { + return true; + } + // try to connect to owncloud.org to see if http connections to the internet are possible. $connected = @fsockopen("www.owncloud.org", 80); if ($connected) { @@ -952,9 +1007,9 @@ class OC_Util { * @param string $url Url to get content * @return string of the response or false on error * This function get the content of a page via curl, if curl is enabled. - * If not, file_get_element is used. + * If not, file_get_contents is used. */ - public static function getUrlContent($url){ + public static function getUrlContent($url) { if (function_exists('curl_init')) { $curl = curl_init(); @@ -1043,7 +1098,11 @@ class OC_Util { } // XCache if (function_exists('xcache_clear_cache')) { - xcache_clear_cache(XC_TYPE_VAR, 0); + if (ini_get('xcache.admin.enable_auth')) { + OC_Log::write('core', 'XCache opcode cache will not be cleared because "xcache.admin.enable_auth" is enabled.', \OC_Log::WARN); + } else { + xcache_clear_cache(XC_TYPE_PHP, 0); + } } // Opcache (PHP >= 5.5) if (function_exists('opcache_reset')) { @@ -1077,4 +1136,17 @@ class OC_Util { $t = explode('/', $file); return array_pop($t); } + + /** + * A human readable string is generated based on version, channel and build number + * @return string + */ + public static function getHumanVersion() { + $version = OC_Util::getVersionString().' ('.OC_Util::getChannel().')'; + $build = OC_Util::getBuild(); + if(!empty($build) and OC_Util::getChannel() === 'daily') { + $version .= ' Build:' . $build; + } + return $version; + } } |