diff options
author | Georg Ehrke <developer@georgehrke.com> | 2014-05-31 14:55:00 +0200 |
---|---|---|
committer | Georg Ehrke <developer@georgehrke.com> | 2014-05-31 14:55:00 +0200 |
commit | c8636ca4d9528faf42b1cd877bb73e56d26244cf (patch) | |
tree | b65bc6f1d6af00e15e97eb2cc518eeda2a9896e3 /lib/private | |
parent | 2bcfd8e084b27ed89cf6e62bc9ab2c681d5a8361 (diff) | |
parent | cff9440a37a64a43403b7dd57a99a203410e426a (diff) | |
download | nextcloud-server-c8636ca4d9528faf42b1cd877bb73e56d26244cf.tar.gz nextcloud-server-c8636ca4d9528faf42b1cd877bb73e56d26244cf.zip |
Merge branch 'master' into update_shipped_apps_from_appstore
Conflicts:
lib/private/app.php
lib/private/installer.php
Diffstat (limited to 'lib/private')
136 files changed, 2874 insertions, 1954 deletions
diff --git a/lib/private/app.php b/lib/private/app.php index e672df7b32a..fe1fa6a0d1a 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -42,7 +42,7 @@ class OC_App{ static private $altLogin = array(); /** - * @brief clean the appid + * clean the appid * @param string|boolean $app Appid that needs to be cleaned * @return string */ @@ -51,7 +51,7 @@ class OC_App{ } /** - * @brief loads all apps + * loads all apps * @param array $types * @return bool * @@ -192,7 +192,7 @@ class OC_App{ } /** - * @brief checks whether or not an app is enabled + * checks whether or not an app is enabled * @param string $app app * @return bool * @@ -207,7 +207,7 @@ class OC_App{ } /** - * @brief enables an app + * enables an app * @param mixed $app app * @throws \Exception * @return void @@ -257,7 +257,7 @@ class OC_App{ } /** - * @brief disables an app + * disables an app * @param string $app app * @return null * @@ -271,7 +271,7 @@ class OC_App{ } /** - * @brief adds an entry to the navigation + * adds an entry to the navigation * @param array $data array containing the data * @return bool * @@ -293,7 +293,7 @@ class OC_App{ } /** - * @brief marks a navigation entry as active + * marks a navigation entry as active * @param string $id id of the entry * @return bool * @@ -307,9 +307,9 @@ class OC_App{ } /** - * @brief Get the navigation entries for the $app + * Get the navigation entries for the $app * @param string $app app - * @return array of the $data added with addNavigationEntry + * @return array an array of the $data added with addNavigationEntry * * Warning: destroys the existing entries */ @@ -323,7 +323,7 @@ class OC_App{ } /** - * @brief gets the active Menu entry + * gets the active Menu entry * @return string id or empty string * * This function returns the id of the active navigation entry (set by @@ -334,7 +334,7 @@ class OC_App{ } /** - * @brief Returns the Settings Navigation + * Returns the Settings Navigation * @return string * * This function returns an array containing all settings pages added. The @@ -559,7 +559,7 @@ class OC_App{ /** - * @brief Read all app metadata from the info.xml file + * Read all app metadata from the info.xml file * @param string $appid id of the app or the path of the info.xml file * @param boolean $path (optional) * @return array @@ -626,7 +626,7 @@ class OC_App{ } /** - * @brief Returns the navigation + * Returns the navigation * @return array * * This function returns an array containing all entries added. The @@ -717,8 +717,8 @@ class OC_App{ } /** - * @brief: get a list of all apps in the apps folder - * @return array or app names (string IDs) + * get a list of all apps in the apps folder + * @return array an array of app names (string IDs) * @todo: change the name of this method to getInstalledApps, which is more accurate */ public static function getAllApps() { @@ -750,7 +750,7 @@ class OC_App{ } /** - * @brief: Lists all apps, this is used in apps.php + * Lists all apps, this is used in apps.php * @return array */ public static function listAllApps() { @@ -824,7 +824,7 @@ class OC_App{ } /** - * @brief: Internal custom sort funtion to bring the app into the right order. Should only be called by listAllApps + * 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) { @@ -854,7 +854,7 @@ class OC_App{ } /** - * @brief: get a list of all apps on apps.owncloud.com + * 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 */ @@ -959,8 +959,14 @@ class OC_App{ * ownCloud version. disable them if not. * This is important if you upgrade ownCloud and have non ported 3rd * party apps installed. + * + * @param array $apps optional app id list to check, uses all enabled apps + * when not specified + * + * @return array containing the list of ids of the disabled apps */ public static function checkAppsRequirements($apps = array()) { + $disabledApps = array(); if (empty($apps)) { $apps = OC_App::getEnabledApps(); } @@ -968,49 +974,91 @@ class OC_App{ foreach($apps as $app) { // check if the app is compatible with this version of ownCloud $info = OC_App::getAppInfo($app); - if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) { + if(!self::isAppCompatible($version, $info)) { OC_Log::write('core', 'App "'.$info['name'].'" ('.$app.') can\'t be used because it is' .' not compatible with this version of ownCloud', OC_Log::ERROR); OC_App::disable( $app ); OC_Hook::emit('update', 'success', 'Disabled '.$info['name'].' app because it is not compatible'); + $disabledApps[] = $app; } } + return $disabledApps; } + /** + * Ajust the number of version parts of $version1 to match + * the number of version parts of $version2. + * + * @param string $version1 version to adjust + * @param string $version2 version to take the number of parts from + * @return string shortened $version1 + */ + private static function adjustVersionParts($version1, $version2) { + $version1 = explode('.', $version1); + $version2 = explode('.', $version2); + // reduce $version1 to match the number of parts in $version2 + while (count($version1) > count($version2)) { + array_pop($version1); + } + // if $version1 does not have enough parts, add some + while (count($version1) < count($version2)) { + $version1[] = '0'; + } + return implode('.', $version1); + } /** - * Compares the app version with the owncloud version to see if the app - * requires a newer version than the currently active one - * @param array $owncloudVersions array with 3 entries: major minor bugfix - * @param string $appRequired the required version from the xml - * major.minor.bugfix + * Check whether the current ownCloud version matches the given + * application's version requirements. + * + * The comparison is made based on the number of parts that the + * app info version has. For example for ownCloud 6.0.3 if the + * app info version is expecting version 6.0, the comparison is + * made on the first two parts of the ownCloud version. + * This means that it's possible to specify "requiremin" => 6 + * and "requiremax" => 6 and it will still match ownCloud 6.0.3. + * + * @param string $ocVersion ownCloud version to check against + * @param array $appInfo app info (from xml) + * * @return boolean true if compatible, otherwise false */ - public static function isAppVersionCompatible($owncloudVersions, $appRequired){ - $appVersions = explode('.', $appRequired); + public static function isAppCompatible($ocVersion, $appInfo){ + $requireMin = ''; + $requireMax = ''; + if (isset($appInfo['requiremin'])) { + $requireMin = $appInfo['requiremin']; + } else if (isset($appInfo['require'])) { + $requireMin = $appInfo['require']; + } + + if (isset($appInfo['requiremax'])) { + $requireMax = $appInfo['requiremax']; + } - for($i=0; $i<count($appVersions); $i++){ - $appVersion = (int) $appVersions[$i]; + if (is_array($ocVersion)) { + $ocVersion = implode('.', $ocVersion); + } - if(isset($owncloudVersions[$i])){ - $owncloudVersion = $owncloudVersions[$i]; - } else { - $owncloudVersion = 0; - } + if (!empty($requireMin) + && version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<') + ) { - if($owncloudVersion < $appVersion){ - return false; - } elseif ($owncloudVersion > $appVersion) { - return true; - } + return false; + } + + if (!empty($requireMax) + && version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>') + ) { + + return false; } return true; } - /** * get the installed version of all apps */ @@ -1054,7 +1102,7 @@ class OC_App{ // check if the app is compatible with this version of ownCloud $info = self::getAppInfo($app); $version=OC_Util::getVersion(); - if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) { + if(!self::isAppCompatible($version, $info)) { throw new \Exception( $l->t("App \"%s\" can't be installed because it is not compatible with this version of ownCloud.", array($info['name']) diff --git a/lib/private/appconfig.php b/lib/private/appconfig.php index 0cd6b3bc35b..e2a961b1d6d 100644 --- a/lib/private/appconfig.php +++ b/lib/private/appconfig.php @@ -89,8 +89,8 @@ class AppConfig implements \OCP\IAppConfig { } /** - * @brief Get all apps using the config - * @return array with app ids + * Get all apps using the config + * @return array an array of app ids * * This function returns a list of all apps that have at least one * entry in the appconfig table. @@ -107,9 +107,9 @@ class AppConfig implements \OCP\IAppConfig { } /** - * @brief Get the available keys for an app + * Get the available keys for an app * @param string $app the app we are looking for - * @return array with key names + * @return array an array of key names * * This function gets all keys of an app. Please note that the values are * not returned. @@ -122,7 +122,7 @@ class AppConfig implements \OCP\IAppConfig { } /** - * @brief Gets the config value + * Gets the config value * @param string $app app * @param string $key key * @param string $default = null, default value if the key does not exist @@ -141,7 +141,7 @@ class AppConfig implements \OCP\IAppConfig { } /** - * @brief check if a key is set in the appconfig + * check if a key is set in the appconfig * @param string $app * @param string $key * @return bool @@ -152,7 +152,7 @@ class AppConfig implements \OCP\IAppConfig { } /** - * @brief sets a value in the appconfig + * sets a value in the appconfig * @param string $app app * @param string $key key * @param string $value value @@ -185,7 +185,7 @@ class AppConfig implements \OCP\IAppConfig { } /** - * @brief Deletes a key + * Deletes a key * @param string $app app * @param string $key key * @return boolean|null @@ -202,7 +202,7 @@ class AppConfig implements \OCP\IAppConfig { } /** - * @brief Remove app from appconfig + * Remove app from appconfig * @param string $app app * @return boolean|null * diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php index 3b13194862d..baf52d02054 100644 --- a/lib/private/appframework/app.php +++ b/lib/private/appframework/app.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/core/api.php b/lib/private/appframework/core/api.php index e7269373bb0..ba6b9f95cb2 100644 --- a/lib/private/appframework/core/api.php +++ b/lib/private/appframework/core/api.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -119,7 +119,7 @@ class API implements IApi{ } /** - * @brief connects a function to a hook + * connects a function to a hook * @param string $signalClass class name of emitter * @param string $signalName name of signal * @param string $slotClass class name of slot @@ -133,10 +133,10 @@ class API implements IApi{ } /** - * @brief Emits a signal. To get data from the slot use references! + * Emits a signal. To get data from the slot use references! * @param string $signalClass class name of emitter * @param string $signalName name of signal - * @param array $params defautl: array() array with additional data + * @param array $params default: array() array with additional data * @return bool, true if slots exists or false if not */ public function emitHook($signalClass, $signalName, $params = array()) { @@ -144,7 +144,7 @@ class API implements IApi{ } /** - * @brief clear hooks + * clear hooks * @param string $signalClass * @param string $signalName */ diff --git a/lib/private/appframework/db/db.php b/lib/private/appframework/db/db.php new file mode 100644 index 00000000000..fc77a38f814 --- /dev/null +++ b/lib/private/appframework/db/db.php @@ -0,0 +1,57 @@ +<?php + +/** + * ownCloud - App Framework + * + * @author Bernhard Posselt + * @copyright 2012 Bernhard Posselt dev@bernhard-posselt.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\Db; + +use \OCP\IDb; + + +/** + * Small Facade for being able to inject the database connection for tests + */ +class Db implements IDb { + + + /** + * Used to abstract 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 \OC_DB_StatementWrapper prepared SQL query + */ + public function prepareQuery($sql, $limit=null, $offset=null){ + return \OCP\DB::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 getInsertId($tableName){ + return \OCP\DB::insertid($tableName); + } + + +} diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php index e478225a53d..61a2333ecee 100644 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ b/lib/private/appframework/dependencyinjection/dicontainer.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -30,8 +30,10 @@ use OC\AppFramework\Http\Dispatcher; use OC\AppFramework\Core\API; use OC\AppFramework\Middleware\MiddlewareDispatcher; use OC\AppFramework\Middleware\Security\SecurityMiddleware; +use OC\AppFramework\Middleware\Security\CORSMiddleware; use OC\AppFramework\Utility\SimpleContainer; use OC\AppFramework\Utility\TimeFactory; +use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\IApi; use OCP\AppFramework\IAppContainer; use OCP\AppFramework\Middleware; @@ -80,7 +82,12 @@ class DIContainer extends SimpleContainer implements IAppContainer{ }); $this['Dispatcher'] = $this->share(function($c) { - return new Dispatcher($c['Protocol'], $c['MiddlewareDispatcher']); + return new Dispatcher( + $c['Protocol'], + $c['MiddlewareDispatcher'], + $c['ControllerMethodReflector'], + $c['Request'] + ); }); @@ -89,13 +96,30 @@ class DIContainer extends SimpleContainer implements IAppContainer{ */ $app = $this; $this['SecurityMiddleware'] = $this->share(function($c) use ($app){ - return new SecurityMiddleware($app, $c['Request']); + return new SecurityMiddleware( + $c['Request'], + $c['ControllerMethodReflector'], + $app->getServer()->getNavigationManager(), + $app->getServer()->getURLGenerator(), + $app->getServer()->getLogger(), + $c['AppName'], + $app->isLoggedIn(), + $app->isAdminUser() + ); + }); + + $this['CORSMiddleware'] = $this->share(function($c) { + return new CORSMiddleware( + $c['Request'], + $c['ControllerMethodReflector'] + ); }); $middleWares = &$this->middleWares; $this['MiddlewareDispatcher'] = $this->share(function($c) use (&$middleWares) { $dispatcher = new MiddlewareDispatcher(); $dispatcher->registerMiddleware($c['SecurityMiddleware']); + $dispatcher->registerMiddleware($c['CORSMiddleware']); foreach($middleWares as $middleWare) { $dispatcher->registerMiddleware($c[$middleWare]); @@ -112,6 +136,9 @@ class DIContainer extends SimpleContainer implements IAppContainer{ return new TimeFactory(); }); + $this['ControllerMethodReflector'] = $this->share(function($c) { + return new ControllerMethodReflector(); + }); } @@ -168,8 +195,8 @@ class DIContainer extends SimpleContainer implements IAppContainer{ } /** - * @param $message - * @param $level + * @param string $message + * @param string $level * @return mixed */ function log($message, $level) { diff --git a/lib/private/appframework/http.php b/lib/private/appframework/http.php index 65d926105f1..2b1387af715 100644 --- a/lib/private/appframework/http.php +++ b/lib/private/appframework/http.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -33,7 +33,7 @@ class Http extends BaseHttp { protected $headers; /** - * @param $_SERVER $server + * @param array $server $_SERVER * @param string $protocolVersion the http version to use defaults to HTTP/1.1 */ public function __construct($server, $protocolVersion='HTTP/1.1') { diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/appframework/http/dispatcher.php index a2afb53f0fa..442e33ee726 100644 --- a/lib/private/appframework/http/dispatcher.php +++ b/lib/private/appframework/http/dispatcher.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -26,7 +26,11 @@ namespace OC\AppFramework\Http; use \OC\AppFramework\Middleware\MiddlewareDispatcher; use \OC\AppFramework\Http; +use \OC\AppFramework\Utility\ControllerMethodReflector; + use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Response; +use OCP\IRequest; /** @@ -36,17 +40,25 @@ class Dispatcher { private $middlewareDispatcher; private $protocol; - + private $reflector; + private $request; /** * @param Http $protocol the http protocol with contains all status headers * @param MiddlewareDispatcher $middlewareDispatcher the dispatcher which * runs the middleware + * @param ControllerMethodReflector the reflector that is used to inject + * the arguments for the controller + * @param IRequest $request the incoming request */ public function __construct(Http $protocol, - MiddlewareDispatcher $middlewareDispatcher) { + MiddlewareDispatcher $middlewareDispatcher, + ControllerMethodReflector $reflector, + IRequest $request) { $this->protocol = $protocol; $this->middlewareDispatcher = $middlewareDispatcher; + $this->reflector = $reflector; + $this->request = $request; } @@ -63,10 +75,13 @@ class Dispatcher { $out = array(null, array(), null); try { + // prefill reflector with everything thats needed for the + // middlewares + $this->reflector->reflect($controller, $methodName); $this->middlewareDispatcher->beforeController($controller, $methodName); - $response = $controller->$methodName(); + $response = $this->executeController($controller, $methodName); // if an exception appears, the middleware checks if it can handle the // exception and creates a response. If no response is created, it is @@ -98,4 +113,70 @@ class Dispatcher { } + /** + * Uses the reflected parameters, types and request parameters to execute + * the controller + * @param Controller $controller the controller to be executed + * @param string $methodName the method on the controller that should be executed + * @return Response + */ + private function executeController($controller, $methodName) { + $arguments = array(); + + // valid types that will be casted + $types = array('int', 'integer', 'bool', 'boolean', 'float'); + + foreach($this->reflector->getParameters() as $param => $default) { + + // try to get the parameter from the request object and cast + // it to the type annotated in the @param annotation + $value = $this->request->getParam($param, $default); + $type = $this->reflector->getType($param); + + // if this is submitted using GET or a POST form, 'false' should be + // converted to false + if(($type === 'bool' || $type === 'boolean') && + $value === 'false' && + ( + $this->request->method === 'GET' || + strpos($this->request->getHeader('Content-Type'), + 'application/x-www-form-urlencoded') !== false + ) + ) { + $value = false; + + } elseif(in_array($type, $types)) { + settype($value, $type); + } + + $arguments[] = $value; + } + + $response = call_user_func_array(array($controller, $methodName), $arguments); + + // format response if not of type response + if(!($response instanceof Response)) { + + // get format from the url format or request format parameter + $format = $this->request->getParam('format'); + + // if none is given try the first Accept header + if($format === null) { + $header = $this->request->getHeader('Accept'); + $formats = explode(',', $header); + + if($header !== null && count($formats) > 0) { + $accept = strtolower(trim($formats[0])); + $format = str_replace('application/', '', $accept); + } else { + $format = 'json'; + } + } + + $response = $controller->buildResponse($response, $format); + } + + return $response; + } + } diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index 643fa685adc..8b68ca486ff 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -3,7 +3,9 @@ * ownCloud - Request * * @author Thomas Tanghus + * @author Bernhard Posselt * @copyright 2013 Thomas Tanghus (thomas@tanghus.net) + * @copyright 2014 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/middleware/middlewaredispatcher.php b/lib/private/appframework/middleware/middlewaredispatcher.php index 598743e523f..dcb63a8e552 100644 --- a/lib/private/appframework/middleware/middlewaredispatcher.php +++ b/lib/private/appframework/middleware/middlewaredispatcher.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/middleware/security/corsmiddleware.php b/lib/private/appframework/middleware/security/corsmiddleware.php new file mode 100644 index 00000000000..dca3996ea2e --- /dev/null +++ b/lib/private/appframework/middleware/security/corsmiddleware.php @@ -0,0 +1,75 @@ +<?php +/** + * ownCloud - App Framework + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Bernhard Posselt <dev@bernhard-posselt.com> + * @copyright Bernhard Posselt 2014 + */ + +namespace OC\AppFramework\Middleware\Security; + +use OC\AppFramework\Utility\ControllerMethodReflector; +use OCP\IRequest; +use OCP\AppFramework\Http\Response; +use OCP\AppFramework\Middleware; + +/** + * This middleware sets the correct CORS headers on a response if the + * controller has the @CORS annotation. This is needed for webapps that want + * to access an API and dont run on the same domain, see + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS + */ +class CORSMiddleware extends Middleware { + + private $request; + private $reflector; + + /** + * @param IRequest $request + * @param ControllerMethodReflector $reflector + */ + public function __construct(IRequest $request, + ControllerMethodReflector $reflector) { + $this->request = $request; + $this->reflector = $reflector; + } + + + /** + * 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){ + // only react if its a CORS request and if the request sends origin and + + if(isset($this->request->server['HTTP_ORIGIN']) && + $this->reflector->hasAnnotation('CORS')) { + + // allow credentials headers must not be true or CSRF is possible + // otherwise + foreach($response->getHeaders() as $header => $value ) { + if(strtolower($header) === 'access-control-allow-credentials' && + strtolower(trim($value)) === 'true') { + $msg = 'Access-Control-Allow-Credentials must not be '. + 'set to true in order to prevent CSRF'; + throw new SecurityException($msg); + } + } + + $origin = $this->request->server['HTTP_ORIGIN']; + $response->addHeader('Access-Control-Allow-Origin', $origin); + } + return $response; + } + + +} diff --git a/lib/private/appframework/middleware/security/securityexception.php b/lib/private/appframework/middleware/security/securityexception.php index e551675acdf..df37d5e3275 100644 --- a/lib/private/appframework/middleware/security/securityexception.php +++ b/lib/private/appframework/middleware/security/securityexception.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php index 0f160d224ad..5b56210024d 100644 --- a/lib/private/appframework/middleware/security/securitymiddleware.php +++ b/lib/private/appframework/middleware/security/securitymiddleware.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -25,13 +25,15 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Http; -use OC\AppFramework\Utility\MethodAnnotationReader; +use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Middleware; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\JSONResponse; -use OCP\AppFramework\IAppContainer; +use OCP\INavigationManager; +use OCP\IURLGenerator; use OCP\IRequest; +use OCP\ILogger; /** @@ -42,23 +44,41 @@ use OCP\IRequest; */ class SecurityMiddleware extends Middleware { - /** - * @var \OCP\AppFramework\IAppContainer - */ - private $app; - - /** - * @var \OCP\IRequest - */ + private $navigationManager; private $request; + private $reflector; + private $appName; + private $urlGenerator; + private $logger; + private $isLoggedIn; + private $isAdminUser; /** - * @param IAppContainer $app * @param IRequest $request + * @param ControllerMethodReflector $reflector + * @param INavigationManager $navigationManager + * @param IURLGenerator $urlGenerator + * @param ILogger $logger + * @param string $appName + * @param bool $isLoggedIn + * @param bool $isAdminUser */ - public function __construct(IAppContainer $app, IRequest $request){ - $this->app = $app; + public function __construct(IRequest $request, + ControllerMethodReflector $reflector, + INavigationManager $navigationManager, + IURLGenerator $urlGenerator, + ILogger $logger, + $appName, + $isLoggedIn, + $isAdminUser){ + $this->navigationManager = $navigationManager; $this->request = $request; + $this->reflector = $reflector; + $this->appName = $appName; + $this->urlGenerator = $urlGenerator; + $this->logger = $logger; + $this->isLoggedIn = $isLoggedIn; + $this->isAdminUser = $isAdminUser; } @@ -72,28 +92,25 @@ class SecurityMiddleware extends Middleware { */ public function beforeController($controller, $methodName){ - // get annotations from comments - $annotationReader = new MethodAnnotationReader($controller, $methodName); - // this will set the current navigation entry of the app, use this only // for normal HTML requests and not for AJAX requests - $this->app->getServer()->getNavigationManager()->setActiveEntry($this->app->getAppName()); + $this->navigationManager->setActiveEntry($this->appName); // security checks - $isPublicPage = $annotationReader->hasAnnotation('PublicPage'); + $isPublicPage = $this->reflector->hasAnnotation('PublicPage'); if(!$isPublicPage) { - if(!$this->app->isLoggedIn()) { + if(!$this->isLoggedIn) { throw new SecurityException('Current user is not logged in', Http::STATUS_UNAUTHORIZED); } - if(!$annotationReader->hasAnnotation('NoAdminRequired')) { - if(!$this->app->isAdminUser()) { + if(!$this->reflector->hasAnnotation('NoAdminRequired')) { + if(!$this->isAdminUser) { throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN); } } } - if(!$annotationReader->hasAnnotation('NoCSRFRequired')) { + if(!$this->reflector->hasAnnotation('NoCSRFRequired')) { if(!$this->request->passesCSRFCheck()) { throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED); } @@ -121,13 +138,13 @@ class SecurityMiddleware extends Middleware { array('message' => $exception->getMessage()), $exception->getCode() ); - $this->app->log($exception->getMessage(), 'debug'); + $this->logger->debug($exception->getMessage()); } else { // TODO: replace with link to route - $url = $this->app->getServer()->getURLGenerator()->getAbsoluteURL('index.php'); + $url = $this->urlGenerator->getAbsoluteURL('index.php'); $response = new RedirectResponse($url); - $this->app->log($exception->getMessage(), 'debug'); + $this->logger->debug($exception->getMessage()); } return $response; diff --git a/lib/private/appframework/routing/routeconfig.php b/lib/private/appframework/routing/routeconfig.php index a3bbde6af53..91ea7778d08 100644 --- a/lib/private/appframework/routing/routeconfig.php +++ b/lib/private/appframework/routing/routeconfig.php @@ -61,7 +61,7 @@ class RouteConfig { /** * Creates one route base on the give configuration - * @param $routes + * @param array $routes * @throws \UnexpectedValueException */ private function processSimpleRoutes($routes) @@ -105,7 +105,7 @@ class RouteConfig { * - update * - destroy * - * @param $routes + * @param array $routes */ private function processResources($routes) { @@ -151,7 +151,7 @@ class RouteConfig { /** * Based on a given route name the controller name is generated - * @param $controller + * @param string $controller * @return string */ private function buildControllerName($controller) @@ -161,7 +161,7 @@ class RouteConfig { /** * Based on the action part of the route name the controller method name is generated - * @param $action + * @param string $action * @return string */ private function buildActionName($action) { @@ -170,7 +170,7 @@ class RouteConfig { /** * Generates the id used in the url part o the route url - * @param $resource + * @param string $resource * @return string */ private function buildResourceId($resource) { @@ -179,7 +179,7 @@ class RouteConfig { /** * Underscored strings are converted to camel case strings - * @param $str string + * @param string $str * @return string */ private function underScoreToCamelCase($str) { diff --git a/lib/private/appframework/utility/methodannotationreader.php b/lib/private/appframework/utility/controllermethodreflector.php index 42060a08529..a1519c72809 100644 --- a/lib/private/appframework/utility/methodannotationreader.php +++ b/lib/private/appframework/utility/controllermethodreflector.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2014 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -28,23 +28,68 @@ namespace OC\AppFramework\Utility; /** * Reads and parses annotations from doc comments */ -class MethodAnnotationReader { +class ControllerMethodReflector { private $annotations; + private $types; + private $parameters; + + public function __construct() { + $this->types = array(); + $this->parameters = array(); + $this->annotations = array(); + } + /** * @param object $object an object or classname - * @param string $method the method which we want to inspect for annotations + * @param string $method the method which we want to inspect */ - public function __construct($object, $method){ - $this->annotations = array(); - + public function reflect($object, $method){ $reflection = new \ReflectionMethod($object, $method); $docs = $reflection->getDocComment(); // extract everything prefixed by @ and first letter uppercase preg_match_all('/@([A-Z]\w+)/', $docs, $matches); $this->annotations = $matches[1]; + + // extract type parameter information + preg_match_all('/@param (?<type>\w+) \$(?<var>\w+)/', $docs, $matches); + $this->types = array_combine($matches['var'], $matches['type']); + + // get method parameters + foreach ($reflection->getParameters() as $param) { + if($param->isOptional()) { + $default = $param->getDefaultValue(); + } else { + $default = null; + } + $this->parameters[$param->name] = $default; + } + } + + + /** + * Inspects the PHPDoc parameters for types + * @param string $parameter the parameter whose type comments should be + * parsed + * @return string|null type in the type parameters (@param int $something) + * would return int or null if not existing + */ + public function getType($parameter) { + if(array_key_exists($parameter, $this->types)) { + return $this->types[$parameter]; + } else { + return null; + } + } + + + /** + * @return array the arguments of the method with key => default value + */ + public function getParameters() { + return $this->parameters; } diff --git a/lib/private/appframework/utility/timefactory.php b/lib/private/appframework/utility/timefactory.php index 2c3dd6cf5e3..a9b07a356e3 100644 --- a/lib/private/appframework/utility/timefactory.php +++ b/lib/private/appframework/utility/timefactory.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/archive/tar.php b/lib/private/archive/tar.php index cbdb565ba35..21a995d9e50 100644 --- a/lib/private/archive/tar.php +++ b/lib/private/archive/tar.php @@ -154,7 +154,7 @@ class OC_Archive_TAR extends OC_Archive{ } /** * get the last modified time of a file in the archive - * @param string path + * @param string $path * @return int */ function mtime($path) { diff --git a/lib/private/avatar.php b/lib/private/avatar.php index e97f55eecaf..2286b896878 100644 --- a/lib/private/avatar.php +++ b/lib/private/avatar.php @@ -15,16 +15,16 @@ class OC_Avatar implements \OCP\IAvatar { private $view; /** - * @brief constructor - * @param $user string user to do avatar-management with + * constructor + * @param string $user user to do avatar-management with */ public function __construct ($user) { $this->view = new \OC\Files\View('/'.$user); } /** - * @brief get the users avatar - * @param $size integer size in px of the avatar, avatars are square, defaults to 64 + * get the users avatar + * @param int $size 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) { @@ -43,8 +43,8 @@ class OC_Avatar implements \OCP\IAvatar { } /** - * @brief sets the users avatar - * @param $data mixed OC_Image, imagedata or path to set a new avatar + * sets the users avatar + * @param \OC_Image|resource|string $data 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 @@ -81,7 +81,7 @@ class OC_Avatar implements \OCP\IAvatar { } /** - * @brief remove the users avatar + * remove the users avatar * @return void */ public function remove () { diff --git a/lib/private/avatarmanager.php b/lib/private/avatarmanager.php index 3ca46868ea6..6abe87c4f41 100644 --- a/lib/private/avatarmanager.php +++ b/lib/private/avatarmanager.php @@ -15,9 +15,9 @@ use OCP\IAvatarManager; class AvatarManager implements IAvatarManager { /** - * @brief return a user specific instance of \OCP\IAvatar + * return a user specific instance of \OCP\IAvatar * @see \OCP\IAvatar - * @param $user string the ownCloud user id + * @param string $user the ownCloud user id * @return \OCP\IAvatar */ function getAvatar($user) { diff --git a/lib/private/backgroundjob.php b/lib/private/backgroundjob.php index afc3c270405..922824753b0 100644 --- a/lib/private/backgroundjob.php +++ b/lib/private/backgroundjob.php @@ -25,7 +25,7 @@ */ class OC_BackgroundJob{ /** - * @brief get the execution type of background jobs + * get the execution type of background jobs * @return string * * This method returns the type how background jobs are executed. If the user @@ -36,7 +36,7 @@ class OC_BackgroundJob{ } /** - * @brief sets the background jobs execution type + * sets the background jobs execution type * @param string $type execution type * @return false|null * diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php index 26c90269349..9fa13c25851 100644 --- a/lib/private/backgroundjob/joblist.php +++ b/lib/private/backgroundjob/joblist.php @@ -31,7 +31,7 @@ class JobList implements IJobList { } /** - * @param \Test\BackgroundJob\TestJob $job + * @param Job|string $job * @param mixed $argument */ public function add($job, $argument = null) { @@ -48,7 +48,7 @@ class JobList implements IJobList { } /** - * @param Job $job + * @param Job|string $job * @param mixed $argument */ public function remove($job, $argument = null) { @@ -70,7 +70,7 @@ class JobList implements IJobList { /** * check if a job is in the list * - * @param $job + * @param Job|string $job * @param mixed $argument * @return bool */ @@ -126,7 +126,7 @@ class JobList implements IJobList { /** * @param int $id - * @return Job + * @return Job|null */ public function getById($id) { $query = $this->conn->prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` WHERE `id` = ?'); diff --git a/lib/private/cache/file.php b/lib/private/cache/file.php index feee9cc32b6..4e7c065678e 100644 --- a/lib/private/cache/file.php +++ b/lib/private/cache/file.php @@ -48,7 +48,7 @@ class File { /** * Returns the size of the stored/cached data * - * @param $key + * @param string $key * @return int */ public function size($key) { diff --git a/lib/private/config.php b/lib/private/config.php index 6701ca0532b..82a1c46c9d5 100644 --- a/lib/private/config.php +++ b/lib/private/config.php @@ -64,8 +64,8 @@ class Config { } /** - * @brief Lists all available config keys - * @return array with key names + * Lists all available config keys + * @return array an array of key names * * This function returns all keys saved in config.php. Please note that it * does not return the values. @@ -75,10 +75,10 @@ class Config { } /** - * @brief Gets a value from config.php + * Gets a value from config.php * @param string $key key - * @param array|bool|string|null $default = null default value - * @return string the value or $default + * @param mixed $default = null default value + * @return mixed the value or $default * * This function gets the value from config.php. If it does not exist, * $default will be returned. @@ -92,9 +92,9 @@ class Config { } /** - * @brief Sets a value + * Sets a value * @param string $key key - * @param string $value value + * @param mixed $value value * * This function sets the value and writes the config.php. * @@ -108,7 +108,7 @@ class Config { } /** - * @brief Removes a key from the config + * Removes a key from the config * @param string $key key * * This function removes a key from the config.php. @@ -125,7 +125,7 @@ class Config { } /** - * @brief Loads the config file + * Loads the config file * * Reads the config file and saves it to the cache */ @@ -153,7 +153,7 @@ class Config { } /** - * @brief Writes the config file + * Writes the config file * * Saves the config to the config file. * diff --git a/lib/private/connector/sabre/auth.php b/lib/private/connector/sabre/auth.php index 5577273df8c..9ebf5fc05cf 100644 --- a/lib/private/connector/sabre/auth.php +++ b/lib/private/connector/sabre/auth.php @@ -69,6 +69,8 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic { * even if there are no HTTP Basic Auth headers. * In other case, just fallback to the parent implementation. * + * @param Sabre_DAV_Server $server + * @param $realm * @return bool */ public function authenticate(Sabre_DAV_Server $server, $realm) { diff --git a/lib/private/connector/sabre/exceptionloggerplugin.php b/lib/private/connector/sabre/exceptionloggerplugin.php index 8e77afaf207..5eaf1e87621 100644 --- a/lib/private/connector/sabre/exceptionloggerplugin.php +++ b/lib/private/connector/sabre/exceptionloggerplugin.php @@ -11,6 +11,17 @@ class OC_Connector_Sabre_ExceptionLoggerPlugin extends Sabre_DAV_ServerPlugin { + private $nonFatalExceptions = array( + 'Sabre_DAV_Exception_NotAuthenticated' => true, + // the sync client uses this to find out whether files exist, + // so it is not always an error, log it as debug + 'Sabre_DAV_Exception_NotFound' => true, + // this one mostly happens when the same file is uploaded at + // exactly the same time from two clients, only one client + // wins, the second one gets "Precondition failed" + 'Sabre_DAV_Exception_PreconditionFailed' => true, + ); + private $appName; /** @@ -43,8 +54,10 @@ class OC_Connector_Sabre_ExceptionLoggerPlugin extends Sabre_DAV_ServerPlugin */ public function logException($e) { $exceptionClass = get_class($e); - if ($exceptionClass !== 'Sabre_DAV_Exception_NotAuthenticated') { - \OCP\Util::logException($this->appName, $e); + $level = \OCP\Util::FATAL; + if (isset($this->nonFatalExceptions[$exceptionClass])) { + $level = \OCP\Util::DEBUG; } + \OCP\Util::logException($this->appName, $e, $level); } } diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 66b50a87552..8a16ba55e7a 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -123,7 +123,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D /** * Returns the data * - * @return string | resource + * @return string|resource */ public function get() { @@ -156,7 +156,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D /** * Returns the size of the node, in bytes * - * @return int + * @return int|float */ public function getSize() { return $this->info->getSize(); diff --git a/lib/private/connector/sabre/filesplugin.php b/lib/private/connector/sabre/filesplugin.php index 65231040fb5..25d7fd53343 100644 --- a/lib/private/connector/sabre/filesplugin.php +++ b/lib/private/connector/sabre/filesplugin.php @@ -37,6 +37,7 @@ class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin $server->xmlNamespaces[self::NS_OWNCLOUD] = 'oc'; $server->protectedProperties[] = '{' . self::NS_OWNCLOUD . '}id'; + $server->protectedProperties[] = '{' . self::NS_OWNCLOUD . '}perm'; $this->server = $server; $this->server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties')); @@ -57,15 +58,24 @@ class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin 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)]); + $fileIdPropertyName = '{' . self::NS_OWNCLOUD . '}id'; + $permissionsPropertyName = '{' . self::NS_OWNCLOUD . '}permissions'; + if (array_search($fileIdPropertyName, $requestedProperties)) { + unset($requestedProperties[array_search($fileIdPropertyName, $requestedProperties)]); + } + if (array_search($permissionsPropertyName, $requestedProperties)) { + unset($requestedProperties[array_search($permissionsPropertyName, $requestedProperties)]); } /** @var $node OC_Connector_Sabre_Node */ $fileId = $node->getFileId(); if (!is_null($fileId)) { - $returnedProperties[200][$fileid_propertyname] = $fileId; + $returnedProperties[200][$fileIdPropertyName] = $fileId; + } + + $permissions = $node->getDavPermissions(); + if (!is_null($fileId)) { + $returnedProperties[200][$permissionsPropertyName] = $permissions; } } @@ -73,7 +83,7 @@ class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin } /** - * @param $filePath + * @param string $filePath * @param Sabre_DAV_INode $node * @throws Sabre_DAV_Exception_BadRequest */ diff --git a/lib/private/connector/sabre/node.php b/lib/private/connector/sabre/node.php index eede39cba8b..f124b754443 100644 --- a/lib/private/connector/sabre/node.php +++ b/lib/private/connector/sabre/node.php @@ -56,7 +56,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr protected $info; /** - * @brief Sets up the node, expects a full path name + * Sets up the node, expects a full path name * @param \OC\Files\View $view * @param \OCP\Files\FileInfo $info */ @@ -71,7 +71,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } /** - * @brief Returns the name of the node + * Returns the name of the node * @return string */ public function getName() { @@ -79,7 +79,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } /** - * @brief Renames the node + * Renames the node * @param string $name The new name * @throws Sabre_DAV_Exception_BadRequest * @throws Sabre_DAV_Exception_Forbidden @@ -116,7 +116,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } /** - * @brief Returns the last modification time, as a unix timestamp + * Returns the last modification time, as a unix timestamp * @return int timestamp as integer */ public function getLastModified() { @@ -138,7 +138,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } /** - * @brief Updates properties on this node, + * Updates properties on this node, * @see Sabre_DAV_IProperties::updateProperties * @param array $properties * @return boolean @@ -188,7 +188,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } /** - * @brief Returns a list of properties for this nodes.; + * Returns a list of properties for this nodes.; * @param array $properties * @return array * @note The properties list is a list of propertynames the client @@ -237,4 +237,36 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr return null; } + + /** + * @return string|null + */ + public function getDavPermissions() { + $p =''; + if ($this->info->isShared()) { + $p .= 'S'; + } + if ($this->info->isShareable()) { + $p .= 'R'; + } + if ($this->info->isMounted()) { + $p .= 'M'; + } + if ($this->info->isDeletable()) { + $p .= 'D'; + } + if ($this->info->isDeletable()) { + $p .= 'N'; + } + if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) { + if ($this->info->isUpdateable()) { + $p .= 'W'; + } + } else { + if ($this->info->isUpdateable()) { + $p .= 'CK'; + } + } + return $p; + } } diff --git a/lib/private/connector/sabre/quotaplugin.php b/lib/private/connector/sabre/quotaplugin.php index 1e73e1645c3..c9b8336b57b 100644 --- a/lib/private/connector/sabre/quotaplugin.php +++ b/lib/private/connector/sabre/quotaplugin.php @@ -97,7 +97,7 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin { } /** - * @param $parentUri + * @param string $parentUri * @return mixed */ public function getFreeSpace($parentUri) { diff --git a/lib/private/connector/sabre/server.php b/lib/private/connector/sabre/server.php index 2660b043f46..cf28b11163f 100644 --- a/lib/private/connector/sabre/server.php +++ b/lib/private/connector/sabre/server.php @@ -170,7 +170,7 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server { if ($node instanceof Sabre_DAV_IFile) { $size = $node->getSize(); if (!is_null($size)) { - $newProperties[200][$prop] = (int)$node->getSize(); + $newProperties[200][$prop] = 0 + $size; } } break; diff --git a/lib/private/contactsmanager.php b/lib/private/contactsmanager.php index 4299d88017a..338cc048651 100644 --- a/lib/private/contactsmanager.php +++ b/lib/private/contactsmanager.php @@ -31,15 +31,16 @@ namespace OC { * @param string $pattern which should match within the $searchProperties * @param array $searchProperties defines the properties within the query pattern should match * @param array $options - for future use. One should always have options! - * @return array of contacts which are arrays of key-value-pairs + * @return array an array of contacts which are arrays of key-value-pairs */ public function search($pattern, $searchProperties = array(), $options = array()) { + $this->loadAddressBooks(); $result = array(); - foreach($this->address_books as $address_book) { - $r = $address_book->search($pattern, $searchProperties, $options); + foreach($this->addressBooks as $addressBook) { + $r = $addressBook->search($pattern, $searchProperties, $options); $contacts = array(); foreach($r as $c){ - $c['addressbook-key'] = $address_book->getKey(); + $c['addressbook-key'] = $addressBook->getKey(); $contacts[] = $c; } $result = array_merge($result, $contacts); @@ -52,18 +53,20 @@ namespace OC { * This function can be used to delete the contact identified by the given id * * @param object $id the unique identifier to a contact - * @param string $address_book_key identifier of the address book in which the contact shall be deleted + * @param string $addressBookKey identifier of the address book in which the contact shall be deleted * @return bool successful or not */ - public function delete($id, $address_book_key) { - if (!array_key_exists($address_book_key, $this->address_books)) + public function delete($id, $addressBookKey) { + $addressBook = $this->getAddressBook($addressBookKey); + if (!$addressBook) { return null; + } - $address_book = $this->address_books[$address_book_key]; - if ($address_book->getPermissions() & \OCP\PERMISSION_DELETE) + if ($addressBook->getPermissions() & \OCP\PERMISSION_DELETE) { return null; + } - return $address_book->delete($id); + return $addressBook->delete($id); } /** @@ -71,19 +74,20 @@ namespace OC { * Otherwise the contact will be updated by replacing the entire data set. * * @param array $properties this array if key-value-pairs defines a contact - * @param string $address_book_key identifier of the address book in which the contact shall be created or updated + * @param string $addressBookKey identifier of the address book in which the contact shall be created or updated * @return array representing the contact just created or updated */ - public function createOrUpdate($properties, $address_book_key) { - - if (!array_key_exists($address_book_key, $this->address_books)) + public function createOrUpdate($properties, $addressBookKey) { + $addressBook = $this->getAddressBook($addressBookKey); + if (!$addressBook) { return null; + } - $address_book = $this->address_books[$address_book_key]; - if ($address_book->getPermissions() & \OCP\PERMISSION_CREATE) + if ($addressBook->getPermissions() & \OCP\PERMISSION_CREATE) { return null; + } - return $address_book->createOrUpdate($properties); + return $addressBook->createOrUpdate($properties); } /** @@ -92,30 +96,31 @@ namespace OC { * @return bool true if enabled, false if not */ public function isEnabled() { - return !empty($this->address_books); + return !empty($this->addressBooks) || !empty($this->addressBookLoaders); } /** - * @param \OCP\IAddressBook $address_book + * @param \OCP\IAddressBook $addressBook */ - public function registerAddressBook(\OCP\IAddressBook $address_book) { - $this->address_books[$address_book->getKey()] = $address_book; + public function registerAddressBook(\OCP\IAddressBook $addressBook) { + $this->addressBooks[$addressBook->getKey()] = $addressBook; } /** - * @param \OCP\IAddressBook $address_book + * @param \OCP\IAddressBook $addressBook */ - public function unregisterAddressBook(\OCP\IAddressBook $address_book) { - unset($this->address_books[$address_book->getKey()]); + public function unregisterAddressBook(\OCP\IAddressBook $addressBook) { + unset($this->addressBooks[$addressBook->getKey()]); } /** * @return array */ public function getAddressBooks() { + $this->loadAddressBooks(); $result = array(); - foreach($this->address_books as $address_book) { - $result[$address_book->getKey()] = $address_book->getDisplayName(); + foreach($this->addressBooks as $addressBook) { + $result[$addressBook->getKey()] = $addressBook->getDisplayName(); } return $result; @@ -125,26 +130,56 @@ namespace OC { * removes all registered address book instances */ public function clear() { - $this->address_books = array(); + $this->addressBooks = array(); + $this->addressBookLoaders = array(); } /** * @var \OCP\IAddressBook[] which holds all registered address books */ - private $address_books = array(); + private $addressBooks = array(); + + /** + * @var \Closure[] to call to load/register address books + */ + private $addressBookLoaders = array(); /** * In order to improve lazy loading a closure can be registered which will be called in case * address books are actually requested * - * @param string $key * @param \Closure $callable */ - function register($key, \Closure $callable) + public function register(\Closure $callable) { - // - //TODO: implement me - // + $this->addressBookLoaders[] = $callable; + } + + /** + * Get (and load when needed) the address book for $key + * + * @param string $addressBookKey + * @return \OCP\IAddressBook + */ + protected function getAddressBook($addressBookKey) + { + $this->loadAddressBooks(); + if (!array_key_exists($addressBookKey, $this->addressBooks)) { + return null; + } + + return $this->addressBooks[$addressBookKey]; + } + + /** + * Load all address books registered with 'register' + */ + protected function loadAddressBooks() + { + foreach($this->addressBookLoaders as $callable) { + $callable($this); + } + $this->addressBookLoaders = array(); } } } diff --git a/lib/private/davclient.php b/lib/private/davclient.php index 916dc11d17a..a7bf0486519 100644 --- a/lib/private/davclient.php +++ b/lib/private/davclient.php @@ -32,7 +32,7 @@ class OC_DAVClient extends \Sabre_DAV_Client { protected $verifyHost; /** - * @brief Sets the request timeout or 0 to disable timeout. + * Sets the request timeout or 0 to disable timeout. * @param integer $timeout in seconds or 0 to disable */ public function setRequestTimeout($timeout) { @@ -40,7 +40,7 @@ class OC_DAVClient extends \Sabre_DAV_Client { } /** - * @brief Sets the CURLOPT_SSL_VERIFYHOST setting + * Sets the CURLOPT_SSL_VERIFYHOST setting * @param integer $value value to set CURLOPT_SSL_VERIFYHOST to */ public function setVerifyHost($value) { diff --git a/lib/private/db.php b/lib/private/db.php index 322a13642ae..422f783c745 100644 --- a/lib/private/db.php +++ b/lib/private/db.php @@ -46,11 +46,8 @@ class OC_DB { */ static private $connection; //the preferred connection to use, only Doctrine - static private $prefix=null; - static private $type=null; - /** - * @brief connects to the database + * connects to the database * @return boolean|null true if connection can be established or false on error * * Connects to the database as specified in config.php @@ -72,102 +69,45 @@ class OC_DB { $port=false; } - // do nothing if the connection already has been established - if (!self::$connection) { - $config = new \Doctrine\DBAL\Configuration(); - $eventManager = new \Doctrine\Common\EventManager(); - switch($type) { - case 'sqlite': - case 'sqlite3': - $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' ); - $connectionParams = array( - 'user' => $user, - 'password' => $pass, - 'path' => $datadir.'/'.$name.'.db', - 'driver' => 'pdo_sqlite', - ); - $connectionParams['adapter'] = '\OC\DB\AdapterSqlite'; - $connectionParams['wrapperClass'] = 'OC\DB\Connection'; - break; - case 'mysql': - $connectionParams = array( - 'user' => $user, - 'password' => $pass, - 'host' => $host, - 'port' => $port, - 'dbname' => $name, - 'charset' => 'UTF8', - 'driver' => 'pdo_mysql', - ); - $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( - 'user' => $user, - 'password' => $pass, - 'host' => $host, - 'port' => $port, - 'dbname' => $name, - 'driver' => 'pdo_pgsql', - ); - $connectionParams['adapter'] = '\OC\DB\AdapterPgSql'; - $connectionParams['wrapperClass'] = 'OC\DB\Connection'; - break; - case 'oci': - $connectionParams = array( - 'user' => $user, - 'password' => $pass, - 'host' => $host, - 'dbname' => $name, - 'charset' => 'AL32UTF8', - 'driver' => 'oci8', - ); - if (!empty($port)) { - $connectionParams['port'] = $port; - } - $connectionParams['adapter'] = '\OC\DB\AdapterOCI8'; - $connectionParams['wrapperClass'] = 'OC\DB\OracleConnection'; - $eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\OracleSessionInit); - break; - case 'mssql': - $connectionParams = array( - 'user' => $user, - 'password' => $pass, - 'host' => $host, - 'port' => $port, - 'dbname' => $name, - 'charset' => 'UTF8', - 'driver' => 'pdo_sqlsrv', - ); - $connectionParams['adapter'] = '\OC\DB\AdapterSQLSrv'; - $connectionParams['wrapperClass'] = 'OC\DB\Connection'; - break; - default: - return false; - } - $connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_' ); - try { - self::$connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config, $eventManager); - if ($type === 'sqlite' || $type === 'sqlite3') { - // Sqlite doesn't handle query caching and schema changes - // TODO: find a better way to handle this - self::$connection->disableQueryStatementCaching(); - } - } catch(\Doctrine\DBAL\DBALException $e) { - OC_Log::write('core', $e->getMessage(), OC_Log::FATAL); - OC_User::setUserId(null); - - // send http status 503 - header('HTTP/1.1 503 Service Temporarily Unavailable'); - header('Status: 503 Service Temporarily Unavailable'); - OC_Template::printErrorPage('Failed to connect to database'); - die(); + $factory = new \OC\DB\ConnectionFactory(); + if (!$factory->isValidType($type)) { + return false; + } + + if ($factory->normalizeType($type) === 'sqlite3') { + $datadir = OC_Config::getValue("datadirectory", OC::$SERVERROOT.'/data'); + $connectionParams = array( + 'user' => $user, + 'password' => $pass, + 'path' => $datadir.'/'.$name.'.db', + ); + } else { + $connectionParams = array( + 'user' => $user, + 'password' => $pass, + 'host' => $host, + 'dbname' => $name, + ); + if (!empty($port)) { + $connectionParams['port'] = $port; } } + + $connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_'); + + try { + self::$connection = $factory->getConnection($type, $connectionParams); + } catch(\Doctrine\DBAL\DBALException $e) { + OC_Log::write('core', $e->getMessage(), OC_Log::FATAL); + OC_User::setUserId(null); + + // send http status 503 + header('HTTP/1.1 503 Service Temporarily Unavailable'); + header('Status: 503 Service Temporarily Unavailable'); + OC_Template::printErrorPage('Failed to connect to database'); + die(); + } + return true; } @@ -190,7 +130,7 @@ class OC_DB { } /** - * @brief Prepare a SQL query + * Prepare a SQL query * @param string $query Query string * @param int $limit * @param int $offset @@ -202,12 +142,12 @@ class OC_DB { */ static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) { self::connect(); - + if ($isManipulation === null) { //try to guess, so we return the number of rows on manipulations $isManipulation = self::isManipulation($query); } - + // return the result try { $result = self::$connection->prepare($query, $limit, $offset); @@ -222,7 +162,7 @@ class OC_DB { /** * tries to guess the type of statement based on the first 10 characters * the current check allows some whitespace but does not work with IF EXISTS or other more complex statements - * + * * @param string $sql * @return bool */ @@ -245,9 +185,9 @@ class OC_DB { } return false; } - + /** - * @brief execute a prepared statement, on error write log and throw exception + * execute a prepared statement, on error write log and throw exception * @param mixed $stmt OC_DB_StatementWrapper, * an array with 'sql' and optionally 'limit' and 'offset' keys * .. or a simple sql query string @@ -296,7 +236,7 @@ class OC_DB { } /** - * @brief gets last value of autoincrement + * gets last value of autoincrement * @param string $table The optional table name (will replace *PREFIX*) and add sequence suffix * @return string id * @throws DatabaseException @@ -312,7 +252,7 @@ class OC_DB { } /** - * @brief Insert a row if a matching row doesn't exists. + * Insert a row if a matching row doesn't exists. * @param string $table The table to insert into in the form '*PREFIX*tableName' * @param array $input An array of fieldname/value pairs * @return boolean number of updated rows @@ -339,7 +279,7 @@ class OC_DB { } /** - * @brief saves database schema to xml file + * saves database schema to xml file * @param string $file name of file * @param int $mode * @return bool @@ -352,7 +292,7 @@ class OC_DB { } /** - * @brief Creates tables from XML file + * Creates tables from XML file * @param string $file file to read structure from * @return bool * @@ -365,7 +305,7 @@ class OC_DB { } /** - * @brief update the database schema + * update the database schema * @param string $file file to read structure from * @throws Exception * @return string|boolean @@ -382,12 +322,21 @@ class OC_DB { } /** - * @brief drop a table + * drop a table - the database prefix will be prepended * @param string $tableName the table to drop */ public static function dropTable($tableName) { - $schemaManager = self::getMDB2SchemaManager(); - $schemaManager->dropTable($tableName); + + $tableName = OC_Config::getValue('dbtableprefix', 'oc_' ) . trim($tableName); + + self::$connection->beginTransaction(); + + $platform = self::$connection->getDatabasePlatform(); + $sql = $platform->getDropTableSQL($platform->quoteIdentifier($tableName)); + + self::$connection->query($sql); + + self::$connection->commit(); } /** @@ -400,15 +349,6 @@ class OC_DB { } /** - * @brief replaces the ownCloud tables with a new set - * @param $file string path to the MDB2 xml db export file - */ - public static function replaceDB( $file ) { - $schemaManager = self::getMDB2SchemaManager(); - $schemaManager->replaceDB($file); - } - - /** * check if a result is an error, works with Doctrine * @param mixed $result * @return bool @@ -462,4 +402,51 @@ class OC_DB { self::$connection->disableQueryStatementCaching(); } } + + /** + * Checks if a table exists in the database - the database prefix will be prepended + * + * @param string $table + * @return bool + * @throws DatabaseException + */ + public static function tableExists($table) { + + $table = OC_Config::getValue('dbtableprefix', 'oc_' ) . trim($table); + + $dbType = OC_Config::getValue( 'dbtype', 'sqlite' ); + switch ($dbType) { + case 'sqlite': + case 'sqlite3': + $sql = "SELECT name FROM sqlite_master " + . "WHERE type = 'table' AND name = ? " + . "UNION ALL SELECT name FROM sqlite_temp_master " + . "WHERE type = 'table' AND name = ?"; + $result = \OC_DB::executeAudited($sql, array($table, $table)); + break; + case 'mysql': + $sql = 'SHOW TABLES LIKE ?'; + $result = \OC_DB::executeAudited($sql, array($table)); + break; + case 'pgsql': + $sql = 'SELECT tablename AS table_name, schemaname AS schema_name ' + . 'FROM pg_tables WHERE schemaname NOT LIKE \'pg_%\' ' + . 'AND schemaname != \'information_schema\' ' + . 'AND tablename = ?'; + $result = \OC_DB::executeAudited($sql, array($table)); + break; + case 'oci': + $sql = 'SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME = ?'; + $result = \OC_DB::executeAudited($sql, array($table)); + break; + case 'mssql': + $sql = 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ?'; + $result = \OC_DB::executeAudited($sql, array($table)); + break; + default: + throw new DatabaseException("Unknown database type: $dbType"); + } + + return $result->fetchOne() === $table; + } } diff --git a/lib/private/db/adapter.php b/lib/private/db/adapter.php index 6b31f37dd98..975b9432286 100644 --- a/lib/private/db/adapter.php +++ b/lib/private/db/adapter.php @@ -40,7 +40,7 @@ class Adapter { } /** - * @brief insert the @input values when they do not exist yet + * insert the @input values when they do not exist yet * @param string $table name * @param array $input key->value pairs * @return int count of inserted rows diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php index 2bd7b093020..b7981fcd691 100644 --- a/lib/private/db/connection.php +++ b/lib/private/db/connection.php @@ -152,7 +152,7 @@ class Connection extends \Doctrine\DBAL\Connection { } /** - * @brief Insert a row if a matching row doesn't exists. + * Insert a row if a matching row doesn't exists. * @param string $table. The table to insert into in the form '*PREFIX*tableName' * @param array $input. An array of fieldname/value pairs * @return bool The return value from execute() diff --git a/lib/private/db/connectionfactory.php b/lib/private/db/connectionfactory.php new file mode 100644 index 00000000000..8f852cf7127 --- /dev/null +++ b/lib/private/db/connectionfactory.php @@ -0,0 +1,118 @@ +<?php +/** + * Copyright (c) 2014 Andreas Fischer <bantu@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + +/** +* Takes care of creating and configuring Doctrine connections. +*/ +class ConnectionFactory { + /** + * @var array + * + * Array mapping DBMS type to default connection parameters passed to + * \Doctrine\DBAL\DriverManager::getConnection(). + */ + protected $defaultConnectionParams = array( + 'mssql' => array( + 'adapter' => '\OC\DB\AdapterSQLSrv', + 'charset' => 'UTF8', + 'driver' => 'pdo_sqlsrv', + 'wrapperClass' => 'OC\DB\Connection', + ), + 'mysql' => array( + 'adapter' => '\OC\DB\Adapter', + 'charset' => 'UTF8', + 'driver' => 'pdo_mysql', + 'wrapperClass' => 'OC\DB\Connection', + ), + 'oci' => array( + 'adapter' => '\OC\DB\AdapterOCI8', + 'charset' => 'AL32UTF8', + 'driver' => 'oci8', + 'wrapperClass' => 'OC\DB\OracleConnection', + ), + 'pgsql' => array( + 'adapter' => '\OC\DB\AdapterPgSql', + 'driver' => 'pdo_pgsql', + 'wrapperClass' => 'OC\DB\Connection', + ), + 'sqlite3' => array( + 'adapter' => '\OC\DB\AdapterSqlite', + 'driver' => 'pdo_sqlite', + 'wrapperClass' => 'OC\DB\Connection', + ), + ); + + /** + * @brief Get default connection parameters for a given DBMS. + * @param string $type DBMS type + * @throws \InvalidArgumentException If $type is invalid + * @return array Default connection parameters. + */ + public function getDefaultConnectionParams($type) { + $normalizedType = $this->normalizeType($type); + if (!isset($this->defaultConnectionParams[$normalizedType])) { + throw new \InvalidArgumentException("Unsupported type: $type"); + } + return $this->defaultConnectionParams[$normalizedType]; + } + + /** + * @brief Get default connection parameters for a given DBMS. + * @param string $type DBMS type + * @param array $additionalConnectionParams Additional connection parameters + * @return \OC\DB\Connection + */ + public function getConnection($type, $additionalConnectionParams) { + $normalizedType = $this->normalizeType($type); + $eventManager = new \Doctrine\Common\EventManager(); + switch ($normalizedType) { + case 'mysql': + // 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 'oci': + $eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\OracleSessionInit); + break; + } + $connection = \Doctrine\DBAL\DriverManager::getConnection( + array_merge($this->getDefaultConnectionParams($type), $additionalConnectionParams), + new \Doctrine\DBAL\Configuration(), + $eventManager + ); + switch ($normalizedType) { + case 'sqlite3': + // Sqlite doesn't handle query caching and schema changes + // TODO: find a better way to handle this + /** @var $connection \OC\DB\Connection */ + $connection->disableQueryStatementCaching(); + break; + } + return $connection; + } + + /** + * @brief Normalize DBMS type + * @param string $type DBMS type + * @return string Normalized DBMS type + */ + public function normalizeType($type) { + return $type === 'sqlite' ? 'sqlite3' : $type; + } + + /** + * @brief Checks whether the specified DBMS type is valid. + * @return bool + */ + public function isValidType($type) { + $normalizedType = $this->normalizeType($type); + return isset($this->defaultConnectionParams[$normalizedType]); + } +} diff --git a/lib/private/db/connectionwrapper.php b/lib/private/db/connectionwrapper.php index c2cfc21d204..132e76666ab 100644 --- a/lib/private/db/connectionwrapper.php +++ b/lib/private/db/connectionwrapper.php @@ -41,8 +41,8 @@ class ConnectionWrapper implements \OCP\IDBConnection { /** * 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 + * @param string $table The table name (will replace *PREFIX*) to perform the replace on. + * @param array $input * * The input array if in the form: * diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php index aaf2ea543b9..4208dbd18f4 100644 --- a/lib/private/db/mdb2schemamanager.php +++ b/lib/private/db/mdb2schemamanager.php @@ -24,7 +24,7 @@ class MDB2SchemaManager { } /** - * @brief saves database scheme to xml file + * saves database scheme to xml file * @param string $file name of file * @param int|string $mode * @return bool @@ -38,7 +38,7 @@ class MDB2SchemaManager { } /** - * @brief Creates tables from XML file + * Creates tables from XML file * @param string $file file to read structure from * @return bool * @@ -51,7 +51,7 @@ class MDB2SchemaManager { } /** - * @brief update the database scheme + * update the database scheme * @param string $file file to read structure from * @return string|boolean */ @@ -86,7 +86,7 @@ class MDB2SchemaManager { $column->oldColumnName = $platform->quoteIdentifier($column->oldColumnName); } } - + if ($generateSql) { return $this->generateChangeScript($schemaDiff); } @@ -95,19 +95,6 @@ class MDB2SchemaManager { } /** - * @brief drop a table - * @param string $tableName the table to drop - */ - public function dropTable($tableName) { - $sm = $this->conn->getSchemaManager(); - $fromSchema = $sm->createSchema(); - $toSchema = clone $fromSchema; - $toSchema->dropTable($tableName); - $sql = $fromSchema->getMigrateToSql($toSchema, $this->conn->getDatabasePlatform()); - $this->conn->executeQuery($sql); - } - - /** * remove all tables defined in a database structure xml file * @param string $file the xml file describing the tables */ @@ -125,27 +112,6 @@ class MDB2SchemaManager { } /** - * @brief replaces the ownCloud tables with a new set - * @param $file string path to the MDB2 xml db export file - */ - public function replaceDB( $file ) { - $apps = \OC_App::getAllApps(); - $this->conn->beginTransaction(); - // Delete the old tables - $this->removeDBStructure( \OC::$SERVERROOT . '/db_structure.xml' ); - - foreach($apps as $app) { - $path = \OC_App::getAppPath($app).'/appinfo/database.xml'; - if(file_exists($path)) { - $this->removeDBStructure( $path ); - } - } - - // Create new tables - $this->conn->commit(); - } - - /** * @param \Doctrine\DBAL\Schema\Schema $schema * @return bool */ diff --git a/lib/private/db/mdb2schemareader.php b/lib/private/db/mdb2schemareader.php index 1c16d03eab2..597650985fa 100644 --- a/lib/private/db/mdb2schemareader.php +++ b/lib/private/db/mdb2schemareader.php @@ -66,7 +66,7 @@ class MDB2SchemaReader { } /** - * @param\Doctrine\DBAL\Schema\Schema $schema + * @param \Doctrine\DBAL\Schema\Schema $schema * @param \SimpleXMLElement $xml * @throws \DomainException */ @@ -303,7 +303,7 @@ class MDB2SchemaReader { } /** - * @param \SimpleXMLElement | string $xml + * @param \SimpleXMLElement|string $xml * @return bool */ private function asBool($xml) { diff --git a/lib/private/db/pgsqltools.php b/lib/private/db/pgsqltools.php new file mode 100644 index 00000000000..c3ac140594d --- /dev/null +++ b/lib/private/db/pgsqltools.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> + * Copyright (c) 2014 Andreas Fischer <bantu@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + +/** +* Various PostgreSQL specific helper functions. +*/ +class PgSqlTools { + /** + * @brief Resynchronizes all sequences of a database after using INSERTs + * without leaving out the auto-incremented column. + * @param \OC\DB\Connection $conn + * @return null + */ + public function resynchronizeDatabaseSequences(Connection $conn) { + $databaseName = $conn->getDatabase(); + foreach ($conn->getSchemaManager()->listSequences() as $sequence) { + $sequenceName = $sequence->getName(); + $sqlInfo = 'SELECT table_schema, table_name, column_name + FROM information_schema.columns + WHERE column_default = ? AND table_catalog = ?'; + $sequenceInfo = $conn->fetchAssoc($sqlInfo, array( + "nextval('$sequenceName'::regclass)", + $databaseName + )); + $tableName = $sequenceInfo['table_name']; + $columnName = $sequenceInfo['column_name']; + $sqlMaxId = "SELECT MAX($columnName) FROM $tableName"; + $sqlSetval = "SELECT setval('$sequenceName', ($sqlMaxId))"; + $conn->executeQuery($sqlSetval); + } + } +} diff --git a/lib/private/db/statementwrapper.php b/lib/private/db/statementwrapper.php index 492209b883b..93fabc147ca 100644 --- a/lib/private/db/statementwrapper.php +++ b/lib/private/db/statementwrapper.php @@ -13,6 +13,7 @@ * @method string errorCode(); * @method array errorInfo(); * @method integer rowCount(); + * @method array fetchAll(integer $fetchMode = null); */ class OC_DB_StatementWrapper { /** @@ -41,7 +42,7 @@ class OC_DB_StatementWrapper { * make execute return the result instead of a bool * * @param array $input - * @return \OC_DB_StatementWrapper | int + * @return \OC_DB_StatementWrapper|int */ public function execute($input=array()) { if(OC_Config::getValue( "log_query", false)) { diff --git a/lib/private/defaults.php b/lib/private/defaults.php index fca798568c5..663c327a3b0 100644 --- a/lib/private/defaults.php +++ b/lib/private/defaults.php @@ -185,7 +185,7 @@ class OC_Defaults { /** * Returns mail header color - * @return mail header color + * @return string */ public function getMailHeaderColor() { if ($this->themeExist('getMailHeaderColor')) { diff --git a/lib/private/fileproxy.php b/lib/private/fileproxy.php index 88976c1b8e5..2835e974642 100644 --- a/lib/private/fileproxy.php +++ b/lib/private/fileproxy.php @@ -47,7 +47,7 @@ class OC_FileProxy{ /** * fallback function when a proxy operation is not implemented * @param string $function the name of the proxy operation - * @param mixed + * @param mixed $arguments * * this implements a dummy proxy for all operations */ diff --git a/lib/private/files.php b/lib/private/files.php index 3affcf10449..7c437a16a98 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -152,7 +152,7 @@ class OC_Files { /** @var $storage \OC\Files\Storage\Storage */ list($storage) = $view->resolvePath($filename); if ($storage->isLocal()) { - self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename)); + self::addSendfileHeader($filename); } else { \OC\Files\Filesystem::readfile($filename); } @@ -167,9 +167,11 @@ class OC_Files { */ private static function addSendfileHeader($filename) { if (isset($_SERVER['MOD_X_SENDFILE_ENABLED'])) { + $filename = \OC\Files\Filesystem::getLocalFile($filename); header("X-Sendfile: " . $filename); } if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) { + $filename = \OC\Files\Filesystem::getLocalFile($filename); if (isset($_SERVER['HTTP_RANGE']) && preg_match("/^bytes=([0-9]+)-([0-9]*)$/", $_SERVER['HTTP_RANGE'], $range)) { $filelength = filesize($filename); @@ -185,6 +187,7 @@ class OC_Files { } if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { + $filename = \OC::$WEBROOT . '/data' . \OC\Files\Filesystem::getRoot() . $filename; header("X-Accel-Redirect: " . $filename); } } @@ -222,7 +225,7 @@ class OC_Files { * checks if the selected files are within the size constraint. If not, outputs an error page. * * @param string $dir - * @param array | string $files + * @param array|string $files */ static function validateZipDownload($dir, $files) { if (!OC_Config::getValue('allowZipDownload', true)) { diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index 1c9de56f8c5..59963f41e3d 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -109,7 +109,7 @@ class Cache { * get the stored metadata of a file or folder * * @param string/int $file - * @return array | false + * @return array|false */ public function get($file) { if (is_string($file) or $file == '') { @@ -142,11 +142,11 @@ class Cache { } else { //fix types $data['fileid'] = (int)$data['fileid']; - $data['size'] = (int)$data['size']; + $data['size'] = 0 + $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['unencrypted_size'] = 0 + $data['unencrypted_size']; $data['storage'] = $this->storageId; $data['mimetype'] = $this->getMimetype($data['mimetype']); $data['mimepart'] = $this->getMimetype($data['mimepart']); @@ -450,7 +450,7 @@ class Cache { * search for files matching $pattern * * @param string $pattern - * @return array of file data + * @return array an array of file data */ public function search($pattern) { @@ -532,9 +532,9 @@ class Cache { $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); if ($row = $result->fetchRow()) { list($sum, $min, $unencryptedSum) = array_values($row); - $sum = (int)$sum; - $min = (int)$min; - $unencryptedSum = (int)$unencryptedSum; + $sum = 0 + $sum; + $min = 0 + $min; + $unencryptedSum = 0 + $unencryptedSum; if ($min === -1) { $totalSize = $min; } else { @@ -597,12 +597,16 @@ class Cache { * get the path of a file on this storage by it's id * * @param int $id - * @return string | null + * @return string|null */ public function getPathById($id) { $sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ? AND `storage` = ?'; $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); if ($row = $result->fetchRow()) { + // Oracle stores empty strings as null... + if ($row['path'] === null) { + return ''; + } return $row['path']; } else { return null; @@ -636,7 +640,7 @@ class Cache { /** * normalize the given path - * @param $path + * @param string $path * @return string */ public function normalize($path) { diff --git a/lib/private/files/cache/homecache.php b/lib/private/files/cache/homecache.php index 2326c46e8d0..f61769f0b9b 100644 --- a/lib/private/files/cache/homecache.php +++ b/lib/private/files/cache/homecache.php @@ -36,8 +36,10 @@ class HomeCache extends Cache { $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); if ($row = $result->fetchRow()) { list($sum, $unencryptedSum) = array_values($row); - $totalSize = (int)$sum; - $unencryptedSize = (int)$unencryptedSum; + $totalSize = 0 + $sum; + $unencryptedSize = 0 + $unencryptedSum; + $entry['size'] += 0; + $entry['unencrypted_size'] += 0; if ($entry['size'] !== $totalSize) { $this->update($id, array('size' => $totalSize)); } diff --git a/lib/private/files/cache/permissions.php b/lib/private/files/cache/permissions.php index 2e2bdb20b78..eba18af3863 100644 --- a/lib/private/files/cache/permissions.php +++ b/lib/private/files/cache/permissions.php @@ -36,7 +36,7 @@ class Permissions { $sql = 'SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'; $result = \OC_DB::executeAudited($sql, array($user, $fileId)); if ($row = $result->fetchRow()) { - return $row['permissions']; + return $this->updatePermissions($row['permissions']); } else { return -1; } @@ -78,7 +78,7 @@ class Permissions { $result = \OC_DB::executeAudited($sql, $params); $filePermissions = array(); while ($row = $result->fetchRow()) { - $filePermissions[$row['fileid']] = $row['permissions']; + $filePermissions[$row['fileid']] = $this->updatePermissions($row['permissions']); } return $filePermissions; } @@ -99,7 +99,7 @@ class Permissions { $result = \OC_DB::executeAudited($sql, array($parentId, $user)); $filePermissions = array(); while ($row = $result->fetchRow()) { - $filePermissions[$row['fileid']] = $row['permissions']; + $filePermissions[$row['fileid']] = $this->updatePermissions($row['permissions']); } return $filePermissions; } @@ -140,4 +140,17 @@ class Permissions { } return $users; } + + /** + * check if admin removed the share permission for the user and update the permissions + * + * @param int $permissions + * @return int + */ + protected function updatePermissions($permissions) { + if (\OCP\Util::isSharingDisabledForUser()) { + $permissions &= ~\OCP\PERMISSION_SHARE; + } + return $permissions; + } } diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index c0bdde06a75..b97070fcdf0 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -10,6 +10,7 @@ namespace OC\Files\Cache; use OC\Files\Filesystem; use OC\Hooks\BasicEmitter; +use OCP\Config; /** * Class Scanner @@ -26,22 +27,27 @@ class Scanner extends BasicEmitter { /** * @var \OC\Files\Storage\Storage $storage */ - private $storage; + protected $storage; /** * @var string $storageId */ - private $storageId; + protected $storageId; /** * @var \OC\Files\Cache\Cache $cache */ - private $cache; + protected $cache; /** * @var \OC\Files\Cache\Permissions $permissionsCache */ - private $permissionsCache; + protected $permissionsCache; + + /** + * @var boolean $cacheActive If true, perform cache operations, if false, do not affect cache + */ + protected $cacheActive; const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; @@ -54,6 +60,7 @@ class Scanner extends BasicEmitter { $this->storageId = $this->storage->getId(); $this->cache = $storage->getCache(); $this->permissionsCache = $storage->getPermissionsCache(); + $this->cacheActive = !Config::getSystemValue('filesystem_cache_readonly', false); } /** @@ -61,7 +68,7 @@ class Scanner extends BasicEmitter { * * * * @param string $path - * @return array with metadata of the file + * @return array an array of metadata of the file */ public function getData($path) { if (!$this->storage->isReadable($path)) { @@ -88,7 +95,7 @@ class Scanner extends BasicEmitter { * @param string $file * @param int $reuseExisting * @param bool $parentExistsInCache - * @return array with metadata of the scanned file + * @return array an array of metadata of the scanned file */ public function scanFile($file, $reuseExisting = 0, $parentExistsInCache = false) { if (!self::isPartialFile($file) @@ -137,9 +144,12 @@ class Scanner extends BasicEmitter { $parent = ''; } $parentCacheData = $this->cache->get($parent); - $this->cache->update($parentCacheData['fileid'], array( - 'etag' => $this->storage->getETag($parent), - )); + \OC_Hook::emit('Scanner', 'updateCache', array('file' => $file, 'data' => $data)); + if($this->cacheActive) { + $this->cache->update($parentCacheData['fileid'], array( + 'etag' => $this->storage->getETag($parent), + )); + } } } } @@ -156,12 +166,18 @@ class Scanner extends BasicEmitter { } } if (!empty($newData)) { - $data['fileid'] = $this->cache->put($file, $newData); + \OC_Hook::emit('Scanner', 'addToCache', array('file' => $file, 'data' => $newData)); + if($this->cacheActive) { + $data['fileid'] = $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); + \OC_Hook::emit('Scanner', 'removeFromCache', array('file' => $file)); + if($this->cacheActive) { + $this->cache->remove($file); + } } return $data; } @@ -174,7 +190,7 @@ class Scanner extends BasicEmitter { * @param string $path * @param bool $recursive * @param int $reuse - * @return array with the meta data of the scanned file or folder + * @return array an array of the meta data of the scanned file or folder */ public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) { if ($reuse === -1) { @@ -244,7 +260,10 @@ class Scanner extends BasicEmitter { $removedChildren = \array_diff($existingChildren, $newChildren); foreach ($removedChildren as $childName) { $child = ($path) ? $path . '/' . $childName : $childName; - $this->cache->remove($child); + \OC_Hook::emit('Scanner', 'removeFromCache', array('file' => $child)); + if($this->cacheActive) { + $this->cache->remove($child); + } } \OC_DB::commit(); if ($exceptionOccurred){ @@ -263,17 +282,21 @@ class Scanner extends BasicEmitter { $size += $childSize; } } - $this->cache->put($path, array('size' => $size)); + $newData = array('size' => $size); + \OC_Hook::emit('Scanner', 'addToCache', array('file' => $child, 'data' => $newData)); + if($this->cacheActive) { + $this->cache->put($path, $newData); + } } $this->emit('\OC\Files\Cache\Scanner', 'postScanFolder', array($path, $this->storageId)); return $size; } /** - * @brief check if the file should be ignored when scanning + * check if the file should be ignored when scanning * NOTE: files with a '.part' extension are ignored as well! * prevents unfinished put requests to be scanned - * @param String $file + * @param string $file * @return boolean */ public static function isPartialFile($file) { @@ -290,8 +313,19 @@ class Scanner extends BasicEmitter { $lastPath = null; while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG); - $this->cache->correctFolderSize($path); + \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path)); + if($this->cacheActive) { + $this->cache->correctFolderSize($path); + } $lastPath = $path; } } + + /** + * Set whether the cache is affected by scan operations + * @param boolean $active The active state of the cache + */ + public function setCacheActive($active) { + $this->cacheActive = $active; + } } diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php index 199ce5dee78..f6feb6624b2 100644 --- a/lib/private/files/cache/updater.php +++ b/lib/private/files/cache/updater.php @@ -17,7 +17,7 @@ class Updater { * resolve a path to a storage and internal path * * @param string $path the relative path - * @return array consisting of the storage and the internal path + * @return array an array consisting of the storage and the internal path */ static public function resolvePath($path) { $view = \OC\Files\Filesystem::getView(); @@ -108,7 +108,7 @@ class Updater { } /** - * @brief get file owner and path + * get file owner and path * @param string $filename * @return string[] with the oweners uid and the owners path */ diff --git a/lib/private/files/cache/watcher.php b/lib/private/files/cache/watcher.php index 48aa6f853ce..5a4f53fb73d 100644 --- a/lib/private/files/cache/watcher.php +++ b/lib/private/files/cache/watcher.php @@ -45,7 +45,7 @@ class Watcher { } /** - * @param int $policy either \OC\Files\Cache\Watcher::UPDATE_NEVER, \OC\Files\Cache\Watcher::UPDATE_ONCE, \OC\Files\Cache\Watcher::UPDATE_ALWAYS + * @param int $policy either \OC\Files\Cache\Watcher::CHECK_NEVER, \OC\Files\Cache\Watcher::CHECK_ONCE, \OC\Files\Cache\Watcher::CHECK_ALWAYS */ public function setPolicy($policy) { $this->watchPolicy = $policy; @@ -55,7 +55,7 @@ class Watcher { * check $path for updates * * @param string $path - * @return boolean | array true if path was updated, otherwise the cached data is returned + * @return boolean|array true if path was updated, otherwise the cached data is returned */ public function checkUpdate($path) { if ($this->watchPolicy === self::CHECK_ALWAYS or ($this->watchPolicy === self::CHECK_ONCE and array_search($path, $this->checkedPaths) === false)) { diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php index d6940f50bf1..e7afeb4ccce 100644 --- a/lib/private/files/fileinfo.php +++ b/lib/private/files/fileinfo.php @@ -147,7 +147,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { } /** - * @return \OCP\Files\FileInfo::TYPE_FILE | \OCP\Files\FileInfo::TYPE_FOLDER + * @return \OCP\Files\FileInfo::TYPE_FILE|\OCP\Files\FileInfo::TYPE_FOLDER */ public function getType() { if (isset($this->data['type'])) { @@ -196,4 +196,28 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { public function isShareable() { return $this->checkPermissions(\OCP\PERMISSION_SHARE); } + + /** + * Check if a file or folder is shared + * @return bool + */ + public function isShared() { + $sid = $this->getStorage()->getId(); + if (!is_null($sid)) { + $sid = explode(':', $sid); + return ($sid[0] === 'shared'); + } + + return false; + } + + public function isMounted() { + $sid = $this->getStorage()->getId(); + if (!is_null($sid)) { + $sid = explode(':', $sid); + return ($sid[0] !== 'local' and $sid[0] !== 'home'); + } + + return false; + } } diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index 52df1bec611..ad7213d2368 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -245,7 +245,7 @@ class Filesystem { } /** - * @param $id + * @param string $id * @return Mount\Mount[] */ public static function getMountByStorageId($id) { @@ -256,7 +256,7 @@ class Filesystem { } /** - * @param $id + * @param int $id * @return Mount\Mount[] */ public static function getMountByNumericId($id) { @@ -270,7 +270,7 @@ class Filesystem { * resolve a path to a storage and internal path * * @param string $path - * @return array consisting of the storage and the internal path + * @return array an array consisting of the storage and the internal path */ static public function resolvePath($path) { if (!self::$mounts) { @@ -384,7 +384,7 @@ class Filesystem { } /** - * @brief get the relative path of the root data directory for the current user + * get the relative path of the root data directory for the current user * @return string * * Returns path like /admin/files @@ -502,7 +502,7 @@ class Filesystem { } /** - * @brief check if the directory should be ignored when scanning + * check if the directory should be ignored when scanning * NOTE: the special directories . and .. would cause never ending recursion * @param String $dir * @return boolean @@ -662,7 +662,7 @@ class Filesystem { } /** - * @brief Fix common problems with a file path + * Fix common problems with a file path * @param string $path * @param bool $stripTrailingSlash * @return string diff --git a/lib/private/files/mapper.php b/lib/private/files/mapper.php index 833d4bd8d1c..666719da12d 100644 --- a/lib/private/files/mapper.php +++ b/lib/private/files/mapper.php @@ -97,8 +97,8 @@ class Mapper } /** - * @param $path - * @param $root + * @param string $path + * @param string $root * @return false|string */ public function stripRootFolder($path, $root) { diff --git a/lib/private/files/mount/manager.php b/lib/private/files/mount/manager.php index 91460b72730..db1f4600c74 100644 --- a/lib/private/files/mount/manager.php +++ b/lib/private/files/mount/manager.php @@ -33,7 +33,7 @@ class Manager { /** * Find the mount for $path * - * @param $path + * @param string $path * @return Mount */ public function find($path) { @@ -61,7 +61,7 @@ class Manager { /** * Find all mounts in $path * - * @param $path + * @param string $path * @return Mount[] */ public function findIn($path) { @@ -112,7 +112,7 @@ class Manager { /** * Find mounts by numeric storage id * - * @param string $id + * @param int $id * @return Mount[] */ public function findByNumericId($id) { diff --git a/lib/private/files/mount/mount.php b/lib/private/files/mount/mount.php index 08d5ddf348b..7c40853ac95 100644 --- a/lib/private/files/mount/mount.php +++ b/lib/private/files/mount/mount.php @@ -28,7 +28,7 @@ class Mount { private $loader; /** - * @param string | \OC\Files\Storage\Storage $storage + * @param string|\OC\Files\Storage\Storage $storage * @param string $mountpoint * @param array $arguments (optional)\ * @param \OC\Files\Storage\Loader $loader @@ -59,6 +59,8 @@ class Mount { } /** + * get complete path to the mount point, relative to data/ + * * @return string */ public function getMountPoint() { @@ -66,6 +68,15 @@ class Mount { } /** + * get name of the mount point + * + * @return string + */ + public function getMountPointName() { + return basename(rtrim($this->mountPoint, '/')); + } + + /** * @param string $mountPoint new mount point */ public function setMountPoint($mountPoint) { @@ -150,6 +161,6 @@ class Mount { * @param callable $wrapper */ public function wrapStorage($wrapper) { - $this->storage = $wrapper($this->mountPoint, $this->storage); + $this->storage = $wrapper($this->mountPoint, $this->getStorage()); } } diff --git a/lib/private/files/node/folder.php b/lib/private/files/node/folder.php index d9e0ddc2d61..1af34fc2be6 100644 --- a/lib/private/files/node/folder.php +++ b/lib/private/files/node/folder.php @@ -296,7 +296,7 @@ class Folder extends Node implements \OCP\Files\Folder { } /** - * @param $id + * @param int $id * @return \OC\Files\Node\Node[] */ public function getById($id) { diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index 8a263d4ce1e..6b11603323a 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -8,6 +8,9 @@ namespace OC\Files\Storage; +use OC\Files\Filesystem; +use OC\Files\Cache\Watcher; + /** * Storage backend class for providing common filesystem operation methods * which are not storage-backend specific. @@ -19,7 +22,6 @@ namespace OC\Files\Storage; * Some \OC\Files\Storage\Common methods call functions which are first defined * in classes which extend it, e.g. $this->stat() . */ - abstract class Common implements \OC\Files\Storage\Storage { protected $cache; protected $scanner; @@ -35,6 +37,22 @@ abstract class Common implements \OC\Files\Storage\Storage { public function __construct($parameters) { } + /** + * Remove a file of folder + * + * @param string $path + * @return bool + */ + protected function remove($path) { + if ($this->is_dir($path)) { + return $this->rmdir($path); + } else if ($this->is_file($path)) { + return $this->unlink($path); + } else { + return false; + } + } + public function is_dir($path) { return $this->filetype($path) == 'dir'; } @@ -81,6 +99,10 @@ abstract class Common implements \OC\Files\Storage\Storage { } public function isSharable($path) { + if (\OC_Util::isSharingDisabledForUser()) { + return false; + } + return $this->isReadable($path); } @@ -132,20 +154,33 @@ abstract class Common implements \OC\Files\Storage\Storage { } public function rename($path1, $path2) { - if ($this->copy($path1, $path2)) { - $this->removeCachedFile($path1); - return $this->unlink($path1); - } else { - return false; - } + $this->remove($path2); + + $this->removeCachedFile($path1); + return $this->copy($path1, $path2) and $this->remove($path1); } public function copy($path1, $path2) { - $source = $this->fopen($path1, 'r'); - $target = $this->fopen($path2, 'w'); - list($count, $result) = \OC_Helper::streamCopy($source, $target); - $this->removeCachedFile($path2); - return $result; + if ($this->is_dir($path1)) { + $this->remove($path2); + $dir = $this->opendir($path1); + $this->mkdir($path2); + while ($file = readdir($dir)) { + if (!Filesystem::isIgnoredDir($file)) { + if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { + return false; + } + } + } + closedir($dir); + return true; + } else { + $source = $this->fopen($path1, 'r'); + $target = $this->fopen($path2, 'w'); + list(, $result) = \OC_Helper::streamCopy($source, $target); + $this->removeCachedFile($path2); + return $result; + } } public function getMimeType($path) { @@ -276,6 +311,7 @@ abstract class Common implements \OC\Files\Storage\Storage { public function getWatcher($path = '') { if (!isset($this->watcher)) { $this->watcher = new \OC\Files\Cache\Watcher($this); + $this->watcher->setPolicy(\OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_ONCE)); } return $this->watcher; } @@ -317,7 +353,7 @@ abstract class Common implements \OC\Files\Storage\Storage { * clean a path, i.e. remove all redundant '.' and '..' * making sure that it can't point to higher than '/' * - * @param $path The path to clean + * @param string $path The path to clean * @return string cleaned path */ public function cleanPath($path) { @@ -347,7 +383,7 @@ abstract class Common implements \OC\Files\Storage\Storage { /** * get the free space in the storage * - * @param $path + * @param string $path * @return int */ public function free_space($path) { @@ -376,4 +412,14 @@ abstract class Common implements \OC\Files\Storage\Storage { protected function removeCachedFile($path) { unset($this->cachedFiles[$path]); } + + /** + * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class + * + * @param string $class + * @return bool + */ + public function instanceOfStorage($class) { + return is_a($this, $class); + } } diff --git a/lib/private/files/storage/home.php b/lib/private/files/storage/home.php index 1c2a682f197..f66096f6d9c 100644 --- a/lib/private/files/storage/home.php +++ b/lib/private/files/storage/home.php @@ -23,7 +23,7 @@ class Home extends Local { protected $user; /** - * @brief Construct a Home storage instance + * 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. @@ -57,7 +57,7 @@ class Home extends Local { } /** - * @brief Returns the owner of this home storage + * Returns the owner of this home storage * @return \OC\User\User owner of this home storage */ public function getUser() { diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index de940fc7cdb..e33747bbd52 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -89,11 +89,10 @@ if (\OC_Util::runningOnWindows()) { public function stat($path) { $fullPath = $this->datadir . $path; $statResult = stat($fullPath); - - if ($statResult['size'] < 0) { - $size = self::getFileSizeFromOS($fullPath); - $statResult['size'] = $size; - $statResult[7] = $size; + if (PHP_INT_SIZE === 4 && !$this->is_dir($path)) { + $filesize = $this->filesize($path); + $statResult['size'] = $filesize; + $statResult[7] = $filesize; } return $statResult; } @@ -109,15 +108,13 @@ if (\OC_Util::runningOnWindows()) { public function filesize($path) { if ($this->is_dir($path)) { return 0; - } else { - $fullPath = $this->datadir . $path; - $fileSize = filesize($fullPath); - if ($fileSize < 0) { - return self::getFileSizeFromOS($fullPath); - } - - return $fileSize; } + $fullPath = $this->datadir . $path; + if (PHP_INT_SIZE === 4) { + $helper = new \OC\LargeFileHelper; + return $helper->getFilesize($fullPath); + } + return filesize($fullPath); } public function isReadable($path) { @@ -164,7 +161,14 @@ if (\OC_Util::runningOnWindows()) { } public function unlink($path) { - return $this->delTree($path); + if ($this->is_dir($path)) { + return $this->rmdir($path); + } else if ($this->is_file($path)) { + return unlink($this->datadir . $path); + } else { + return false; + } + } public function rename($path1, $path2) { @@ -177,20 +181,21 @@ if (\OC_Util::runningOnWindows()) { return false; } - if ($return = rename($this->datadir . $path1, $this->datadir . $path2)) { + if ($this->is_dir($path2)) { + $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); } - return $return; + + return rename($this->datadir . $path1, $this->datadir . $path2); } public function copy($path1, $path2) { - if ($this->is_dir($path2)) { - if (!$this->file_exists($path2)) { - $this->mkdir($path2); - } - $source = substr($path1, strrpos($path1, '/') + 1); - $path2 .= $source; + if ($this->is_dir($path1)) { + return parent::copy($path1, $path2); + } else { + return copy($this->datadir . $path1, $this->datadir . $path2); } - return copy($this->datadir . $path1, $this->datadir . $path2); } public function fopen($path, $mode) { @@ -212,59 +217,6 @@ if (\OC_Util::runningOnWindows()) { return $return; } - /** - * @param string $dir - */ - private function delTree($dir) { - $dirRelative = $dir; - $dir = $this->datadir . $dir; - if (!file_exists($dir)) return true; - if (!is_dir($dir) || is_link($dir)) return unlink($dir); - foreach (scandir($dir) as $item) { - if ($item == '.' || $item == '..') continue; - if (is_file($dir . '/' . $item)) { - if (unlink($dir . '/' . $item)) { - } - } elseif (is_dir($dir . '/' . $item)) { - if (!$this->delTree($dirRelative . "/" . $item)) { - return false; - }; - } - } - if ($return = rmdir($dir)) { - } - return $return; - } - - /** - * @param string $fullPath - */ - private static function getFileSizeFromOS($fullPath) { - $name = strtolower(php_uname('s')); - // Windows OS: we use COM to access the filesystem - if (strpos($name, 'win') !== false) { - if (class_exists('COM')) { - $fsobj = new \COM("Scripting.FileSystemObject"); - $f = $fsobj->GetFile($fullPath); - return $f->Size; - } - } else if (strpos($name, 'bsd') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -f %z ' . escapeshellarg($fullPath)); - } - } else if (strpos($name, 'linux') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -c %s ' . escapeshellarg($fullPath)); - } - } else { - \OC_Log::write('core', - 'Unable to determine file size of "' . $fullPath . '". Unknown OS: ' . $name, - \OC_Log::ERROR); - } - - return 0; - } - public function hash($type, $path, $raw = false) { return hash_file($type, $this->datadir . $path, $raw); } diff --git a/lib/private/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php index 07691661644..ea4deaa66e8 100644 --- a/lib/private/files/storage/mappedlocal.php +++ b/lib/private/files/storage/mappedlocal.php @@ -10,29 +10,33 @@ namespace OC\Files\Storage; /** * for local filestore, we only have to map the paths */ -class MappedLocal extends \OC\Files\Storage\Common{ +class MappedLocal extends \OC\Files\Storage\Common { protected $datadir; private $mapper; public function __construct($arguments) { - $this->datadir=$arguments['datadir']; - if(substr($this->datadir, -1)!=='/') { - $this->datadir.='/'; + $this->datadir = $arguments['datadir']; + if (substr($this->datadir, -1) !== '/') { + $this->datadir .= '/'; } - $this->mapper= new \OC\Files\Mapper($this->datadir); + $this->mapper = new \OC\Files\Mapper($this->datadir); } + public function __destruct() { if (defined('PHPUNIT_RUN')) { $this->mapper->removePath($this->datadir, true, true); } } - public function getId(){ - return 'local::'.$this->datadir; + + public function getId() { + return 'local::' . $this->datadir; } + public function mkdir($path) { return @mkdir($this->buildPath($path), 0777, true); } + public function rmdir($path) { try { $it = new \RecursiveIteratorIterator( @@ -68,9 +72,10 @@ class MappedLocal extends \OC\Files\Storage\Common{ return false; } } + public function opendir($path) { $files = array('.', '..'); - $physicalPath= $this->buildPath($path); + $physicalPath = $this->buildPath($path); $logicalPath = $this->mapper->physicalToLogic($physicalPath); $dh = opendir($physicalPath); @@ -80,7 +85,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ continue; } - $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.'/'.$file); + $logicalFilePath = $this->mapper->physicalToLogic($physicalPath . '/' . $file); $file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath); $file = $this->stripLeading($file); @@ -88,121 +93,151 @@ class MappedLocal extends \OC\Files\Storage\Common{ } } - \OC\Files\Stream\Dir::register('local-win32'.$path, $files); - return opendir('fakedir://local-win32'.$path); + \OC\Files\Stream\Dir::register('local-win32' . $path, $files); + return opendir('fakedir://local-win32' . $path); } + public function is_dir($path) { - if(substr($path, -1)=='/') { - $path=substr($path, 0, -1); + if (substr($path, -1) == '/') { + $path = substr($path, 0, -1); } return is_dir($this->buildPath($path)); } + public function is_file($path) { return is_file($this->buildPath($path)); } + public function stat($path) { $fullPath = $this->buildPath($path); $statResult = stat($fullPath); - - if ($statResult['size'] < 0) { - $size = self::getFileSizeFromOS($fullPath); - $statResult['size'] = $size; - $statResult[7] = $size; + if (PHP_INT_SIZE === 4 && !$this->is_dir($path)) { + $filesize = $this->filesize($path); + $statResult['size'] = $filesize; + $statResult[7] = $filesize; } return $statResult; } + public function filetype($path) { - $filetype=filetype($this->buildPath($path)); - if($filetype=='link') { - $filetype=filetype(realpath($this->buildPath($path))); + $filetype = filetype($this->buildPath($path)); + if ($filetype == 'link') { + $filetype = filetype(realpath($this->buildPath($path))); } return $filetype; } + public function filesize($path) { - if($this->is_dir($path)) { + if ($this->is_dir($path)) { return 0; - }else{ - $fullPath = $this->buildPath($path); - $fileSize = filesize($fullPath); - if ($fileSize < 0) { - return self::getFileSizeFromOS($fullPath); - } - - return $fileSize; } + $fullPath = $this->buildPath($path); + if (PHP_INT_SIZE === 4) { + $helper = new \OC\LargeFileHelper; + return $helper->getFilesize($fullPath); + } + return filesize($fullPath); } + public function isReadable($path) { return is_readable($this->buildPath($path)); } + public function isUpdatable($path) { return is_writable($this->buildPath($path)); } + public function file_exists($path) { return file_exists($this->buildPath($path)); } + public function filemtime($path) { return filemtime($this->buildPath($path)); } - public function touch($path, $mtime=null) { + + public function touch($path, $mtime = null) { // sets the modification time of the file to the given value. // If mtime is nil the current time is set. // note that the access time of the file always changes to the current time. - if(!is_null($mtime)) { - $result=touch( $this->buildPath($path), $mtime ); - }else{ - $result=touch( $this->buildPath($path)); + if (!is_null($mtime)) { + $result = touch($this->buildPath($path), $mtime); + } else { + $result = touch($this->buildPath($path)); } - if( $result ) { - clearstatcache( true, $this->buildPath($path) ); + if ($result) { + clearstatcache(true, $this->buildPath($path)); } return $result; } + public function file_get_contents($path) { return file_get_contents($this->buildPath($path)); } + public function file_put_contents($path, $data) { return file_put_contents($this->buildPath($path), $data); } + public function unlink($path) { return $this->delTree($path); } + public function rename($path1, $path2) { if (!$this->isUpdatable($path1)) { - \OC_Log::write('core', 'unable to rename, file is not writable : '.$path1, \OC_Log::ERROR); + \OC_Log::write('core', 'unable to rename, file is not writable : ' . $path1, \OC_Log::ERROR); return false; } - if(! $this->file_exists($path1)) { - \OC_Log::write('core', 'unable to rename, file does not exists : '.$path1, \OC_Log::ERROR); + if (!$this->file_exists($path1)) { + \OC_Log::write('core', 'unable to rename, file does not exists : ' . $path1, \OC_Log::ERROR); return false; } + if ($this->is_dir($path2)) { + $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); + } + $physicPath1 = $this->buildPath($path1); $physicPath2 = $this->buildPath($path2); - if($return=rename($physicPath1, $physicPath2)) { + if ($return = rename($physicPath1, $physicPath2)) { // mapper needs to create copies or all children $this->copyMapping($path1, $path2); $this->cleanMapper($physicPath1, false, true); } return $return; } + public function copy($path1, $path2) { - if($this->is_dir($path2)) { - if(!$this->file_exists($path2)) { - $this->mkdir($path2); + if ($this->is_dir($path1)) { + if ($this->is_dir($path2)) { + $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); } - $source=substr($path1, strrpos($path1, '/')+1); - $path2.=$source; - } - if($return=copy($this->buildPath($path1), $this->buildPath($path2))) { - // mapper needs to create copies or all children - $this->copyMapping($path1, $path2); + $dir = $this->opendir($path1); + $this->mkdir($path2); + while ($file = readdir($dir)) { + if (!\OC\Files\Filesystem::isIgnoredDir($file)) { + if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { + return false; + } + } + } + closedir($dir); + return true; + } else { + if ($return = copy($this->buildPath($path1), $this->buildPath($path2))) { + $this->copyMapping($path1, $path2); + } + return $return; } - return $return; } + public function fopen($path, $mode) { - if($return=fopen($this->buildPath($path), $mode)) { - switch($mode) { + if ($return = fopen($this->buildPath($path), $mode)) { + switch ($mode) { case 'r': break; case 'r+': @@ -223,15 +258,15 @@ class MappedLocal extends \OC\Files\Storage\Common{ * @param string $dir */ private function delTree($dir, $isLogicPath=true) { - $dirRelative=$dir; + $dirRelative = $dir; if ($isLogicPath) { - $dir=$this->buildPath($dir); + $dir = $this->buildPath($dir); } if (!file_exists($dir)) { return true; } if (!is_dir($dir) || is_link($dir)) { - if($return=unlink($dir)) { + if ($return = unlink($dir)) { $this->cleanMapper($dir, false); return $return; } @@ -240,52 +275,23 @@ class MappedLocal extends \OC\Files\Storage\Common{ if ($item == '.' || $item == '..') { continue; } - if(is_file($dir.'/'.$item)) { - if(unlink($dir.'/'.$item)) { - $this->cleanMapper($dir.'/'.$item, false); + if (is_file($dir . '/' . $item)) { + if (unlink($dir . '/' . $item)) { + $this->cleanMapper($dir . '/' . $item, false); } - }elseif(is_dir($dir.'/'.$item)) { - if (!$this->delTree($dir. "/" . $item, false)) { + } elseif (is_dir($dir . '/' . $item)) { + if (!$this->delTree($dir . "/" . $item, false)) { return false; }; } } - if($return=rmdir($dir)) { + if ($return = rmdir($dir)) { $this->cleanMapper($dir, false); } return $return; } - /** - * @param string $fullPath - */ - private static function getFileSizeFromOS($fullPath) { - $name = strtolower(php_uname('s')); - // Windows OS: we use COM to access the filesystem - if (strpos($name, 'win') !== false) { - if (class_exists('COM')) { - $fsobj = new \COM("Scripting.FileSystemObject"); - $f = $fsobj->GetFile($fullPath); - return $f->Size; - } - } else if (strpos($name, 'bsd') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -f %z ' . escapeshellarg($fullPath)); - } - } else if (strpos($name, 'linux') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -c %s ' . escapeshellarg($fullPath)); - } - } else { - \OC_Log::write('core', - 'Unable to determine file size of "'.$fullPath.'". Unknown OS: '.$name, - \OC_Log::ERROR); - } - - return 0; - } - - public function hash($type, $path, $raw=false) { + public function hash($type, $path, $raw = false) { return hash_file($type, $this->buildPath($path), $raw); } @@ -296,9 +302,11 @@ class MappedLocal extends \OC\Files\Storage\Common{ public function search($query) { return $this->searchInDir($query); } + public function getLocalFile($path) { return $this->buildPath($path); } + public function getLocalFolder($path) { return $this->buildPath($path); } @@ -306,20 +314,20 @@ class MappedLocal extends \OC\Files\Storage\Common{ /** * @param string $query */ - protected function searchInDir($query, $dir='') { - $files=array(); + protected function searchInDir($query, $dir = '') { + $files = array(); $physicalDir = $this->buildPath($dir); foreach (scandir($physicalDir) as $item) { if ($item == '.' || $item == '..') continue; - $physicalItem = $this->mapper->physicalToLogic($physicalDir.'/'.$item); - $item = substr($physicalItem, strlen($physicalDir)+1); + $physicalItem = $this->mapper->physicalToLogic($physicalDir . '/' . $item); + $item = substr($physicalItem, strlen($physicalDir) + 1); - if(strstr(strtolower($item), strtolower($query)) !== false) { - $files[]=$dir.'/'.$item; + if (strstr(strtolower($item), strtolower($query)) !== false) { + $files[] = $dir . '/' . $item; } - if(is_dir($physicalItem)) { - $files=array_merge($files, $this->searchInDir($query, $dir.'/'.$item)); + if (is_dir($physicalItem)) { + $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item)); } } return $files; @@ -327,30 +335,31 @@ class MappedLocal extends \OC\Files\Storage\Common{ /** * check if a file or folder has been updated since $time + * * @param string $path * @param int $time * @return bool */ public function hasUpdated($path, $time) { - return $this->filemtime($path)>$time; + return $this->filemtime($path) > $time; } /** * @param string $path */ - private function buildPath($path, $create=true) { + private function buildPath($path, $create = true) { $path = $this->stripLeading($path); - $fullPath = $this->datadir.$path; + $fullPath = $this->datadir . $path; return $this->mapper->logicToPhysical($fullPath, $create); } /** * @param string $path */ - private function cleanMapper($path, $isLogicPath=true, $recursive=true) { + private function cleanMapper($path, $isLogicPath = true, $recursive=true) { $fullPath = $path; if ($isLogicPath) { - $fullPath = $this->datadir.$path; + $fullPath = $this->datadir . $path; } $this->mapper->removePath($fullPath, $isLogicPath, $recursive); } @@ -363,8 +372,8 @@ class MappedLocal extends \OC\Files\Storage\Common{ $path1 = $this->stripLeading($path1); $path2 = $this->stripLeading($path2); - $fullPath1 = $this->datadir.$path1; - $fullPath2 = $this->datadir.$path2; + $fullPath1 = $this->datadir . $path1; + $fullPath2 = $this->datadir . $path2; $this->mapper->copy($fullPath1, $fullPath2); } @@ -373,10 +382,10 @@ class MappedLocal extends \OC\Files\Storage\Common{ * @param string $path */ private function stripLeading($path) { - if(strpos($path, '/') === 0) { + if (strpos($path, '/') === 0) { $path = substr($path, 1); } - if(strpos($path, '\\') === 0) { + if (strpos($path, '\\') === 0) { $path = substr($path, 1); } if ($path === false) { diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php index a878b2c5cf6..c57c797f87a 100644 --- a/lib/private/files/storage/wrapper/quota.php +++ b/lib/private/files/storage/wrapper/quota.php @@ -30,7 +30,7 @@ class Quota extends Wrapper { } /** - * @return quota value + * @return int quota value */ public function getQuota() { return $this->quota; diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php index 11ea9f71da7..364475a68e0 100644 --- a/lib/private/files/storage/wrapper/wrapper.php +++ b/lib/private/files/storage/wrapper/wrapper.php @@ -440,4 +440,25 @@ class Wrapper implements \OC\Files\Storage\Storage { public function isLocal() { return $this->storage->isLocal(); } + + /** + * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class + * + * @param string $class + * @return bool + */ + public function instanceOfStorage($class) { + return is_a($this, $class) or $this->storage->instanceOfStorage($class); + } + + /** + * Pass any methods custom to specific storage implementations to the wrapped storage + * + * @param string $method + * @param array $args + * @return mixed + */ + public function __call($method, $args) { + return call_user_func_array(array($this->storage, $method), $args); + } } diff --git a/lib/private/files/stream/oc.php b/lib/private/files/stream/oc.php index 88e7e062df9..c206b41f55e 100644 --- a/lib/private/files/stream/oc.php +++ b/lib/private/files/stream/oc.php @@ -18,7 +18,15 @@ class OC { static private $rootView; private $path; + + /** + * @var resource + */ private $dirSource; + + /** + * @var resource + */ private $fileSource; private $meta; diff --git a/lib/private/files/type/templatemanager.php b/lib/private/files/type/templatemanager.php index cd1536d2732..e693e7079a5 100644 --- a/lib/private/files/type/templatemanager.php +++ b/lib/private/files/type/templatemanager.php @@ -19,7 +19,7 @@ class TemplateManager { * get the path of the template for a mimetype * * @param string $mimetype - * @return string | null + * @return string|null */ public function getTemplatePath($mimetype) { if (isset($this->templates[$mimetype])) { diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 47fc04c937d..0b8d336f260 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -11,7 +11,7 @@ * working with files within that view (e.g. read, write, delete, etc.). Each * view is restricted to a set of directories via a virtual root. The default view * uses the currently logged in user's data directory as root (parts of - * OC_Filesystem are merely a wrapper for OC_FilesystemView). + * OC_Filesystem are merely a wrapper for OC\Files\View). * * Apps that need to access files outside of the user data folders (to modify files * belonging to a user other than the one currently logged in, for example) should @@ -29,15 +29,14 @@ use OC\Files\Cache\Updater; class View { private $fakeRoot = ''; - private $internal_path_cache = array(); - private $storage_cache = array(); public function __construct($root = '') { $this->fakeRoot = $root; } public function getAbsolutePath($path = '/') { - if (!$path) { + $this->assertPathLength($path); + if ($path === '') { $path = '/'; } if ($path[0] !== '/') { @@ -77,6 +76,7 @@ class View { * @return string */ public function getRelativePath($path) { + $this->assertPathLength($path); if ($this->fakeRoot == '') { return $path; } @@ -109,7 +109,7 @@ class View { * resolve a path to a storage and internal path * * @param string $path - * @return array consisting of the storage and the internal path + * @return array an array consisting of the storage and the internal path */ public function resolvePath($path) { $a = $this->getAbsolutePath($path); @@ -168,6 +168,10 @@ class View { } } + /** + * @param string $path + * @return resource + */ public function opendir($path) { return $this->basicOperation('opendir', $path, array('read')); } @@ -204,6 +208,7 @@ class View { } public function readfile($path) { + $this->assertPathLength($path); @ob_end_clean(); $handle = $this->fopen($path, 'rb'); if ($handle) { @@ -428,7 +433,7 @@ class View { if ($this->is_dir($path1)) { $result = $this->copy($path1, $path2); if ($result === true) { - $result = $storage1->unlink($internalPath1); + $result = $storage1->rmdir($internalPath1); } } else { $source = $this->fopen($path1 . $postFix1, 'r'); @@ -552,6 +557,11 @@ class View { } } + /** + * @param string $path + * @param string $mode + * @return resource + */ public function fopen($path, $mode) { $hooks = array(); switch ($mode) { @@ -586,6 +596,7 @@ class View { } public function toTmpFile($path) { + $this->assertPathLength($path); if (Filesystem::isValidPath($path)) { $source = $this->fopen($path, 'r'); if ($source) { @@ -602,7 +613,7 @@ class View { } public function fromTmpFile($tmpFile, $path) { - + $this->assertPathLength($path); if (Filesystem::isValidPath($path)) { // Get directory that the file is going into @@ -631,6 +642,7 @@ class View { } public function getMimeType($path) { + $this->assertPathLength($path); return $this->basicOperation('getMimeType', $path); } @@ -660,11 +672,12 @@ class View { } public function free_space($path = '/') { + $this->assertPathLength($path); return $this->basicOperation('free_space', $path); } /** - * @brief abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage + * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage * @param string $operation * @param string $path * @param array $hooks (optional) @@ -796,9 +809,10 @@ class View { * @param string $path * @param boolean $includeMountPoints whether to add mountpoint sizes, * defaults to true - * @return \OC\Files\FileInfo | false + * @return \OC\Files\FileInfo|false */ public function getFileInfo($path, $includeMountPoints = true) { + $this->assertPathLength($path); $data = array(); if (!Filesystem::isValidPath($path)) { return $data; @@ -869,6 +883,7 @@ class View { * @return FileInfo[] */ public function getDirectoryContent($directory, $mimetype_filter = '') { + $this->assertPathLength($directory); $result = array(); if (!Filesystem::isValidPath($directory)) { return $result; @@ -991,12 +1006,13 @@ class View { * change file metadata * * @param string $path - * @param array | \OCP\Files\FileInfo $data + * @param array|\OCP\Files\FileInfo $data * @return int * * returns the fileid of the updated file */ public function putFileInfo($path, $data) { + $this->assertPathLength($path); if ($data instanceof FileInfo) { $data = $data->getData(); } @@ -1144,4 +1160,12 @@ class View { } return null; } + + private function assertPathLength($path) { + $maxLen = min(PHP_MAXPATHLEN, 4000); + $pathLen = strlen($path); + if ($pathLen > $maxLen) { + throw new \OCP\Files\InvalidPathException("Path length($pathLen) exceeds max path length($maxLen): $path"); + } + } } diff --git a/lib/private/geo.php b/lib/private/geo.php index cd62511f0c1..bd9253bc0dd 100644 --- a/lib/private/geo.php +++ b/lib/private/geo.php @@ -7,9 +7,9 @@ */ class OC_Geo{ /** - * @brief returns the closest timezone to coordinates - * @param $latitude - * @param $longitude + * returns the closest timezone to coordinates + * @param float $latitude + * @param float $longitude * @return mixed Closest timezone */ public static function timezone($latitude, $longitude) { diff --git a/lib/private/group.php b/lib/private/group.php index ea6384bae3e..8dc38129205 100644 --- a/lib/private/group.php +++ b/lib/private/group.php @@ -57,8 +57,8 @@ class OC_Group { } /** - * @brief set the group backend - * @param \OC_Group_Backend $backend The backend to use for user managment + * set the group backend + * @param \OC_Group_Backend $backend The backend to use for user managment * @return bool */ public static function useBackend($backend) { @@ -74,7 +74,7 @@ class OC_Group { } /** - * @brief Try to create a new group + * Try to create a new group * @param string $gid The name of the group to create * @return bool * @@ -93,7 +93,7 @@ class OC_Group { } /** - * @brief delete a group + * delete a group * @param string $gid gid of the group to delete * @return bool * @@ -118,7 +118,7 @@ class OC_Group { } /** - * @brief is user in group? + * is user in group? * @param string $uid uid of the user * @param string $gid gid of the group * @return bool @@ -135,7 +135,7 @@ class OC_Group { } /** - * @brief Add a user to a group + * Add a user to a group * @param string $uid Name of the user to add to group * @param string $gid Name of the group in which add the user * @return bool @@ -156,7 +156,7 @@ class OC_Group { } /** - * @brief Removes a user from a group + * Removes a user from a group * @param string $uid Name of the user to remove from group * @param string $gid Name of the group from which remove the user * @return bool @@ -177,9 +177,9 @@ class OC_Group { } /** - * @brief Get all groups a user belongs to + * Get all groups a user belongs to * @param string $uid Name of the user - * @return array with group names + * @return array an array of group names * * This function fetches all groups a user belongs to. It does not check * if the user exists at all. @@ -199,11 +199,11 @@ class OC_Group { } /** - * @brief get a list of all groups + * get a list of all groups * @param string $search * @param int|null $limit * @param int|null $offset - * @returns array with group names + * @return array an array of group names * * Returns a list with all groups */ @@ -227,12 +227,12 @@ class OC_Group { } /** - * @brief get a list of all users in a group + * get a list of all users in a group * @param string $gid * @param string $search * @param int $limit * @param int $offset - * @returns array with user ids + * @return array an array of user ids */ public static function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { $group = self::getManager()->get($gid); @@ -249,12 +249,12 @@ class OC_Group { } /** - * @brief get a list of all users in several groups + * get a list of all users in several groups * @param string[] $gids * @param string $search * @param int $limit * @param int $offset - * @return array with user ids + * @return array an array of user ids */ public static function usersInGroups($gids, $search = '', $limit = -1, $offset = 0) { $users = array(); @@ -266,24 +266,24 @@ class OC_Group { } /** - * @brief get a list of all display names in a group + * get a list of all display names in a group * @param string $gid * @param string $search * @param int $limit * @param int $offset - * @returns array with display names (value) and user ids(key) + * @return array an array of display names (value) and user ids(key) */ public static function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { return self::getManager()->displayNamesInGroup($gid, $search, $limit, $offset); } /** - * @brief get a list of all display names in several groups + * get a list of all display names in several groups * @param array $gids * @param string $search * @param int $limit * @param int $offset - * @return array with display names (Key) user ids (value) + * @return array an array of display names (Key) user ids (value) */ public static function displayNamesInGroups($gids, $search = '', $limit = -1, $offset = 0) { $displayNames = array(); diff --git a/lib/private/group/backend.php b/lib/private/group/backend.php index cc61fce1615..ab694268bb3 100644 --- a/lib/private/group/backend.php +++ b/lib/private/group/backend.php @@ -49,7 +49,7 @@ abstract class OC_Group_Backend implements OC_Group_Interface { ); /** - * @brief Get all supported actions + * Get all supported actions * @return int bitwise-or'ed actions * * Returns the supported actions as int to be @@ -67,9 +67,9 @@ abstract class OC_Group_Backend implements OC_Group_Interface { } /** - * @brief Check if backend implements actions + * Check if backend implements actions * @param int $actions bitwise-or'ed actions - * @return boolean + * @return bool * * Returns the supported actions as int to be * compared with OC_GROUP_BACKEND_CREATE_GROUP etc. @@ -79,7 +79,7 @@ abstract class OC_Group_Backend implements OC_Group_Interface { } /** - * @brief is user in group? + * is user in group? * @param string $uid uid of the user * @param string $gid gid of the group * @return bool @@ -91,9 +91,9 @@ abstract class OC_Group_Backend implements OC_Group_Interface { } /** - * @brief Get all groups a user belongs to + * Get all groups a user belongs to * @param string $uid Name of the user - * @return array with group names + * @return array an array of group names * * This function fetches all groups a user belongs to. It does not check * if the user exists at all. @@ -103,11 +103,11 @@ abstract class OC_Group_Backend implements OC_Group_Interface { } /** - * @brief get a list of all groups + * get a list of all groups * @param string $search * @param int $limit * @param int $offset - * @return array with group names + * @return array an array of group names * * Returns a list with all groups */ @@ -126,12 +126,12 @@ abstract class OC_Group_Backend implements OC_Group_Interface { } /** - * @brief get a list of all users in a group + * get a list of all users in a group * @param string $gid * @param string $search * @param int $limit * @param int $offset - * @return array with user ids + * @return array an array of user ids */ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { return array(); diff --git a/lib/private/group/database.php b/lib/private/group/database.php index df0d84d0d2a..baaf2cf2739 100644 --- a/lib/private/group/database.php +++ b/lib/private/group/database.php @@ -43,7 +43,7 @@ class OC_Group_Database extends OC_Group_Backend { /** - * @brief Try to create a new group + * Try to create a new group * @param string $gid The name of the group to create * @return bool * @@ -69,7 +69,7 @@ class OC_Group_Database extends OC_Group_Backend { } /** - * @brief delete a group + * delete a group * @param string $gid gid of the group to delete * @return bool * @@ -88,7 +88,7 @@ class OC_Group_Database extends OC_Group_Backend { } /** - * @brief is user in group? + * is user in group? * @param string $uid uid of the user * @param string $gid gid of the group * @return bool @@ -104,7 +104,7 @@ class OC_Group_Database extends OC_Group_Backend { } /** - * @brief Add a user to a group + * Add a user to a group * @param string $uid Name of the user to add to group * @param string $gid Name of the group in which add the user * @return bool @@ -123,7 +123,7 @@ class OC_Group_Database extends OC_Group_Backend { } /** - * @brief Removes a user from a group + * Removes a user from a group * @param string $uid Name of the user to remove from group * @param string $gid Name of the group from which remove the user * @return bool @@ -138,9 +138,9 @@ class OC_Group_Database extends OC_Group_Backend { } /** - * @brief Get all groups a user belongs to + * Get all groups a user belongs to * @param string $uid Name of the user - * @return array with group names + * @return array an array of group names * * This function fetches all groups a user belongs to. It does not check * if the user exists at all. @@ -159,11 +159,11 @@ class OC_Group_Database extends OC_Group_Backend { } /** - * @brief get a list of all groups + * get a list of all groups * @param string $search * @param int $limit * @param int $offset - * @return array with group names + * @return array an array of group names * * Returns a list with all groups */ @@ -192,12 +192,12 @@ class OC_Group_Database extends OC_Group_Backend { } /** - * @brief get a list of all users in a group + * get a list of all users in a group * @param string $gid * @param string $search * @param int $limit * @param int $offset - * @return array with user ids + * @return array an array of user ids */ public function usersInGroup($gid, $search = '', $limit = null, $offset = null) { $stmt = OC_DB::prepare('SELECT `uid` FROM `*PREFIX*group_user` WHERE `gid` = ? AND `uid` LIKE ?', @@ -212,12 +212,11 @@ class OC_Group_Database extends OC_Group_Backend { } /** - * @brief get the number of all users matching the search string in a group + * get the number of all users matching the search string in a group * @param string $gid * @param string $search - * @param int $limit - * @param int $offset - * @return int | false + * @return int|false + * @throws DatabaseException */ public function countUsersInGroup($gid, $search = '') { $stmt = OC_DB::prepare('SELECT COUNT(`uid`) AS `count` FROM `*PREFIX*group_user` WHERE `gid` = ? AND `uid` LIKE ?'); diff --git a/lib/private/group/dummy.php b/lib/private/group/dummy.php index 94cbb607ad1..e48c6a0e266 100644 --- a/lib/private/group/dummy.php +++ b/lib/private/group/dummy.php @@ -27,11 +27,11 @@ class OC_Group_Dummy extends OC_Group_Backend { private $groups=array(); /** - * @brief Try to create a new group + * Try to create a new group * @param string $gid The name of the group to create - * @returns true/false + * @return bool * - * Trys to create a new group. If the group name already exists, false will + * Tries to create a new group. If the group name already exists, false will * be returned. */ public function createGroup($gid) { @@ -44,9 +44,9 @@ class OC_Group_Dummy extends OC_Group_Backend { } /** - * @brief delete a group - * @param $gid gid of the group to delete - * @returns true/false + * delete a group + * @param string $gid gid of the group to delete + * @return bool * * Deletes a group and removes it from the group_user-table */ @@ -60,10 +60,10 @@ class OC_Group_Dummy extends OC_Group_Backend { } /** - * @brief is user in group? - * @param $uid uid of the user - * @param $gid gid of the group - * @returns true/false + * is user in group? + * @param string $uid uid of the user + * @param string $gid gid of the group + * @return bool * * Checks whether the user is member of a group or not. */ @@ -76,10 +76,10 @@ class OC_Group_Dummy extends OC_Group_Backend { } /** - * @brief Add a user to a group - * @param $uid Name of the user to add to group - * @param $gid Name of the group in which add the user - * @returns true/false + * Add a user to a group + * @param string $uid Name of the user to add to group + * @param string $gid Name of the group in which add the user + * @return bool * * Adds a user to a group. */ @@ -97,10 +97,10 @@ class OC_Group_Dummy extends OC_Group_Backend { } /** - * @brief Removes a user from a group - * @param $uid NameUSER of the user to remove from group - * @param $gid Name of the group from which remove the user - * @returns true/false + * Removes a user from a group + * @param string $uid Name of the user to remove from group + * @param string $gid Name of the group from which remove the user + * @return bool * * removes the user from a group. */ @@ -117,9 +117,9 @@ class OC_Group_Dummy extends OC_Group_Backend { } /** - * @brief Get all groups a user belongs to - * @param $uid Name of the user - * @returns array with group names + * Get all groups a user belongs to + * @param string $uid Name of the user + * @return array an array of group names * * This function fetches all groups a user belongs to. It does not check * if the user exists at all. @@ -136,18 +136,23 @@ class OC_Group_Dummy extends OC_Group_Backend { } /** - * @brief get a list of all groups - * @returns array with group names - * - * Returns a list with all groups + * Get a list of all groups + * @param string $search + * @param int $limit + * @param int $offset + * @return array an array of group names */ public function getGroups($search = '', $limit = -1, $offset = 0) { return array_keys($this->groups); } /** - * @brief get a list of all users in a group - * @returns array with user ids + * Get a list of all users in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return array an array of user IDs */ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { if(isset($this->groups[$gid])) { @@ -158,8 +163,12 @@ class OC_Group_Dummy extends OC_Group_Backend { } /** - * @brief get the number of all users in a group - * @returns int | bool + * get the number of all users in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return int */ public function countUsersInGroup($gid, $search = '', $limit = -1, $offset = 0) { if(isset($this->groups[$gid])) { diff --git a/lib/private/group/example.php b/lib/private/group/example.php index 3519b9ed92f..8c1e22866f2 100644 --- a/lib/private/group/example.php +++ b/lib/private/group/example.php @@ -27,58 +27,58 @@ */ abstract class OC_Group_Example { /** - * @brief Try to create a new group - * @param $gid The name of the group to create - * @returns true/false + * Try to create a new group + * @param string $gid The name of the group to create + * @return bool * - * Trys to create a new group. If the group name already exists, false will + * Tries to create a new group. If the group name already exists, false will * be returned. */ abstract public static function createGroup($gid); /** - * @brief delete a group - * @param $gid gid of the group to delete - * @returns true/false + * delete a group + * @param string $gid gid of the group to delete + * @return bool * * Deletes a group and removes it from the group_user-table */ abstract public static function deleteGroup($gid); /** - * @brief is user in group? - * @param $uid uid of the user - * @param $gid gid of the group - * @returns true/false + * is user in group? + * @param string $uid uid of the user + * @param string $gid gid of the group + * @return bool * * Checks whether the user is member of a group or not. */ abstract public static function inGroup($uid, $gid); /** - * @brief Add a user to a group - * @param $uid Name of the user to add to group - * @param $gid Name of the group in which add the user - * @returns true/false + * Add a user to a group + * @param string $uid Name of the user to add to group + * @param string $gid Name of the group in which add the user + * @return bool * * Adds a user to a group. */ abstract public static function addToGroup($uid, $gid); /** - * @brief Removes a user from a group - * @param $uid NameUSER of the user to remove from group - * @param $gid Name of the group from which remove the user - * @returns true/false + * Removes a user from a group + * @param string $uid Name of the user to remove from group + * @param string $gid Name of the group from which remove the user + * @return bool * * removes the user from a group. */ abstract public static function removeFromGroup($uid, $gid); /** - * @brief Get all groups a user belongs to - * @param $uid Name of the user - * @returns array with group names + * Get all groups a user belongs to + * @param string $uid Name of the user + * @return array an array of group names * * This function fetches all groups a user belongs to. It does not check * if the user exists at all. @@ -86,24 +86,28 @@ abstract class OC_Group_Example { abstract public static function getUserGroups($uid); /** - * @brief get a list of all groups - * @returns array with group names - * - * Returns a list with all groups + * get a list of all groups + * @param string $search + * @param int $limit + * @param int $offset + * @return array an array of group names */ abstract public static function getGroups($search = '', $limit = -1, $offset = 0); /** - * check if a group exists + * Check if a group exists * @param string $gid * @return bool */ abstract public function groupExists($gid); /** - * @brief get a list of all users in a group - * @returns array with user ids + * get a list of all users in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return array an array of user ids */ abstract public static function usersInGroup($gid, $search = '', $limit = -1, $offset = 0); - } diff --git a/lib/private/group/group.php b/lib/private/group/group.php index 7593bb68d1a..3e245ab6bbe 100644 --- a/lib/private/group/group.php +++ b/lib/private/group/group.php @@ -26,7 +26,7 @@ class Group { private $usersLoaded; /** - * @var \OC_Group_Backend[] | \OC_Group_Database[] $backend + * @var \OC_Group_Backend[]|\OC_Group_Database[] $backend */ private $backends; @@ -184,7 +184,7 @@ class Group { * returns the number of users matching the search string * * @param string $search - * @return int | bool + * @return int|bool */ public function count($search) { $users = false; @@ -244,7 +244,7 @@ class Group { } /** - * @brief returns all the Users from an array that really exists + * returns all the Users from an array that really exists * @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 */ diff --git a/lib/private/group/interface.php b/lib/private/group/interface.php index 4ef3663837f..ee5c2d635d6 100644 --- a/lib/private/group/interface.php +++ b/lib/private/group/interface.php @@ -23,7 +23,7 @@ interface OC_Group_Interface { /** - * @brief Check if backend implements actions + * Check if backend implements actions * @param int $actions bitwise-or'ed actions * @return boolean * @@ -33,7 +33,7 @@ interface OC_Group_Interface { public function implementsActions($actions); /** - * @brief is user in group? + * is user in group? * @param string $uid uid of the user * @param string $gid gid of the group * @return bool @@ -43,9 +43,9 @@ interface OC_Group_Interface { public function inGroup($uid, $gid); /** - * @brief Get all groups a user belongs to + * Get all groups a user belongs to * @param string $uid Name of the user - * @return array with group names + * @return array an array of group names * * This function fetches all groups a user belongs to. It does not check * if the user exists at all. @@ -53,11 +53,11 @@ interface OC_Group_Interface { public function getUserGroups($uid); /** - * @brief get a list of all groups + * get a list of all groups * @param string $search * @param int $limit * @param int $offset - * @return array with group names + * @return array an array of group names * * Returns a list with all groups */ @@ -71,12 +71,12 @@ interface OC_Group_Interface { public function groupExists($gid); /** - * @brief get a list of all users in a group + * get a list of all users in a group * @param string $gid * @param string $search * @param int $limit * @param int $offset - * @return array with user ids + * @return array an array of user ids */ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0); diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php index d31225e3c2e..dae6443e9d4 100644 --- a/lib/private/group/manager.php +++ b/lib/private/group/manager.php @@ -28,7 +28,7 @@ use OC\Hooks\PublicEmitter; */ class Manager extends PublicEmitter { /** - * @var \OC_Group_Backend[] | \OC_Group_Database[] $backends + * @var \OC_Group_Backend[]|\OC_Group_Database[] $backends */ private $backends = array(); @@ -40,19 +40,38 @@ class Manager extends PublicEmitter { /** * @var \OC\Group\Group[] */ - private $cachedGroups; + private $cachedGroups = array(); + + /** + * @var \OC\Group\Group[] + */ + private $cachedUserGroups = array(); /** * @param \OC\User\Manager $userManager */ public function __construct($userManager) { $this->userManager = $userManager; - $cache = & $this->cachedGroups; - $this->listen('\OC\Group', 'postDelete', function ($group) use (&$cache) { + $cachedGroups = & $this->cachedGroups; + $cachedUserGroups = & $this->cachedUserGroups; + $this->listen('\OC\Group', 'postDelete', function ($group) use (&$cachedGroups, &$cachedUserGroups) { + /** + * @var \OC\Group\Group $group + */ + unset($cachedGroups[$group->getGID()]); + $cachedUserGroups = array(); + }); + $this->listen('\OC\Group', 'postAddUser', function ($group) use (&$cachedUserGroups) { /** * @var \OC\Group\Group $group */ - unset($cache[$group->getGID()]); + $cachedUserGroups = array(); + }); + $this->listen('\OC\Group', 'postRemoveUser', function ($group) use (&$cachedUserGroups) { + /** + * @var \OC\Group\Group $group + */ + $cachedUserGroups = array(); }); } @@ -135,7 +154,7 @@ class Manager extends PublicEmitter { foreach ($this->backends as $backend) { $groupIds = $backend->getGroups($search, $limit, $offset); foreach ($groupIds as $groupId) { - $groups[$groupId] = $this->getGroupObject($groupId); + $groups[$groupId] = $this->get($groupId); } if (!is_null($limit) and $limit <= 0) { return array_values($groups); @@ -149,23 +168,28 @@ class Manager extends PublicEmitter { * @return \OC\Group\Group[] */ public function getUserGroups($user) { + $uid = $user->getUID(); + if (isset($this->cachedUserGroups[$uid])) { + return $this->cachedUserGroups[$uid]; + } $groups = array(); foreach ($this->backends as $backend) { - $groupIds = $backend->getUserGroups($user->getUID()); + $groupIds = $backend->getUserGroups($uid); foreach ($groupIds as $groupId) { - $groups[$groupId] = $this->getGroupObject($groupId); + $groups[$groupId] = $this->get($groupId); } } - return array_values($groups); + $this->cachedUserGroups[$uid] = array_values($groups); + return $this->cachedUserGroups[$uid]; } /** - * @brief get a list of all display names in a group + * get a list of all display names in a group * @param string $gid * @param string $search * @param int $limit * @param int $offset - * @return array with display names (value) and user ids (key) + * @return array an array of display names (value) and user ids (key) */ public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { $group = $this->get($gid); diff --git a/lib/private/helper.php b/lib/private/helper.php index 4058ec199a7..e9ca036a32c 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -31,12 +31,12 @@ class OC_Helper { private static $templateManager; /** - * @brief Creates an url using a defined route - * @param $route + * Creates an url using a defined route + * @param string $route * @param array $parameters * @return * @internal param array $args with param=>value, will be appended to the returned url - * @returns string the url + * @return string the url * * Returns a url to the given app and file. */ @@ -45,7 +45,7 @@ class OC_Helper { } /** - * @brief Creates an url + * 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 @@ -68,7 +68,7 @@ class OC_Helper { } /** - * @brief Creates an absolute url + * Creates an absolute url * @param string $app app * @param string $file file * @param array $args array with param=>value, will be appended to the returned url @@ -78,11 +78,13 @@ class OC_Helper { * Returns a absolute url to the given app and file. */ public static function linkToAbsolute($app, $file, $args = array()) { - return self::linkTo($app, $file, $args); + return OC::$server->getURLGenerator()->getAbsoluteURL( + self::linkTo($app, $file, $args) + ); } /** - * @brief Makes an $url absolute + * Makes an $url absolute * @param string $url the url * @return string the absolute url * @@ -93,7 +95,7 @@ class OC_Helper { } /** - * @brief Creates an url for remote use + * Creates an url for remote use * @param string $service id * @return string the url * @@ -104,7 +106,7 @@ class OC_Helper { } /** - * @brief Creates an absolute url for remote use + * Creates an absolute url for remote use * @param string $service id * @param bool $add_slash * @return string the url @@ -112,12 +114,14 @@ class OC_Helper { * Returns a absolute url to the given service. */ public static function linkToRemote($service, $add_slash = true) { - return self::makeURLAbsolute(self::linkToRemoteBase($service)) - . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : ''); + return OC::$server->getURLGenerator()->getAbsoluteURL( + self::linkToRemoteBase($service) + . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '') + ); } /** - * @brief Creates an absolute url for public use + * Creates an absolute url for public use * @param string $service id * @param bool $add_slash * @return string the url @@ -125,12 +129,16 @@ class OC_Helper { * Returns a absolute url to the given service. */ public static function linkToPublic($service, $add_slash = false) { - return self::linkToAbsolute('', 'public.php') . '?service=' . $service - . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : ''); + return OC::$server->getURLGenerator()->getAbsoluteURL( + self::linkTo( + '', 'public.php') . '?service=' . $service + . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '' + ) + ); } /** - * @brief Creates path to an image + * Creates path to an image * @param string $app app * @param string $image image name * @return string the url @@ -142,7 +150,7 @@ class OC_Helper { } /** - * @brief get path to icon of file type + * get path to icon of file type * @param string $mimetype mimetype * @return string the url * @@ -256,7 +264,7 @@ class OC_Helper { } /** - * @brief get path to preview of file + * get path to preview of file * @param string $path path * @return string the url * @@ -271,7 +279,7 @@ class OC_Helper { } /** - * @brief Make a human file size + * Make a human file size * @param int $bytes file size in bytes * @return string a human readable file size * @@ -306,7 +314,7 @@ class OC_Helper { } /** - * @brief Make a php file size + * Make a php file size * @param int $bytes file size in bytes * @return string a php parseable file size * @@ -332,7 +340,7 @@ class OC_Helper { } /** - * @brief Make a computer file size + * Make a computer file size * @param string $str file size in human readable format * @return int a file size in bytes * @@ -369,7 +377,7 @@ class OC_Helper { } /** - * @brief Recursive copying of folders + * Recursive copying of folders * @param string $src source folder * @param string $dest target folder * @@ -391,7 +399,7 @@ class OC_Helper { } /** - * @brief Recursive deletion of folders + * Recursive deletion of folders * @param string $dir path to the folder * @return bool */ @@ -399,7 +407,7 @@ class OC_Helper { if (is_dir($dir)) { $files = scandir($dir); foreach ($files as $file) { - if ($file != "." && $file != "..") { + if ($file !== '' && $file !== "." && $file !== "..") { self::rmdirr("$dir/$file"); } } @@ -477,7 +485,7 @@ class OC_Helper { } /** - * @brief Checks $_REQUEST contains a var for the $s key. If so, returns the html-escaped value of this var; otherwise returns the default value provided by $d. + * Checks $_REQUEST contains a var for the $s key. If so, returns the html-escaped value of this var; otherwise returns the default value provided by $d. * @param string $s name of the var to escape, if set. * @param string $d default value. * @return string the print-safe value. @@ -487,7 +495,7 @@ class OC_Helper { /** * detect if a given program is found in the search PATH * - * @param $name + * @param string $name * @param bool $path * @internal param string $program name * @internal param string $optional search path, defaults to $PATH @@ -662,8 +670,8 @@ class OC_Helper { /** * Adds a suffix to the name in case the file exists * - * @param $path - * @param $filename + * @param string $path + * @param string $filename * @return string */ public static function buildNotExistingFileName($path, $filename) { @@ -674,8 +682,8 @@ class OC_Helper { /** * Adds a suffix to the name in case the file exists * - * @param $path - * @param $filename + * @param string $path + * @param string $filename * @return string */ public static function buildNotExistingFileNameForView($path, $filename, \OC\Files\View $view) { @@ -718,21 +726,33 @@ class OC_Helper { } /** - * @brief Checks if $sub is a subdirectory of $parent + * Checks if $sub is a subdirectory of $parent * * @param string $sub * @param string $parent * @return bool */ - public static function issubdirectory($sub, $parent) { - if (strpos(realpath($sub), realpath($parent)) === 0) { + public static function isSubDirectory($sub, $parent) { + $realpathSub = realpath($sub); + $realpathParent = realpath($parent); + + // realpath() may return false in case the directory does not exist + // since we can not be sure how different PHP versions may behave here + // we do an additional check whether realpath returned false + if($realpathSub === false || $realpathParent === false) { + return false; + } + + // Check whether $sub is a subdirectory of $parent + if (strpos($realpathSub, $realpathParent) === 0) { return true; } + return false; } /** - * @brief Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is. + * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is. * * @param array $input The array to work on * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default) @@ -753,9 +773,9 @@ class OC_Helper { } /** - * @brief replaces a copy of string delimited by the start and (optionally) length parameters with the string given in replacement. + * replaces a copy of string delimited by the start and (optionally) length parameters with the string given in replacement. * - * @param $string + * @param string $string * @param string $replacement The replacement string. * @param int $start If start is positive, the replacing will begin at the start'th offset into string. If start is negative, the replacing will begin at the start'th character from the end of string. * @param int $length Length of the part to be replaced @@ -774,7 +794,7 @@ class OC_Helper { } /** - * @brief Replace all occurrences of the search string with the replacement string + * Replace all occurrences of the search string with the replacement string * * @param string $search The value being searched for, otherwise known as the needle. * @param string $replace The replacement @@ -796,7 +816,7 @@ class OC_Helper { } /** - * @brief performs a search in a nested array + * performs a search in a nested array * @param array $haystack the array to be searched * @param string $needle the search string * @param string $index optional, only search this key name @@ -838,7 +858,7 @@ class OC_Helper { } /** - * @brief calculates the maximum upload size respecting system settings, free space and user quota + * calculates the maximum upload size respecting system settings, free space and user quota * * @param string $dir the current folder where the user currently operates * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly @@ -853,7 +873,7 @@ class OC_Helper { /** * Calculate free space left within user quota - * + * * @param string $dir the current folder where the user currently operates * @return int number of bytes representing */ diff --git a/lib/private/hook.php b/lib/private/hook.php index b63b442c31b..30e22847c7f 100644 --- a/lib/private/hook.php +++ b/lib/private/hook.php @@ -8,7 +8,7 @@ class OC_Hook{ static private $registered = array(); /** - * @brief connects a function to a hook + * connects a function to a hook * @param string $signalclass class name of emitter * @param string $signalname name of signal * @param string $slotclass class name of slot @@ -42,10 +42,10 @@ class OC_Hook{ } /** - * @brief emits a signal + * emits a signal * @param string $signalclass class name of emitter * @param string $signalname name of signal - * @param array $params defautl: array() array with additional data + * @param mixed $params default: array() array with additional data * @return bool, true if slots exists or false if not * * Emits a signal. To get data from the slot use references! diff --git a/lib/private/image.php b/lib/private/image.php index 14aa64d12da..5331c399159 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -33,7 +33,7 @@ class OC_Image { private $fileInfo; /** - * @brief Get mime type for an image file. + * Get mime type for an image file. * @param string|null $filePath The path to a local image file. * @return string The mime type if the it could be determined, otherwise an empty string. */ @@ -48,7 +48,7 @@ class OC_Image { } /** - * @brief Constructor. + * Constructor. * @param resource|string $imageRef The path to a local file, a base64 encoded string or a resource created by * an imagecreate* function. * @return \OC_Image False on error @@ -70,7 +70,7 @@ class OC_Image { } /** - * @brief Determine whether the object contains an image resource. + * Determine whether the object contains an image resource. * @return bool */ public function valid() { // apparently you can't name a method 'empty'... @@ -78,7 +78,7 @@ class OC_Image { } /** - * @brief Returns the MIME type of the image or an empty string if no image is loaded. + * Returns the MIME type of the image or an empty string if no image is loaded. * @return string */ public function mimeType() { @@ -86,7 +86,7 @@ class OC_Image { } /** - * @brief Returns the width of the image or -1 if no image is loaded. + * Returns the width of the image or -1 if no image is loaded. * @return int */ public function width() { @@ -94,7 +94,7 @@ class OC_Image { } /** - * @brief Returns the height of the image or -1 if no image is loaded. + * Returns the height of the image or -1 if no image is loaded. * @return int */ public function height() { @@ -102,7 +102,7 @@ class OC_Image { } /** - * @brief Returns the width when the image orientation is top-left. + * Returns the width when the image orientation is top-left. * @return int */ public function widthTopLeft() { @@ -125,7 +125,7 @@ class OC_Image { } /** - * @brief Returns the height when the image orientation is top-left. + * Returns the height when the image orientation is top-left. * @return int */ public function heightTopLeft() { @@ -148,7 +148,7 @@ class OC_Image { } /** - * @brief Outputs the image. + * Outputs the image. * @param string $mimeType * @return bool */ @@ -161,7 +161,7 @@ class OC_Image { } /** - * @brief Saves the image. + * Saves the image. * @param string $filePath * @param string $mimeType * @return bool @@ -181,7 +181,7 @@ class OC_Image { } /** - * @brief Outputs/saves the image. + * Outputs/saves the image. * @param string $filePath * @param string $mimeType * @return bool @@ -259,7 +259,7 @@ class OC_Image { } /** - * @brief Prints the image when called as $image(). + * Prints the image when called as $image(). */ public function __invoke() { return $this->show(); @@ -307,7 +307,7 @@ class OC_Image { /** * (I'm open for suggestions on better method name ;) - * @brief Get the orientation based on EXIF data. + * Get the orientation based on EXIF data. * @return int The orientation or -1 if no EXIF data is available. */ public function getOrientation() { @@ -335,7 +335,7 @@ class OC_Image { /** * (I'm open for suggestions on better method name ;) - * @brief Fixes orientation based on EXIF data. + * Fixes orientation based on EXIF data. * @return bool. */ public function fixOrientation() { @@ -396,7 +396,7 @@ class OC_Image { } /** - * @brief Loads an image from a local file, a base64 encoded string or a resource created by an imagecreate* function. + * Loads an image from a local file, a base64 encoded string or a resource created by an imagecreate* function. * @param resource|string $imageRef The path to a local file, a base64 encoded string or a resource created by an imagecreate* function or a file resource (file handle ). * @return resource|false An image resource or false on error */ @@ -421,10 +421,10 @@ class OC_Image { } /** - * @brief Loads an image from an open file handle. + * Loads an image from an open file handle. * It is the responsibility of the caller to position the pointer at the correct place and to close the handle again. * @param resource $handle - * @return An image resource or false on error + * @return resource|false An image resource or false on error */ public function loadFromFileHandle($handle) { OC_Log::write('core', __METHOD__.'(): Trying', OC_Log::DEBUG); @@ -435,7 +435,7 @@ class OC_Image { } /** - * @brief Loads an image from a local file. + * Loads an image from a local file. * @param bool|string $imagePath The path to a local file. * @return bool|resource An image resource or false on error */ @@ -536,7 +536,7 @@ class OC_Image { } /** - * @brief Loads an image from a string of data. + * Loads an image from a string of data. * @param string $str A string of image data as read from a file. * @return bool|resource An image resource or false on error */ @@ -561,7 +561,7 @@ class OC_Image { } /** - * @brief Loads an image from a base64 encoded string. + * Loads an image from a base64 encoded string. * @param string $str A string base64 encoded string of image data. * @return bool|resource An image resource or false on error */ @@ -729,7 +729,7 @@ class OC_Image { } /** - * @brief Resizes the image preserving ratio. + * Resizes the image preserving ratio. * @param integer $maxSize The maximum size of either the width or height. * @return bool */ @@ -793,7 +793,7 @@ class OC_Image { } /** - * @brief Crops the image to the middle square. If the image is already square it just returns. + * Crops the image to the middle square. If the image is already square it just returns. * @param int $size maximum size for the result (optional) * @return bool for success or failure */ @@ -852,7 +852,7 @@ class OC_Image { } /** - * @brief Crops the image from point $x$y with dimension $wx$h. + * Crops the image from point $x$y with dimension $wx$h. * @param int $x Horizontal position * @param int $y Vertical position * @param int $w Width @@ -882,7 +882,7 @@ class OC_Image { } /** - * @brief Resizes the image to fit within a boundry while preserving ratio. + * Resizes the image to fit within a boundry while preserving ratio. * @param integer $maxWidth * @param integer $maxHeight * @return bool diff --git a/lib/private/installer.php b/lib/private/installer.php index e8ea162eb2f..6940a1dc78d 100644 --- a/lib/private/installer.php +++ b/lib/private/installer.php @@ -56,7 +56,7 @@ class OC_Installer{ * It is the task of oc_app_install to create the tables and do whatever is * needed to get the app working. * - * @brief Installs an app + * Installs an app * @param array $data with all information * @throws \Exception * @return integer @@ -303,10 +303,7 @@ class OC_Installer{ } // check if the app is compatible with this version of ownCloud - if( - !isset($info['require']) - or !OC_App::isAppVersionCompatible(OC_Util::getVersion(), $info['require']) - ) { + if(!OC_App::isAppCompatible(OC_Util::getVersion(), $info)) { OC_Helper::rmdirr($extractDir); throw new \Exception($l->t("App can't be installed because it is not compatible with this version of ownCloud")); } @@ -362,7 +359,7 @@ class OC_Installer{ } /** - * @brief Check if app is already downloaded + * Check if app is already downloaded * @param string $name name of the application to remove * @return boolean * @@ -378,9 +375,9 @@ class OC_Installer{ } /** - * @brief Removes an app + * Removes an app * @param string $name name of the application to remove - * @param $options array with options + * @param array $options options * @return boolean|null * * This function removes an app. $options is an associative array. The @@ -431,7 +428,7 @@ class OC_Installer{ } /** - * @brief Installs shipped apps + * Installs shipped apps * * This function installs all apps found in the 'apps' directory that should be enabled by default; */ diff --git a/lib/private/l10n.php b/lib/private/l10n.php index d6680d63445..3e44be88150 100644 --- a/lib/private/l10n.php +++ b/lib/private/l10n.php @@ -86,7 +86,7 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief The constructor + * The constructor * @param string $app app requesting l10n * @param string $lang default: null Language * @@ -134,10 +134,10 @@ class OC_L10N implements \OCP\IL10N { $i18ndir = self::findI18nDir($app); // Localization is in /l10n, Texts are in $i18ndir // (Just no need to define date/time format etc. twice) - if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/') - || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/lib/l10n/') - || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/settings') - || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/') + if((OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/') + || OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/lib/l10n/') + || OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/settings') + || OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/') ) && file_exists($i18ndir.$lang.'.php')) { // Include the file, save the data from $CONFIG @@ -162,7 +162,7 @@ class OC_L10N implements \OCP\IL10N { } } - if(file_exists(OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php') && OC_Helper::issubdirectory(OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php', OC::$SERVERROOT.'/core/l10n/')) { + if(file_exists(OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php') && OC_Helper::isSubDirectory(OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php', OC::$SERVERROOT.'/core/l10n/')) { // Include the file, save the data from $CONFIG include OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php'; if(isset($LOCALIZATIONS) && is_array($LOCALIZATIONS)) { @@ -176,14 +176,14 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief Creates a function that The constructor + * Creates a function that The constructor * * If language is not set, the constructor tries to find the right * language. * * Parts of the code is copied from Habari: * https://github.com/habari/system/blob/master/classes/locale.php - * @param $string string + * @param string $string * @return string */ protected function createPluralFormFunction($string){ @@ -235,7 +235,7 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief Translating + * Translating * @param string $text The text we need a translation for * @param array $parameters default:array() Parameters for sprintf * @return \OC_L10N_String Translation or the same text @@ -248,7 +248,7 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief Translating + * Translating * @param string $text_singular the string to translate for exactly one object * @param string $text_plural the string to translate for n objects * @param integer $count Number of objects @@ -277,8 +277,8 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief getTranslations - * @returns array Fetch all translations + * getTranslations + * @return array Fetch all translations * * Returns an associative array with all translations */ @@ -288,8 +288,8 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief getPluralFormString - * @returns string containing the gettext "Plural-Forms"-string + * getPluralFormString + * @return string containing the gettext "Plural-Forms"-string * * Returns a string like "nplurals=2; plural=(n != 1);" */ @@ -299,8 +299,8 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief getPluralFormFunction - * @returns string the plural form function + * getPluralFormFunction + * @return string the plural form function * * returned function accepts the argument $n */ @@ -313,8 +313,8 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief get localizations - * @returns array Fetch all localizations + * get localizations + * @return array Fetch all localizations * * Returns an associative array with all localizations */ @@ -324,10 +324,10 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief Localization + * Localization * @param string $type Type of localization * @param array|int|string $data parameters for this localization - * @returns String or false + * @return String or false * * Returns the localized data. * @@ -379,9 +379,9 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief Choose a language + * Choose a language * @param array $text Associative Array with possible strings - * @returns String + * @return String * * $text is an array 'de' => 'hallo welt', 'en' => 'hello world', ... * @@ -401,10 +401,27 @@ class OC_L10N implements \OCP\IL10N { self::$language = $lang; } + + /** + * find the best language + * @param array|string $app details below + * 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 + * folder. + * + * If nothing works it returns 'en' + */ + public function getLanguageCode($app=null) { + return self::findLanguage($app); + } + + /** - * @brief find the best language + * find the best language * @param array|string $app details below - * @returns string language + * @return 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 @@ -475,9 +492,9 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief find the l10n directory + * find the l10n directory * @param string $app App that needs to be translated - * @returns directory + * @return directory */ protected static function findI18nDir($app) { // find the i18n dir @@ -495,9 +512,9 @@ class OC_L10N implements \OCP\IL10N { } /** - * @brief find all available languages for an app + * find all available languages for an app * @param string $app App that needs to be translated - * @returns array an array of available languages + * @return array an array of available languages */ public static function findAvailableLanguages($app=null) { $available=array('en');//english is always available @@ -517,7 +534,7 @@ class OC_L10N implements \OCP\IL10N { /** * @param string $app * @param string $lang - * @returns bool + * @return bool */ public static function languageExists($app, $lang) { if ($lang == 'en') {//english is always available diff --git a/lib/private/l10n/factory.php b/lib/private/l10n/factory.php index 8c65f368171..d0c3799b9c2 100644 --- a/lib/private/l10n/factory.php +++ b/lib/private/l10n/factory.php @@ -20,8 +20,8 @@ class Factory { /** * get an L10N instance - * @param $app string - * @param $lang string|null + * @param string $app + * @param string|null $lang * @return \OC_L10N */ public function get($app) { diff --git a/lib/private/largefilehelper.php b/lib/private/largefilehelper.php new file mode 100644 index 00000000000..293e09fe2c9 --- /dev/null +++ b/lib/private/largefilehelper.php @@ -0,0 +1,192 @@ +<?php +/** + * Copyright (c) 2014 Andreas Fischer <bantu@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC; + +/** + * Helper class for large files on 32-bit platforms. + */ +class LargeFileHelper { + /** + * pow(2, 53) as a base-10 string. + * @var string + */ + const POW_2_53 = '9007199254740992'; + + /** + * pow(2, 53) - 1 as a base-10 string. + * @var string + */ + const POW_2_53_MINUS_1 = '9007199254740991'; + + /** + * @brief Checks whether our assumptions hold on the PHP platform we are on. + * + * @throws \RunTimeException if our assumptions do not hold on the current + * PHP platform. + */ + public function __construct() { + $pow_2_53 = floatval(self::POW_2_53_MINUS_1) + 1.0; + if ($this->formatUnsignedInteger($pow_2_53) !== self::POW_2_53) { + throw new \RunTimeException( + 'This class assumes floats to be double precision or "better".' + ); + } + } + + /** + * @brief Formats a signed integer or float as an unsigned integer base-10 + * string. Passed strings will be checked for being base-10. + * + * @param int|float|string $number Number containing unsigned integer data + * + * @throws \UnexpectedValueException if $number is not a float, not an int + * and not a base-10 string. + * + * @return string Unsigned integer base-10 string + */ + public function formatUnsignedInteger($number) { + if (is_float($number)) { + // Undo the effect of the php.ini setting 'precision'. + return number_format($number, 0, '', ''); + } else if (is_string($number) && ctype_digit($number)) { + return $number; + } else if (is_int($number)) { + // Interpret signed integer as unsigned integer. + return sprintf('%u', $number); + } else { + throw new \UnexpectedValueException( + 'Expected int, float or base-10 string' + ); + } + } + + /** + * @brief Tries to get the size of a file via various workarounds that + * even work for large files on 32-bit platforms. + * + * @param string $filename Path to the file. + * + * @return null|int|float Number of bytes as number (float or int) or + * null on failure. + */ + public function getFileSize($filename) { + $fileSize = $this->getFileSizeViaCurl($filename); + if (!is_null($fileSize)) { + return $fileSize; + } + $fileSize = $this->getFileSizeViaCOM($filename); + if (!is_null($fileSize)) { + return $fileSize; + } + $fileSize = $this->getFileSizeViaExec($filename); + if (!is_null($fileSize)) { + return $fileSize; + } + return $this->getFileSizeNative($filename); + } + + /** + * @brief Tries to get the size of a file via a CURL HEAD request. + * + * @param string $filename Path to the file. + * + * @return null|int|float Number of bytes as number (float or int) or + * null on failure. + */ + public function getFileSizeViaCurl($filename) { + if (function_exists('curl_init')) { + $ch = curl_init("file://$filename"); + curl_setopt($ch, CURLOPT_NOBODY, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HEADER, true); + $data = curl_exec($ch); + curl_close($ch); + if ($data !== false) { + $matches = array(); + preg_match('/Content-Length: (\d+)/', $data, $matches); + if (isset($matches[1])) { + return 0 + $matches[1]; + } + } + } + return null; + } + + /** + * @brief Tries to get the size of a file via the Windows DOM extension. + * + * @param string $filename Path to the file. + * + * @return null|int|float Number of bytes as number (float or int) or + * null on failure. + */ + public function getFileSizeViaCOM($filename) { + if (class_exists('COM')) { + $fsobj = new \COM("Scripting.FileSystemObject"); + $file = $fsobj->GetFile($filename); + return 0 + $file->Size; + } + return null; + } + + /** + * @brief Tries to get the size of a file via an exec() call. + * + * @param string $filename Path to the file. + * + * @return null|int|float Number of bytes as number (float or int) or + * null on failure. + */ + public function getFileSizeViaExec($filename) { + if (\OC_Helper::is_function_enabled('exec')) { + $os = strtolower(php_uname('s')); + $arg = escapeshellarg($filename); + $result = ''; + if (strpos($os, 'linux') !== false) { + $result = $this->exec("stat -c %s $arg"); + } else if (strpos($os, 'bsd') !== false) { + $result = $this->exec("stat -f %z $arg"); + } else if (strpos($os, 'win') !== false) { + $result = $this->exec("for %F in ($arg) do @echo %~zF"); + if (is_null($result)) { + // PowerShell + $result = $this->exec("(Get-Item $arg).length"); + } + } + return $result; + } + return null; + } + + /** + * @brief Gets the size of a file via a filesize() call and converts + * negative signed int to positive float. As the result of filesize() + * will wrap around after a file size of 2^32 bytes = 4 GiB, this + * should only be used as a last resort. + * + * @param string $filename Path to the file. + * + * @return int|float Number of bytes as number (float or int). + */ + public function getFileSizeNative($filename) { + $result = filesize($filename); + if ($result < 0) { + // For file sizes between 2 GiB and 4 GiB, filesize() will return a + // negative int, as the PHP data type int is signed. Interpret the + // returned int as an unsigned integer and put it into a float. + return (float) sprintf('%u', $result); + } + return $result; + } + + protected function exec($cmd) { + $result = trim(exec($cmd)); + return ctype_digit($result) ? 0 + $result : null; + } +} diff --git a/lib/private/legacy/appconfig.php b/lib/private/legacy/appconfig.php index cb5cef7e350..4634f2c695d 100644 --- a/lib/private/legacy/appconfig.php +++ b/lib/private/legacy/appconfig.php @@ -34,8 +34,8 @@ class OC_Appconfig { } /** - * @brief Get all apps using the config - * @return array with app ids + * Get all apps using the config + * @return array an array of app ids * * This function returns a list of all apps that have at least one * entry in the appconfig table. @@ -45,9 +45,9 @@ class OC_Appconfig { } /** - * @brief Get the available keys for an app + * Get the available keys for an app * @param string $app the app we are looking for - * @return array with key names + * @return array an array of key names * * This function gets all keys of an app. Please note that the values are * not returned. @@ -57,7 +57,7 @@ class OC_Appconfig { } /** - * @brief Gets the config value + * Gets the config value * @param string $app app * @param string $key key * @param string $default = null, default value if the key does not exist @@ -71,7 +71,7 @@ class OC_Appconfig { } /** - * @brief check if a key is set in the appconfig + * check if a key is set in the appconfig * @param string $app * @param string $key * @return bool @@ -81,7 +81,7 @@ class OC_Appconfig { } /** - * @brief sets a value in the appconfig + * sets a value in the appconfig * @param string $app app * @param string $key key * @param string $value value @@ -93,7 +93,7 @@ class OC_Appconfig { } /** - * @brief Deletes a key + * Deletes a key * @param string $app app * @param string $key key * @@ -104,7 +104,7 @@ class OC_Appconfig { } /** - * @brief Remove app from appconfig + * Remove app from appconfig * @param string $app app * * Removes all keys in appconfig belonging to the app. diff --git a/lib/private/legacy/cache.php b/lib/private/legacy/cache.php deleted file mode 100644 index f915eb516b1..00000000000 --- a/lib/private/legacy/cache.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php -/** - * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net) - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -class OC_Cache extends \OC\Cache { -}
\ No newline at end of file diff --git a/lib/private/legacy/cache/fileglobalgc.php b/lib/private/legacy/cache/fileglobalgc.php deleted file mode 100644 index 385f6406673..00000000000 --- a/lib/private/legacy/cache/fileglobalgc.php +++ /dev/null @@ -1,4 +0,0 @@ -<?php - -class OC_Cache_FileGlobalGC extends OC\Cache\FileGlobalGC{ -} diff --git a/lib/private/legacy/config.php b/lib/private/legacy/config.php index 6c2103179ab..899c19532f0 100644 --- a/lib/private/legacy/config.php +++ b/lib/private/legacy/config.php @@ -50,8 +50,8 @@ class OC_Config { } /** - * @brief Lists all available config keys - * @return array with key names + * Lists all available config keys + * @return array an array of key names * * This function returns all keys saved in config.php. Please note that it * does not return the values. @@ -61,7 +61,7 @@ class OC_Config { } /** - * @brief Gets a value from config.php + * Gets a value from config.php * @param string $key key * @param mixed $default = null default value * @return mixed the value or $default @@ -74,7 +74,7 @@ class OC_Config { } /** - * @brief Sets a value + * Sets a value * @param string $key key * @param mixed $value value * @@ -86,7 +86,7 @@ class OC_Config { } /** - * @brief Removes a key from the config + * Removes a key from the config * @param string $key key * * This function removes a key from the config.php. diff --git a/lib/private/legacy/filesystem.php b/lib/private/legacy/filesystem.php deleted file mode 100644 index 34f92b357ca..00000000000 --- a/lib/private/legacy/filesystem.php +++ /dev/null @@ -1,415 +0,0 @@ -<?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. - */ - -/** - * Class for abstraction of filesystem functions - * This class won't call any filesystem functions for itself but but will pass them to the correct OC_Filestorage object - * this class should also handle all the file permission related stuff - * - * Hooks provided: - * read(path) - * write(path, &run) - * post_write(path) - * create(path, &run) (when a file is created, both create and write will be emitted in that order) - * post_create(path) - * delete(path, &run) - * post_delete(path) - * rename(oldpath,newpath, &run) - * post_rename(oldpath,newpath) - * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emitted in that order) - * post_rename(oldpath,newpath) - * - * the &run parameter can be set to false to prevent the operation from occurring - */ - -/** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ -class OC_Filesystem { - /** - * get the mountpoint of the storage object for a path - * ( note: because a storage is not always mounted inside the fakeroot, the - * returned mountpoint is relative to the absolute root of the filesystem - * and doesn't take the chroot into account ) - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return string - */ - static public function getMountPoint($path) { - return \OC\Files\Filesystem::getMountPoint($path); - } - - /** - * resolve a path to a storage and internal path - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return array consisting of the storage and the internal path - */ - static public function resolvePath($path) { - return \OC\Files\Filesystem::resolvePath($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function init($user, $root) { - return \OC\Files\Filesystem::init($user, $root); - } - - /** - * get the default filesystem view - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @return \OC\Files\View - */ - static public function getView() { - return \OC\Files\Filesystem::getView(); - } - - /** - * tear down the filesystem, removing all storage providers - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function tearDown() { - \OC\Files\Filesystem::tearDown(); - } - - /** - * @brief get the relative path of the root data directory for the current user - * @return string - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * Returns path like /admin/files - */ - static public function getRoot() { - return \OC\Files\Filesystem::getRoot(); - } - - /** - * clear all mounts and storage backends - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - public static function clearMounts() { - \OC\Files\Filesystem::clearMounts(); - } - - /** - * mount an \OC\Files\Storage\Storage in our virtual filesystem - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param \OC\Files\Storage\Storage $class - * @param array $arguments - * @param string $mountpoint - */ - static public function mount($class, $arguments, $mountpoint) { - \OC\Files\Filesystem::mount($class, $arguments, $mountpoint); - } - - /** - * return the path to a local version of the file - * we need this because we can't know if a file is stored local or not from - * outside the filestorage and for some purposes a local file is needed - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return string - */ - static public function getLocalFile($path) { - return \OC\Files\Filesystem::getLocalFile($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return string - */ - static public function getLocalFolder($path) { - return \OC\Files\Filesystem::getLocalFolder($path); - } - - /** - * return path to file which reflects one visible in browser - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return string - */ - static public function getLocalPath($path) { - return \OC\Files\Filesystem::getLocalPath($path); - } - - /** - * check if the requested path is valid - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return bool - */ - static public function isValidPath($path) { - return \OC\Files\Filesystem::isValidPath($path); - } - - /** - * checks if a file is blacklisted for storage in the filesystem - * Listens to write and rename hooks - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param array $data from hook - */ - static public function isBlacklisted($data) { - \OC\Files\Filesystem::isBlacklisted($data); - } - - /** - * following functions are equivalent to their php builtin equivalents for arguments/return values. - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function mkdir($path) { - return \OC\Files\Filesystem::mkdir($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function rmdir($path) { - return \OC\Files\Filesystem::rmdir($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function opendir($path) { - return \OC\Files\Filesystem::opendir($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function readdir($path) { - return \OC\Files\Filesystem::readdir($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function is_dir($path) { - return \OC\Files\Filesystem::is_dir($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function is_file($path) { - return \OC\Files\Filesystem::is_file($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function stat($path) { - return \OC\Files\Filesystem::stat($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function filetype($path) { - return \OC\Files\Filesystem::filetype($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function filesize($path) { - return \OC\Files\Filesystem::filesize($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function readfile($path) { - return \OC\Files\Filesystem::readfile($path); - } - - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - static public function is_readable($path) { - return \OC\Files\Filesystem::isReadable($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function isCreatable($path) { - return \OC\Files\Filesystem::isCreatable($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function isReadable($path) { - return \OC\Files\Filesystem::isReadable($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function isUpdatable($path) { - return \OC\Files\Filesystem::isUpdatable($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function isDeletable($path) { - return \OC\Files\Filesystem::isDeletable($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function isSharable($path) { - return \OC\Files\Filesystem::isSharable($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function file_exists($path) { - return \OC\Files\Filesystem::file_exists($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function filemtime($path) { - return \OC\Files\Filesystem::filemtime($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function touch($path, $mtime = null) { - return \OC\Files\Filesystem::touch($path, $mtime); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function file_get_contents($path) { - return \OC\Files\Filesystem::file_get_contents($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function file_put_contents($path, $data) { - return \OC\Files\Filesystem::file_put_contents($path, $data); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function unlink($path) { - return \OC\Files\Filesystem::unlink($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function rename($path1, $path2) { - return \OC\Files\Filesystem::rename($path1, $path2); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function copy($path1, $path2) { - return \OC\Files\Filesystem::copy($path1, $path2); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function fopen($path, $mode) { - return \OC\Files\Filesystem::fopen($path, $mode); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function toTmpFile($path) { - return \OC\Files\Filesystem::toTmpFile($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function fromTmpFile($tmpFile, $path) { - return \OC\Files\Filesystem::fromTmpFile($tmpFile, $path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function getMimeType($path) { - return \OC\Files\Filesystem::getMimeType($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function hash($type, $path, $raw = false) { - return \OC\Files\Filesystem::hash($type, $path, $raw); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function free_space($path = '/') { - return \OC\Files\Filesystem::free_space($path); - } - - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function search($query) { - return \OC\Files\Filesystem::search($query); - } - - /** - * check if a file or folder has been updated since $time - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @param int $time - * @return bool - */ - static public function hasUpdated($path, $time) { - return \OC\Files\Filesystem::hasUpdated($path, $time); - } - - /** - * normalize a path - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @param bool $stripTrailingSlash - * @return string - */ - public static function normalizePath($path, $stripTrailingSlash = true) { - return \OC\Files\Filesystem::normalizePath($path, $stripTrailingSlash); - } -} diff --git a/lib/private/legacy/filesystemview.php b/lib/private/legacy/filesystemview.php deleted file mode 100644 index d6bca62e06a..00000000000 --- a/lib/private/legacy/filesystemview.php +++ /dev/null @@ -1,9 +0,0 @@ -<?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. */ - -class OC_FilesystemView extends \OC\Files\View {} diff --git a/lib/private/legacy/preferences.php b/lib/private/legacy/preferences.php index fcde12796ca..71d0b749f43 100644 --- a/lib/private/legacy/preferences.php +++ b/lib/private/legacy/preferences.php @@ -28,8 +28,8 @@ OC_Preferences::$object = new \OC\Preferences(OC_DB::getConnection()); class OC_Preferences{ public static $object; /** - * @brief Get all users using the preferences - * @return array with user ids + * Get all users using the preferences + * @return array an array of user ids * * This function returns a list of all users that have at least one entry * in the preferences table. @@ -39,7 +39,7 @@ class OC_Preferences{ } /** - * @brief Get all apps of a user + * Get all apps of a user * @param string $user user * @return integer[] with app ids * @@ -51,10 +51,10 @@ class OC_Preferences{ } /** - * @brief Get the available keys for an app + * Get the available keys for an app * @param string $user user * @param string $app the app we are looking for - * @return array with key names + * @return array an array of key names * * This function gets all keys of an app of an user. Please note that the * values are not returned. @@ -64,7 +64,7 @@ class OC_Preferences{ } /** - * @brief Gets the preference + * Gets the preference * @param string $user user * @param string $app app * @param string $key key @@ -79,7 +79,7 @@ class OC_Preferences{ } /** - * @brief sets a value in the preferences + * sets a value in the preferences * @param string $user user * @param string $app app * @param string $key key @@ -95,7 +95,7 @@ class OC_Preferences{ } /** - * @brief Deletes a key + * Deletes a key * @param string $user user * @param string $app app * @param string $key key @@ -108,7 +108,7 @@ class OC_Preferences{ } /** - * @brief Remove app of user from preferences + * Remove app of user from preferences * @param string $user user * @param string $app app * @return bool @@ -121,7 +121,7 @@ class OC_Preferences{ } /** - * @brief Remove user from preferences + * Remove user from preferences * @param string $user user * @return bool * @@ -133,7 +133,7 @@ class OC_Preferences{ } /** - * @brief Remove app from all users + * Remove app from all users * @param string $app app * @return bool * diff --git a/lib/private/log.php b/lib/private/log.php index e0b9fe3c696..98465ec40ea 100644 --- a/lib/private/log.php +++ b/lib/private/log.php @@ -8,6 +8,8 @@ namespace OC; +use \OCP\ILogger; + /** * logging utilities * @@ -18,8 +20,24 @@ namespace OC; * MonoLog is an example implementing this interface. */ -class Log { - private $logClass; +class Log implements ILogger { + + private $logger; + + /** + * @param string $logger The logger that should be used + */ + public function __construct($logger=null) { + // FIXME: Add this for backwards compatibility, should be fixed at some point probably + if($logger === null) { + $this->logger = 'OC_Log_'.ucfirst(\OC_Config::getValue('log_type', 'owncloud')); + call_user_func(array($this->logger, 'init')); + } else { + $this->logger = $logger; + } + + } + /** * System is unusable. @@ -112,10 +130,6 @@ class Log { $this->log(\OC_Log::DEBUG, $message, $context); } - public function __construct() { - $this->logClass = 'OC_Log_'.ucfirst(\OC_Config::getValue('log_type', 'owncloud')); - call_user_func(array($this->logClass, 'init')); - } /** * Logs with an arbitrary level. @@ -130,7 +144,16 @@ class Log { } else { $app = 'no app in context'; } - $logClass=$this->logClass; - $logClass::write($app, $message, $level); + // interpolate $message as defined in PSR-3 + $replace = array(); + foreach ($context as $key => $val) { + $replace['{' . $key . '}'] = $val; + } + + // interpolate replacement values into the message and return + $message = strtr($message, $replace); + + $logger = $this->logger; + $logger::write($app, $message, $level); } } diff --git a/lib/private/log/errorhandler.php b/lib/private/log/errorhandler.php index 1dde6b507fc..4345b3f6b70 100644 --- a/lib/private/log/errorhandler.php +++ b/lib/private/log/errorhandler.php @@ -15,7 +15,7 @@ class ErrorHandler { private static $logger; /** - * @brief remove password in URLs + * remove password in URLs * @param string $msg * @return string */ diff --git a/lib/private/mail.php b/lib/private/mail.php index f9083cc4e64..81bcb3d8deb 100644 --- a/lib/private/mail.php +++ b/lib/private/mail.php @@ -12,8 +12,6 @@ * A class to handle mail sending. */ -require_once 'class.phpmailer.php'; - class OC_Mail { /** diff --git a/lib/private/memcache/memcached.php b/lib/private/memcache/memcached.php index 075828eebad..cd8e2e8d0b6 100644 --- a/lib/private/memcache/memcached.php +++ b/lib/private/memcache/memcached.php @@ -57,7 +57,7 @@ class Memcached extends Cache { public function hasKey($key) { self::$cache->get($this->getNamespace() . $key); - return self::$cache->getResultCode() !== \Memcached::RES_NOTFOUND; + return self::$cache->getResultCode() === \Memcached::RES_SUCCESS; } public function remove($key) { diff --git a/lib/private/migrate.php b/lib/private/migrate.php index 5bcc11b061b..8d88181ca19 100644 --- a/lib/private/migrate.php +++ b/lib/private/migrate.php @@ -53,7 +53,7 @@ class OC_Migrate{ } /** - * @brief finds and loads the providers + * finds and loads the providers */ static private function findProviders() { // Find the providers @@ -68,7 +68,7 @@ class OC_Migrate{ } /** - * @brief exports a user, or owncloud instance + * exports a user, or owncloud instance * @param string $uid user id of user to export if export type is user, defaults to current * @param string $type type of export, defualts to user * @param string $path path to zip output folder @@ -192,7 +192,7 @@ class OC_Migrate{ } /** - * @brief imports a user, or owncloud instance + * imports a user, or owncloud instance * @param string $path path to zip * @param string $type type of import (user or instance) * @param string|null|int $uid userid of new user @@ -307,7 +307,7 @@ class OC_Migrate{ } /** - * @brief recursively deletes a directory + * recursively deletes a directory * @param string $dir path of dir to delete * @param bool $deleteRootToo delete the root directory * @return bool @@ -332,8 +332,8 @@ class OC_Migrate{ } /** - * @brief tries to extract the import zip - * @param $path string path to the zip + * tries to extract the import zip + * @param string $path path to the zip * @return string path to extract location (with a trailing slash) or false on failure */ static private function extractZip( $path ) { @@ -356,7 +356,7 @@ class OC_Migrate{ } /** - * @brief creates a migration.db in the users data dir with their app data in + * creates a migration.db in the users data dir with their app data in * @return bool whether operation was successfull */ private static function exportAppData( ) { @@ -406,7 +406,7 @@ class OC_Migrate{ /** - * @brief generates json containing export info, and merges any data supplied + * generates json containing export info, and merges any data supplied * @param array $array of data to include in the returned json * @return string */ @@ -430,7 +430,7 @@ class OC_Migrate{ } /** - * @brief connects to migration.db, or creates if not found + * connects to migration.db, or creates if not found * @param string $path to migration.db, defaults to user data dir * @return bool whether the operation was successful */ @@ -460,7 +460,7 @@ class OC_Migrate{ } /** - * @brief creates the tables in migration.db from an apps database.xml + * creates the tables in migration.db from an apps database.xml * @param string $appid id of the app * @return bool whether the operation was successful */ @@ -498,7 +498,7 @@ class OC_Migrate{ } /** - * @brief tries to create the zip + * tries to create the zip * @return bool */ static private function createZip() { @@ -519,7 +519,7 @@ class OC_Migrate{ } /** - * @brief returns an array of apps that support migration + * returns an array of apps that support migration * @return array */ static public function getApps() { @@ -534,11 +534,11 @@ class OC_Migrate{ } /** - * @brief imports a new user + * imports a new user * @param string $db string path to migration.db - * @param $info object of migration info + * @param object $info object of migration info * @param string|null|int $uid uid to use - * @return array of apps with import statuses, or false on failure. + * @return array an array of apps with import statuses, or false on failure. */ public static function importAppData( $db, $info, $uid=null ) { // Check if the db exists diff --git a/lib/private/migration/content.php b/lib/private/migration/content.php index b0e7a4e9528..cb5d9ad1472 100644 --- a/lib/private/migration/content.php +++ b/lib/private/migration/content.php @@ -33,9 +33,9 @@ class OC_Migration_Content{ private $tmpfiles=array(); /** - * @brief sets up the + * sets up the * @param ZipArchive $zip ZipArchive object - * @param $db a database object (required for exporttype user) + * @param object $db a database object (required for exporttype user) * @return bool|null */ public function __construct( $zip, $db=null ) { @@ -45,11 +45,9 @@ class OC_Migration_Content{ } - // @brief prepares the db - // @param $query the sql query to prepare - /** - * @param string $query + * prepares the db + * @param string $query the sql query to prepare */ public function prepare( $query ) { @@ -73,7 +71,7 @@ class OC_Migration_Content{ } /** - * @brief processes the db query + * processes the db query * @param string $query the query to process * @return string of processed query */ @@ -87,8 +85,8 @@ class OC_Migration_Content{ } /** - * @brief copys rows to migration.db from the main database - * @param $options array of options. + * copys rows to migration.db from the main database + * @param array $options array of options. * @return bool */ public function copyRows( $options ) { @@ -129,9 +127,9 @@ class OC_Migration_Content{ } /** - * @brief saves a sql data set into migration.db + * saves a sql data set into migration.db * @param OC_DB_StatementWrapper $data a sql data set returned from self::prepare()->query() - * @param $options array of copyRows options + * @param array $options array of copyRows options * @return void */ private function insertData( $data, $options ) { @@ -168,10 +166,10 @@ class OC_Migration_Content{ } /** - * @brief adds a directory to the zip object + * adds a directory to the zip object * @param boolean|string $dir string path of the directory to add - * @param $recursive bool - * @param $internaldir string path of folder to add dir to in zip + * @param bool $recursive + * @param string $internaldir path of folder to add dir to in zip * @return bool */ public function addDir( $dir, $recursive=true, $internaldir='' ) { @@ -203,7 +201,7 @@ class OC_Migration_Content{ } /** - * @brief adds a file to the zip from a given string + * adds a file to the zip from a given string * @param string $data string of data to add * @param string $path the relative path inside of the zip to save the file to * @return bool @@ -222,7 +220,7 @@ class OC_Migration_Content{ } /** - * @brief closes the zip, removes temp files + * closes the zip, removes temp files * @return bool */ public function finish() { @@ -237,7 +235,7 @@ class OC_Migration_Content{ } /** - * @brief cleans up after the zip + * cleans up after the zip */ private function cleanup() { // Delete tmp files diff --git a/lib/private/migration/provider.php b/lib/private/migration/provider.php index 2829a97a776..a7c611dcdd4 100644 --- a/lib/private/migration/provider.php +++ b/lib/private/migration/provider.php @@ -17,19 +17,19 @@ abstract class OC_Migration_Provider{ } /** - * @brief exports data for apps + * exports data for apps * @return array appdata to be exported */ abstract function export( ); /** - * @brief imports data for the app + * imports data for the app * @return void */ abstract function import( ); /** - * @brief sets the OC_Migration_Content object to $this->content + * sets the OC_Migration_Content object to $this->content * @param OC_Migration_Content $content a OC_Migration_Content object */ public function setData( $uid, $content, $info=null ) { @@ -43,7 +43,7 @@ abstract class OC_Migration_Provider{ } /** - * @brief returns the appid of the provider + * returns the appid of the provider * @return string */ public function getID() { diff --git a/lib/private/navigationmanager.php b/lib/private/navigationmanager.php index 1f657b9ad80..8ad2f4c8f63 100644 --- a/lib/private/navigationmanager.php +++ b/lib/private/navigationmanager.php @@ -29,15 +29,15 @@ class NavigationManager implements \OCP\INavigationManager { } /** - * @brief returns all the added Menu entries - * @return array of the added entries + * returns all the added Menu entries + * @return array an array of the added entries */ public function getAll() { return $this->entries; } /** - * @brief removes all the entries + * removes all the entries */ public function clear() { $this->entries = array(); @@ -52,7 +52,7 @@ class NavigationManager implements \OCP\INavigationManager { } /** - * @brief gets the active Menu entry + * gets the active Menu entry * @return string id or empty string * * This function returns the id of the active navigation entry (set by diff --git a/lib/private/ocs.php b/lib/private/ocs.php index 211e8222145..aeb3d259b30 100644 --- a/lib/private/ocs.php +++ b/lib/private/ocs.php @@ -213,8 +213,8 @@ class OC_OCS { } /** - * @param $writer - * @param $data + * @param resource $writer + * @param array $data * @param string $node */ public static function toXml($writer, $data, $node) { diff --git a/lib/private/ocs/cloud.php b/lib/private/ocs/cloud.php index c8bb9425f1a..3ced0af8ee1 100644 --- a/lib/private/ocs/cloud.php +++ b/lib/private/ocs/cloud.php @@ -57,8 +57,8 @@ class OC_OCS_Cloud { * </quota> * </data> * - * @param $parameters object should contain parameter 'userid' which identifies - * the user from whom the information will be returned + * @param array $parameters should contain parameter 'userid' which identifies + * the user from whom the information will be returned */ public static function getUser($parameters) { $return = array(); diff --git a/lib/private/ocs/result.php b/lib/private/ocs/result.php index 0e3b85d5905..567fe7f87fe 100644 --- a/lib/private/ocs/result.php +++ b/lib/private/ocs/result.php @@ -26,7 +26,7 @@ class OC_OCS_Result{ /** * create the OCS_Result object - * @param $data mixed the data to return + * @param mixed $data the data to return */ public function __construct($data=null, $code=100, $message=null) { if ($data === null) { @@ -42,7 +42,7 @@ class OC_OCS_Result{ /** * optionally set the total number of items available - * @param $items int + * @param int $items */ public function setTotalItems(int $items) { $this->items = $items; @@ -50,7 +50,7 @@ class OC_OCS_Result{ /** * optionally set the the number of items per page - * @param $items int + * @param int $items */ public function setItemsPerPage(int $items) { $this->perPage = $items; diff --git a/lib/private/ocsclient.php b/lib/private/ocsclient.php index b0480caf028..39d7e9ccccd 100644 --- a/lib/private/ocsclient.php +++ b/lib/private/ocsclient.php @@ -29,8 +29,8 @@ class OC_OCSClient{ /** - * @brief Get the url of the OCS AppStore server. - * @returns string of the AppStore server + * Get the url of the OCS AppStore server. + * @return string of the AppStore server * * This function returns the url of the OCS AppStore server. It´s possible * to set it in the config file or it will fallback to the default @@ -47,8 +47,8 @@ class OC_OCSClient{ /** - * @brief Get the content of an OCS url call. - * @returns string of the response + * Get the content of an OCS url call. + * @return string of the response * This function calls an OCS server and returns the response. It also sets a sane timeout * @param string $url */ @@ -58,8 +58,8 @@ class OC_OCSClient{ } /** - * @brief Get all the categories from the OCS server - * @returns array with category ids + * Get all the categories from the OCS server + * @return array an array of category ids * @note returns NULL if config value appstoreenabled is set to false * This function returns a list of all the application categories on the OCS server */ @@ -91,11 +91,11 @@ class OC_OCSClient{ } /** - * @brief Get all the applications from the OCS server - * @returns array with application data + * Get all the applications from the OCS server + * @return array an array of application data * * This function returns a list of all the applications on the OCS server - * @param $categories + * @param array|string $categories * @param int $page * @param string $filter */ @@ -148,9 +148,9 @@ class OC_OCSClient{ /** - * @brief Get an the applications from the OCS server + * Get an the applications from the OCS server * @param string $id - * @returns array with application data + * @return array an array of application data * * This function returns an applications from the OCS server */ @@ -191,8 +191,8 @@ class OC_OCSClient{ } /** - * @brief Get the download url for an application from the OCS server - * @returns array with application data + * Get the download url for an application from the OCS server + * @return array an array of application data * * This function returns an download url for an applications from the OCS server * @param string $id diff --git a/lib/private/preferences.php b/lib/private/preferences.php index d45e6e77089..a4bfc650d08 100644 --- a/lib/private/preferences.php +++ b/lib/private/preferences.php @@ -68,8 +68,8 @@ class Preferences { } /** - * @brief Get all users using the preferences - * @return array with user ids + * Get all users using the preferences + * @return array an array of user ids * * This function returns a list of all users that have at least one entry * in the preferences table. @@ -109,7 +109,7 @@ class Preferences { } /** - * @brief Get all apps of an user + * Get all apps of an user * @param string $user user * @return integer[] with app ids * @@ -122,10 +122,10 @@ class Preferences { } /** - * @brief Get the available keys for an app + * Get the available keys for an app * @param string $user user * @param string $app the app we are looking for - * @return array with key names + * @return array an array of key names * * This function gets all keys of an app of an user. Please note that the * values are not returned. @@ -140,7 +140,7 @@ class Preferences { } /** - * @brief Gets the preference + * Gets the preference * @param string $user user * @param string $app app * @param string $key key @@ -160,7 +160,7 @@ class Preferences { } /** - * @brief sets a value in the preferences + * sets a value in the preferences * @param string $user user * @param string $app app * @param string $key key @@ -206,7 +206,44 @@ class Preferences { } /** - * @brief Deletes a key + * Gets the preference for an array of users + * @param string $app + * @param string $key + * @param array $users + * @return array Mapped values: userid => value + */ + public function getValueForUsers($app, $key, $users) { + if (empty($users) || !is_array($users)) { + return array(); + } + + $chunked_users = array_chunk($users, 50, true); + $placeholders_50 = implode(',', array_fill(0, 50, '?')); + + $userValues = array(); + foreach ($chunked_users as $chunk) { + $queryParams = $chunk; + array_unshift($queryParams, $key); + array_unshift($queryParams, $app); + + $placeholders = (sizeof($chunk) == 50) ? $placeholders_50 : implode(',', array_fill(0, sizeof($chunk), '?')); + + $query = 'SELECT `userid`, `configvalue` ' + . ' FROM `*PREFIX*preferences` ' + . ' WHERE `appid` = ? AND `configkey` = ?' + . ' AND `userid` IN (' . $placeholders . ')'; + $result = $this->conn->executeQuery($query, $queryParams); + + while ($row = $result->fetch()) { + $userValues[$row['userid']] = $row['configvalue']; + } + } + + return $userValues; + } + + /** + * Deletes a key * @param string $user user * @param string $app app * @param string $key key @@ -227,7 +264,7 @@ class Preferences { } /** - * @brief Remove app of user from preferences + * Remove app of user from preferences * @param string $user user * @param string $app app * @@ -246,7 +283,7 @@ class Preferences { } /** - * @brief Remove user from preferences + * Remove user from preferences * @param string $user user * * Removes all keys in preferences belonging to the user. @@ -261,7 +298,7 @@ class Preferences { } /** - * @brief Remove app from all users + * Remove app from all users * @param string $app app * * Removes all keys in preferences belonging to the app. diff --git a/lib/private/preview.php b/lib/private/preview.php index 2964b83c508..8089379bde5 100755 --- a/lib/private/preview.php +++ b/lib/private/preview.php @@ -66,7 +66,7 @@ class Preview { protected $info; /** - * @brief check if thumbnail or bigger version of thumbnail of file is cached + * check if thumbnail or bigger version of thumbnail of file is cached * @param string $user userid - if no user is given, OC_User::getUser will be used * @param string $root path of root * @param string $file The path to the file where you want a thumbnail from @@ -111,7 +111,7 @@ class Preview { } /** - * @brief returns the path of the file you want a thumbnail from + * returns the path of the file you want a thumbnail from * @return string */ public function getFile() { @@ -119,7 +119,7 @@ class Preview { } /** - * @brief returns the max width of the preview + * returns the max width of the preview * @return integer */ public function getMaxX() { @@ -127,7 +127,7 @@ class Preview { } /** - * @brief returns the max height of the preview + * returns the max height of the preview * @return integer */ public function getMaxY() { @@ -135,7 +135,7 @@ class Preview { } /** - * @brief returns whether or not scalingup is enabled + * returns whether or not scalingup is enabled * @return bool */ public function getScalingUp() { @@ -143,7 +143,7 @@ class Preview { } /** - * @brief returns the name of the thumbnailfolder + * returns the name of the thumbnailfolder * @return string */ public function getThumbnailsFolder() { @@ -151,7 +151,7 @@ class Preview { } /** - * @brief returns the max scale factor + * returns the max scale factor * @return string */ public function getMaxScaleFactor() { @@ -159,7 +159,7 @@ class Preview { } /** - * @brief returns the max width set in ownCloud's config + * returns the max width set in ownCloud's config * @return string */ public function getConfigMaxX() { @@ -167,7 +167,7 @@ class Preview { } /** - * @brief returns the max height set in ownCloud's config + * returns the max height set in ownCloud's config * @return string */ public function getConfigMaxY() { @@ -189,9 +189,9 @@ class Preview { } /** - * @brief set the path of the file you want a thumbnail from + * set the path of the file you want a thumbnail from * @param string $file - * @return $this + * @return \OC\Preview $this */ public function setFile($file) { $this->file = $file; @@ -206,7 +206,7 @@ class Preview { } /** - * @brief set mime type explicitly + * set mime type explicitly * @param string $mimeType */ public function setMimetype($mimeType) { @@ -214,10 +214,10 @@ class Preview { } /** - * @brief set the the max width of the preview + * set the the max width of the preview * @param int $maxX * @throws \Exception - * @return $this + * @return \OC\Preview $this */ public function setMaxX($maxX = 1) { if ($maxX <= 0) { @@ -235,10 +235,10 @@ class Preview { } /** - * @brief set the the max height of the preview + * set the the max height of the preview * @param int $maxY * @throws \Exception - * @return $this + * @return \OC\Preview $this */ public function setMaxY($maxY = 1) { if ($maxY <= 0) { @@ -256,9 +256,9 @@ class Preview { } /** - * @brief set whether or not scalingup is enabled + * set whether or not scalingup is enabled * @param bool $scalingUp - * @return $this + * @return \OC\Preview $this */ public function setScalingup($scalingUp) { if ($this->getMaxScaleFactor() === 1) { @@ -274,7 +274,7 @@ class Preview { } /** - * @brief check if all parameters are valid + * check if all parameters are valid * @return bool */ public function isFileValid() { @@ -293,7 +293,7 @@ class Preview { } /** - * @brief deletes previews of a file with specific x and y + * deletes previews of a file with specific x and y * @return bool */ public function deletePreview() { @@ -310,7 +310,7 @@ class Preview { } /** - * @brief deletes all previews of a file + * deletes all previews of a file * @return bool */ public function deleteAllPreviews() { @@ -328,7 +328,7 @@ class Preview { } /** - * @brief check if thumbnail or bigger version of thumbnail of file is cached + * check if thumbnail or bigger version of thumbnail of file is cached * @param int $fileId fileId of the original image * @return string|false path to thumbnail if it exists or false */ @@ -348,7 +348,7 @@ class Preview { } /** - * @brief check if a bigger version of thumbnail of file is cached + * check if a bigger version of thumbnail of file is cached * @param int $fileId fileId of the original image * @return string|false path to bigger thumbnail if it exists or false */ @@ -380,9 +380,9 @@ class Preview { } /** - * @brief get possible bigger thumbnails of the given image + * get possible bigger thumbnails of the given image * @param int $fileId fileId of the original image - * @return array of paths to bigger thumbnails + * @return array an array of paths to bigger thumbnails */ private function getPossibleThumbnails($fileId) { @@ -433,12 +433,12 @@ class Preview { * @return bool */ private function unscalable($x, $y) { - + $maxX = $this->getMaxX(); $maxY = $this->getMaxY(); $scalingUp = $this->getScalingUp(); $maxScaleFactor = $this->getMaxScaleFactor(); - + if ($x < $maxX || $y < $maxY) { if ($scalingUp) { $scalefactor = $maxX / $x; @@ -453,7 +453,7 @@ class Preview { } /** - * @brief return a preview of a file + * return a preview of a file * @return \OC_Image */ public function getPreview() { @@ -529,7 +529,7 @@ class Preview { } /** - * @brief show preview + * show preview * @return void */ public function showPreview($mimeType = null) { @@ -541,7 +541,7 @@ class Preview { } /** - * @brief resize, crop and fix orientation + * resize, crop and fix orientation * @return void */ private function resizeAndCrop() { @@ -652,7 +652,7 @@ class Preview { } /** - * @brief register a new preview provider to be used + * register a new preview provider to be used * @param array $options * @return void */ @@ -661,7 +661,7 @@ class Preview { } /** - * @brief create instances of all the registered preview providers + * create instances of all the registered preview providers * @return void */ private static function initProviders() { @@ -750,7 +750,7 @@ class Preview { } /** - * @param $fileId + * @param int $fileId * @return string */ private function buildCachePath($fileId) { diff --git a/lib/private/preview/image.php b/lib/private/preview/image.php index 59aaa27ef34..cec5d7c0170 100644 --- a/lib/private/preview/image.php +++ b/lib/private/preview/image.php @@ -22,12 +22,13 @@ class Image extends Provider { } $image = new \OC_Image(); - //check if file is encrypted + if($fileInfo['encrypted'] === true) { - $image->loadFromData(stream_get_contents($fileview->fopen($path, 'r'))); - }else{ - $image->loadFromFile($fileview->getLocalFile($path)); + $fileName = $fileview->toTmpFile($path); + } else { + $fileName = $fileview->getLocalFile($path); } + $image->loadFromFile($fileName); return $image->valid() ? $image : false; } diff --git a/lib/private/previewmanager.php b/lib/private/previewmanager.php index ac9a866a75b..23dbee13c7d 100755 --- a/lib/private/previewmanager.php +++ b/lib/private/previewmanager.php @@ -13,7 +13,7 @@ use OCP\IPreview; class PreviewManager implements IPreview { /** - * @brief return a preview of a file + * return a preview of a file * @param string $file The path to the file where you want a thumbnail from * @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 @@ -27,7 +27,7 @@ class PreviewManager implements IPreview { } /** - * @brief returns true if the passed mime type is supported + * returns true if the passed mime type is supported * @param string $mimeType * @return boolean */ diff --git a/lib/private/request.php b/lib/private/request.php index 90f7488eea5..09928021a7f 100755 --- a/lib/private/request.php +++ b/lib/private/request.php @@ -16,9 +16,9 @@ class OC_Request { const REGEX_LOCALHOST = '/^(127\.0\.0\.1|localhost)(:[0-9]+|)$/'; /** - * @brief Check overwrite condition + * Check overwrite condition * @param string $type - * @returns bool + * @return bool */ private static function isOverwriteCondition($type = '') { $regex = '/' . OC_Config::getValue('overwritecondaddr', '') . '/'; @@ -27,7 +27,7 @@ class OC_Request { } /** - * @brief Checks whether a domain is considered as trusted from the list + * Checks whether a domain is considered as trusted from the list * of trusted domains. If no trusted domains have been configured, returns * true. * This is used to prevent Host Header Poisoning. @@ -47,9 +47,9 @@ class OC_Request { } /** - * @brief Returns the unverified server host from the headers without checking + * Returns the unverified server host from the headers without checking * whether it is a trusted domain - * @returns string the server host + * @return string the server host * * Returns the server host, even if the website uses one or more * reverse proxies @@ -87,9 +87,9 @@ class OC_Request { } /** - * @brief Returns the server host from the headers, or the first configured + * Returns the server host from the headers, or the first configured * trusted domain if the host isn't in the trusted list - * @returns string the server host + * @return string the server host * * Returns the server host, even if the website uses one or more * reverse proxies @@ -120,8 +120,8 @@ class OC_Request { } /** - * @brief Returns the server protocol - * @returns string the server protocol + * Returns the server protocol + * @return string the server protocol * * Returns the server protocol. It respects reverse proxy servers and load balancers */ @@ -142,8 +142,8 @@ class OC_Request { } /** - * @brief Returns the request uri - * @returns string the request uri + * Returns the request uri + * @return string the request uri * * Returns the request uri, even if the website uses one or more * reverse proxies @@ -158,7 +158,7 @@ class OC_Request { } /** - * @brief Returns the script name + * Returns the script name * @return string the script name * * Returns the script name, even if the website uses one or more @@ -176,7 +176,7 @@ class OC_Request { } /** - * @brief get Path info from request + * get Path info from request * @return string Path info or false when not found */ public static function getPathInfo() { @@ -200,7 +200,7 @@ class OC_Request { } /** - * @brief get Path info from request, not urldecoded + * get Path info from request, not urldecoded * @throws Exception * @return string Path info or false when not found */ @@ -242,7 +242,7 @@ class OC_Request { } /** - * @brief Check if the requester sent along an mtime + * Check if the requester sent along an mtime * @return false or an mtime */ static public function hasModificationTime () { diff --git a/lib/private/response.php b/lib/private/response.php index 1aa5e629b8b..caa382af776 100644 --- a/lib/private/response.php +++ b/lib/private/response.php @@ -10,12 +10,13 @@ class OC_Response { const STATUS_FOUND = 304; const STATUS_NOT_MODIFIED = 304; const STATUS_TEMPORARY_REDIRECT = 307; + const STATUS_BAD_REQUEST = 400; const STATUS_NOT_FOUND = 404; const STATUS_INTERNAL_SERVER_ERROR = 500; const STATUS_SERVICE_UNAVAILABLE = 503; /** - * @brief Enable response caching by sending correct HTTP headers + * Enable response caching by sending correct HTTP headers * @param integer $cache_time time to cache the response * >0 cache time in seconds * 0 and <0 enable default browser caching @@ -41,7 +42,7 @@ class OC_Response { } /** - * @brief disable browser caching + * disable browser caching * @see enableCaching with cache_time = 0 */ static public function disableCaching() { @@ -49,7 +50,7 @@ class OC_Response { } /** - * @brief Set response status + * Set response status * @param int $status a HTTP status code, see also the STATUS constants */ static public function setStatus($status) { @@ -83,7 +84,7 @@ class OC_Response { } /** - * @brief Send redirect response + * Send redirect response * @param string $location to redirect to */ static public function redirect($location) { @@ -92,8 +93,8 @@ class OC_Response { } /** - * @brief Set reponse expire time - * @param $expires date-time when the response expires + * Set reponse expire time + * @param string|DateTime $expires date-time when the response expires * string for DateInterval from now * DateTime object when to expire response */ @@ -113,7 +114,7 @@ class OC_Response { /** * Checks and set ETag header, when the request matches sends a * 'not modified' response - * @param $etag token to use for modification check + * @param string $etag token to use for modification check */ static public function setETagHeader($etag) { if (empty($etag)) { @@ -131,7 +132,7 @@ class OC_Response { /** * Checks and set Last-Modified header, when the request matches sends a * 'not modified' response - * @param $lastModified time when the reponse was last modified + * @param int|DateTime|string $lastModified time when the reponse was last modified */ static public function setLastModifiedHeader($lastModified) { if (empty($lastModified)) { @@ -170,7 +171,7 @@ class OC_Response { } /** - * @brief Send file as response, checking and setting caching headers + * Send file as response, checking and setting caching headers * @param string $filepath of file to send */ static public function sendFile($filepath) { @@ -186,4 +187,36 @@ class OC_Response { self::setStatus(self::STATUS_NOT_FOUND); } } + + /* + * This function adds some security related headers to all requests served via base.php + * The implementation of this function has to happen here to ensure that all third-party + * components (e.g. SabreDAV) also benefit from this headers. + */ + public static function addSecurityHeaders() { + header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters + header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE + + // iFrame Restriction Policy + $xFramePolicy = OC_Config::getValue('xframe_restriction', true); + if ($xFramePolicy) { + header('X-Frame-Options: Sameorigin'); // Disallow iFraming from other domains + } + + // Content Security Policy + // If you change the standard policy, please also change it in config.sample.php + $policy = OC_Config::getValue('custom_csp_policy', + 'default-src \'self\'; ' + . 'script-src \'self\' \'unsafe-eval\'; ' + . 'style-src \'self\' \'unsafe-inline\'; ' + . 'frame-src *; ' + . 'img-src *; ' + . 'font-src \'self\' data:; ' + . 'media-src *'); + header('Content-Security-Policy:' . $policy); + + // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag + header('X-Robots-Tag: none'); + } + } diff --git a/lib/private/route/route.php b/lib/private/route/route.php index df80facf9c1..87030ad7853 100644 --- a/lib/private/route/route.php +++ b/lib/private/route/route.php @@ -124,7 +124,7 @@ class Route extends SymfonyRoute implements IRoute { /** * The action to execute when this route matches, includes a file like * it is called directly - * @param $file + * @param string $file * @return void */ public function actionInclude($file) { diff --git a/lib/private/route/router.php b/lib/private/route/router.php index f7900362bec..a72ac2bb3f1 100644 --- a/lib/private/route/router.php +++ b/lib/private/route/router.php @@ -90,7 +90,7 @@ class Router implements IRouter { $files[] = 'settings/routes.php'; $files[] = 'core/routes.php'; $files[] = 'ocs/routes.php'; - $this->cacheKey = \OC_Cache::generateCacheKeyFromFiles($files); + $this->cacheKey = \OC\Cache::generateCacheKeyFromFiles($files); } return $this->cacheKey; } @@ -239,7 +239,7 @@ class Router implements IRouter { /** * To isolate the variable scope used inside the $file it is required in it's own method - * @param $file + * @param string $file */ private function requireRouteFile($file) { require_once $file; diff --git a/lib/private/server.php b/lib/private/server.php index 4c29092cf44..47bdee4b0f8 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -3,6 +3,7 @@ namespace OC; use OC\AppFramework\Http\Request; +use OC\AppFramework\Db\Db; use OC\AppFramework\Utility\SimpleContainer; use OC\Cache\UserCache; use OC\DB\ConnectionWrapper; @@ -30,9 +31,9 @@ class Server extends SimpleContainer implements IServerContainer { } if (\OC::$session->exists('requesttoken')) { - $requesttoken = \OC::$session->get('requesttoken'); + $requestToken = \OC::$session->get('requesttoken'); } else { - $requesttoken = false; + $requestToken = false; } if (defined('PHPUNIT_RUN') && PHPUNIT_RUN @@ -54,7 +55,7 @@ class Server extends SimpleContainer implements IServerContainer { ? $_SERVER['REQUEST_METHOD'] : null, 'urlParams' => $urlParams, - 'requesttoken' => $requesttoken, + 'requesttoken' => $requestToken, ), $stream ); }); @@ -158,6 +159,14 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('AvatarManager', function($c) { return new AvatarManager(); }); + $this->registerService('Logger', function($c) { + /** @var $c SimpleContainer */ + $logClass = $c->query('AllConfig')->getSystemValue('log_type', 'owncloud'); + $logger = 'OC_Log_' . ucfirst($logClass); + call_user_func(array($logger, 'init')); + + return new Log($logger); + }); $this->registerService('JobList', function ($c) { /** * @var Server $c @@ -177,6 +186,9 @@ class Server extends SimpleContainer implements IServerContainer { } return $router; }); + $this->registerService('Db', function($c){ + return new Db(); + }); } /** @@ -325,14 +337,14 @@ class Server extends SimpleContainer implements IServerContainer { } /** - * @return \OC\URLGenerator + * @return \OCP\IURLGenerator */ function getURLGenerator() { return $this->query('URLGenerator'); } /** - * @return \OC\Helper + * @return \OCP\IHelper */ function getHelper() { return $this->query('AppHelper'); @@ -393,6 +405,15 @@ class Server extends SimpleContainer implements IServerContainer { } /** + * Returns a logger instance + * + * @return \OCP\ILogger + */ + function getLogger() { + return $this->query('Logger'); + } + + /** * Returns a router for generating and matching urls * * @return \OCP\Route\IRouter @@ -400,4 +421,13 @@ class Server extends SimpleContainer implements IServerContainer { function getRouter(){ return $this->query('Router'); } + + + /** + * Returns an instance of the db facade + * @return \OCP\IDb + */ + function getDb() { + return $this->query('Db'); + } } diff --git a/lib/private/setup.php b/lib/private/setup.php index 4889f603332..7a08816c4b1 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -152,7 +152,7 @@ class OC_Setup { } /** - * @brief Post installation checks + * Post installation checks */ public static function postSetupCheck($params) { // setup was successful -> webdav testing now diff --git a/lib/private/share/helper.php b/lib/private/share/helper.php index 515ec85909a..ab9e0ca4926 100644 --- a/lib/private/share/helper.php +++ b/lib/private/share/helper.php @@ -25,13 +25,14 @@ class Helper extends \OC\Share\Constants { /** * Generate a unique target for the item - * @param string Item type - * @param string Item source - * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string User or group the item is being shared with - * @param string User that is the owner of shared item - * @param string The suggested target originating from a reshare (optional) - * @param int The id of the parent group share (optional) + * @param string $itemType + * @param string $itemSource + * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK + * @param string $shareWith User or group the item is being shared with + * @param string $uidOwner User that is the owner of shared item + * @param string $suggestedTarget The suggested target originating from a reshare (optional) + * @param int $groupParent The id of the parent group share (optional) + * @throws \Exception * @return string Item target */ public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, @@ -142,9 +143,9 @@ class Helper extends \OC\Share\Constants { /** * Delete all reshares of an item - * @param int Id of item to delete - * @param bool If true, exclude the parent from the delete (optional) - * @param string The user that the parent was shared with (optinal) + * @param int $parent Id of item to delete + * @param bool $excludeParent If true, exclude the parent from the delete (optional) + * @param string $uidOwner The user that the parent was shared with (optional) */ public static function delete($parent, $excludeParent = false, $uidOwner = null) { $ids = array($parent); @@ -201,7 +202,7 @@ class Helper extends \OC\Share\Constants { } /** - * @brief get default expire settings defined by the admin + * get default expire settings defined by the admin * @return array contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays' */ public static function getDefaultExpireSetting() { @@ -221,7 +222,7 @@ class Helper extends \OC\Share\Constants { } /** - * @brief calculate expire date + * calculate expire date * @param array $defaultExpireSettings contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays' * @param int $creationTime timestamp when the share was created * @param int $userExpireDate expire timestamp set by the user @@ -231,7 +232,7 @@ class Helper extends \OC\Share\Constants { $expires = false; - if (isset($defaultExpireSettings['defaultExpireDateSet']) && $defaultExpireSettings['defaultExpireDateSet']) { + if (!empty($defaultExpireSettings['defaultExpireDateSet'])) { $expires = $creationTime + $defaultExpireSettings['expireAfterDays'] * 86400; } @@ -239,8 +240,8 @@ class Helper extends \OC\Share\Constants { if (isset($userExpireDate)) { // if the admin decided to enforce the default expire date then we only take // the user defined expire date of it is before the default expire date - if ($expires && isset($defaultExpireSettings['enforceExpireDate']) && $defaultExpireSettings['enforceExpireDate']) { - $expires = ($userExpireDate < $expires) ? $userExpireDate : $expires; + if ($expires && !empty($defaultExpireSettings['enforceExpireDate'])) { + $expires = min($userExpireDate, $expires); } else { $expires = $userExpireDate; } diff --git a/lib/private/share/hooks.php b/lib/private/share/hooks.php index a33c71eedd2..9ac64d888ea 100644 --- a/lib/private/share/hooks.php +++ b/lib/private/share/hooks.php @@ -22,9 +22,9 @@ namespace OC\Share; class Hooks extends \OC\Share\Constants { - /** + /** * Function that is called after a user is deleted. Cleans up the shares of that user. - * @param array arguments + * @param array $arguments */ public static function post_deleteUser($arguments) { // Delete any items shared with the deleted user @@ -42,7 +42,7 @@ class Hooks extends \OC\Share\Constants { /** * Function that is called after a user is added to a group. * TODO what does it do? - * @param array arguments + * @param array $arguments */ public static function post_addToGroup($arguments) { // Find the group shares and check if the user needs a unique target @@ -76,7 +76,7 @@ class Hooks extends \OC\Share\Constants { /** * Function that is called after a user is removed from a group. Shares are cleaned up. - * @param array arguments + * @param array $arguments */ public static function post_removeFromGroup($arguments) { $sql = 'SELECT `id`, `share_type` FROM `*PREFIX*share`' @@ -95,7 +95,7 @@ class Hooks extends \OC\Share\Constants { /** * Function that is called after a group is removed. Cleans up the shares to that group. - * @param array arguments + * @param array $arguments */ public static function post_deleteGroup($arguments) { $sql = 'SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ? AND `share_with` = ?'; diff --git a/lib/private/share/mailnotifications.php b/lib/private/share/mailnotifications.php index 4799db52330..cb74dcf8b90 100644 --- a/lib/private/share/mailnotifications.php +++ b/lib/private/share/mailnotifications.php @@ -21,11 +21,30 @@ namespace OC\Share; +use DateTime; + class MailNotifications { - private $senderId; // sender userId - private $from; // sender email address + /** + * sender userId + * @var null|string + */ + private $senderId; + + /** + * sender email address + * @var string + */ + private $from; + + /** + * @var string + */ private $senderDisplayName; + + /** + * @var \OC_L10N + */ private $l; /** @@ -47,11 +66,11 @@ class MailNotifications { } /** - * @brief inform users if a file was shared with them + * inform users if a file was shared with them * * @param array $recipientList list of recipients - * @param type $itemSource shared item source - * @param type $itemType shared item type + * @param string $itemSource shared item source + * @param string $itemType shared item type * @return array list of user to whom the mail send operation failed */ public function sendInternalShareMail($recipientList, $itemSource, $itemType) { @@ -106,7 +125,7 @@ class MailNotifications { } /** - * @brief inform recipient about public link share + * inform recipient about public link share * * @param string $recipient recipient email address * @param string $filename the shared file @@ -131,12 +150,12 @@ class MailNotifications { } /** - * @brief create mail body for plain text and html mail + * create mail body for plain text and html mail * * @param string $filename the shared file * @param string $link link to the shared file * @param int $expiration expiration date (timestamp) - * @return array with the html mail body and the plain text mail body + * @return array an array of the html mail body and the plain text mail body */ private function createMailBody($filename, $link, $expiration) { diff --git a/lib/private/share/searchresultsorter.php b/lib/private/share/searchresultsorter.php index 76abbf30846..91709902fff 100644 --- a/lib/private/share/searchresultsorter.php +++ b/lib/private/share/searchresultsorter.php @@ -18,8 +18,8 @@ class SearchResultSorter { * @param string $search the search term as was given by the user * @param string $key the array key containing the value that should be compared * against - * @param $encoding optional, encoding to use, defaults to UTF-8 - * @param $log optional, an \OC\Log instance + * @param string $encoding optional, encoding to use, defaults to UTF-8 + * @param \OC\Log $log optional */ public function __construct($search, $key, \OC\Log $log = null, $encoding = 'UTF-8') { $this->encoding = $encoding; diff --git a/lib/private/share/share.php b/lib/private/share/share.php index b12d62e8439..46796c26370 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -48,11 +48,11 @@ class Share extends \OC\Share\Constants { /** * Register a sharing backend class that implements OCP\Share_Backend for an item type - * @param string Item type - * @param string Backend class - * @param string (optional) Depends on item type - * @param array (optional) List of supported file extensions if this item type depends on files - * @return Returns true if backend is registered or false if error + * @param string $itemType Item type + * @param string $class Backend class + * @param string $collectionOf (optional) Depends on item type + * @param array $supportedFileExtensions (optional) List of supported file extensions if this item type depends on files + * @return boolean true if backend is registered or false if error */ public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) { if (self::isEnabled()) { @@ -78,7 +78,7 @@ class Share extends \OC\Share\Constants { /** * Check if the Share API is enabled - * @return Returns true if enabled or false + * @return boolean true if enabled or false * * The Share API is enabled by default if not configured */ @@ -93,8 +93,8 @@ class Share extends \OC\Share\Constants { * Find which users can access a shared item * @param string $path to the file * @param string $ownerUser owner of the file - * @param bool $includeOwner include owner to the list of users with access to the file - * @param bool $returnUserPaths Return an array with the user => path map + * @param boolean $includeOwner include owner to the list of users with access to the file + * @param boolean $returnUserPaths Return an array with the user => path map * @return array * @note $path needs to be relative to user data dir, e.g. 'file.txt' * not '/admin/data/file.txt' @@ -239,12 +239,12 @@ class Share extends \OC\Share\Constants { /** * Get the items of item type shared with the current user - * @param string Item type - * @param int Format (optional) Format type must be defined by the backend - * @param mixed Parameters (optional) - * @param int Number of items to return (optional) Returns all by default - * @param bool include collections (optional) - * @return Return depends on format + * @param string $itemType + * @param int $format (optional) Format type must be defined by the backend + * @param mixed $parameters (optional) + * @param int $limit Number of items to return (optional) Returns all by default + * @param boolean $includeCollections (optional) + * @return mixed Return depends on format */ public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $includeCollections = false) { @@ -254,13 +254,13 @@ class Share extends \OC\Share\Constants { /** * Get the items of item type shared with a user - * @param string Item type - * @param sting user id for which user we want the shares - * @param int Format (optional) Format type must be defined by the backend - * @param mixed Parameters (optional) - * @param int Number of items to return (optional) Returns all by default - * @param bool include collections (optional) - * @return Return depends on format + * @param string $itemType + * @param string $user id for which user we want the shares + * @param int $format (optional) Format type must be defined by the backend + * @param mixed $parameters (optional) + * @param int $limit Number of items to return (optional) Returns all by default + * @param boolean $includeCollections (optional) + * @return mixed Return depends on format */ public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $includeCollections = false) { @@ -273,9 +273,9 @@ class Share extends \OC\Share\Constants { * @param string $itemType * @param string $itemTarget * @param int $format (optional) Format type must be defined by the backend - * @param mixed Parameters (optional) - * @param bool include collections (optional) - * @return Return depends on format + * @param mixed $parameters (optional) + * @param boolean $includeCollections (optional) + * @return mixed Return depends on format */ public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE, $parameters = null, $includeCollections = false) { @@ -334,12 +334,12 @@ class Share extends \OC\Share\Constants { /** * Get the item of item type shared with the current user by source - * @param string Item type - * @param string Item source - * @param int Format (optional) Format type must be defined by the backend - * @param mixed Parameters - * @param bool include collections - * @return Return depends on format + * @param string $itemType + * @param string $itemSource + * @param int $format (optional) Format type must be defined by the backend + * @param mixed $parameters + * @param boolean $includeCollections + * @return mixed Return depends on format */ public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE, $parameters = null, $includeCollections = false) { @@ -349,10 +349,10 @@ class Share extends \OC\Share\Constants { /** * Get the item of item type shared by a link - * @param string Item type - * @param string Item source - * @param string Owner of link - * @return Item + * @param string $itemType + * @param string $itemSource + * @param string $uidOwner Owner of link + * @return array */ public static function getItemSharedWithByLink($itemType, $itemSource, $uidOwner) { return self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE, @@ -362,7 +362,7 @@ class Share extends \OC\Share\Constants { /** * Based on the given token the share information will be returned - password protected shares will be verified * @param string $token - * @return array | bool false will be returned in case the token is unknown or unauthorized + * @return array|boolean false will be returned in case the token is unknown or unauthorized */ public static function getShareByToken($token, $checkPasswordProtection = true) { $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `token` = ?', 1); @@ -388,8 +388,8 @@ class Share extends \OC\Share\Constants { /** * resolves reshares down to the last real share - * @param $linkItem - * @return $fileOwner + * @param array $linkItem + * @return array file owner */ public static function resolveReShare($linkItem) { @@ -411,12 +411,12 @@ class Share extends \OC\Share\Constants { /** * Get the shared items of item type owned by the current user - * @param string Item type - * @param int Format (optional) Format type must be defined by the backend - * @param mixed Parameters - * @param int Number of items to return (optional) Returns all by default - * @param bool include collections - * @return Return depends on format + * @param string $itemType + * @param int $format (optional) Format type must be defined by the backend + * @param mixed $parameters + * @param int $limit Number of items to return (optional) Returns all by default + * @param boolean $includeCollections + * @return mixed Return depends on format */ public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $includeCollections = false) { @@ -426,12 +426,12 @@ class Share extends \OC\Share\Constants { /** * Get the shared item of item type owned by the current user - * @param string Item type - * @param string Item source - * @param int Format (optional) Format type must be defined by the backend - * @param mixed Parameters - * @param bool include collections - * @return Return depends on format + * @param string $itemType + * @param string $itemSource + * @param int $format (optional) Format type must be defined by the backend + * @param mixed $parameters + * @param boolean $includeCollections + * @return mixed Return depends on format */ public static function getItemShared($itemType, $itemSource, $format = self::FORMAT_NONE, $parameters = null, $includeCollections = false) { @@ -441,12 +441,12 @@ class Share extends \OC\Share\Constants { /** * Get all users an item is shared with - * @param string Item type - * @param string Item source - * @param string Owner - * @param bool Include collections - * @praram bool check expire date - * @return Return array of users + * @param string $itemType + * @param string $itemSource + * @param string $uidOwner + * @param boolean $includeCollections + * @param boolean $checkExpireDate + * @return array Return array of users */ public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections = false, $checkExpireDate = true) { @@ -471,16 +471,12 @@ class Share extends \OC\Share\Constants { * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK * @param string $shareWith User or group the item is being shared with * @param int $permissions CRUDS - * @param null $itemSourceName + * @param string $itemSourceName + * @param \DateTime $expirationDate + * @return boolean|string Returns true on success or false on failure, Returns token on success for links * @throws \Exception - * @internal param \OCP\Item $string type - * @internal param \OCP\Item $string source - * @internal param \OCP\SHARE_TYPE_USER $int , SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @internal param \OCP\User $string or group the item is being shared with - * @internal param \OCP\CRUDS $int permissions - * @return bool|string Returns true on success or false on failure, Returns token on success for links */ - public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null) { + public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null, \DateTime $expirationDate = null) { $uidOwner = \OC_User::getUser(); $sharingPolicy = \OC_Appconfig::getValue('core', 'shareapi_share_policy', 'global'); $l = \OC_L10N::get('lib'); @@ -489,16 +485,23 @@ class Share extends \OC\Share\Constants { $itemSourceName = $itemSource; } - - // verify that the file exists before we try to share it + // check if file can be shared if ($itemType === 'file' or $itemType === 'folder') { $path = \OC\Files\Filesystem::getPath($itemSource); + // verify that the file exists before we try to share it if (!$path) { $message = 'Sharing %s failed, because the file does not exist'; $message_t = $l->t('Sharing %s failed, because the file does not exist', array($itemSourceName)); \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName), \OC_Log::ERROR); throw new \Exception($message_t); } + // verify that the user has share permission + if (!\OC\Files\Filesystem::isSharable($path)) { + $message = 'You are not allowed to share %s'; + $message_t = $l->t('You are not allowed to share %s', array($itemSourceName)); + \OC_Log::write('OCP\Share', sprintf($message, $itemSourceName), \OC_Log::ERROR); + throw new \Exception($message_t); + } } //verify that we don't share a folder which already contains a share mount point @@ -588,7 +591,9 @@ class Share extends \OC\Share\Constants { $shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner)); } else if ($shareType === self::SHARE_TYPE_LINK) { if (\OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes') == 'yes') { + // when updating a link share + // FIXME Don't delete link if we update it if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE, null, 1)) { // remember old token @@ -599,7 +604,7 @@ class Share extends \OC\Share\Constants { } // Generate hash of password - same method as user passwords - if (isset($shareWith)) { + if (!empty($shareWith)) { $forcePortable = (CRYPT_BLOWFISH != 1); $hasher = new \PasswordHash(8, $forcePortable); $shareWith = $hasher->HashPassword($shareWith.\OC_Config::getValue('passwordsalt', '')); @@ -611,6 +616,13 @@ class Share extends \OC\Share\Constants { } } + if (\OCP\Util::isPublicLinkPasswordRequired() && empty($shareWith)) { + $message = 'You need to provide a password to create a public link, only protected links are allowed'; + $message_t = $l->t('You need to provide a password to create a public link, only protected links are allowed'); + \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR); + throw new \Exception($message_t); + } + // Generate token if (isset($oldToken)) { $token = $oldToken; @@ -618,7 +630,7 @@ class Share extends \OC\Share\Constants { $token = \OC_Util::generateRandomBytes(self::TOKEN_LENGTH); } $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, - null, $token, $itemSourceName); + null, $token, $itemSourceName, $expirationDate); if ($result) { return $token; } else { @@ -637,17 +649,18 @@ class Share extends \OC\Share\Constants { \OC_Log::write('OCP\Share', sprintf($message, $shareType, $itemSource), \OC_Log::ERROR); throw new \Exception($message_t); } - // Put the item into the database - return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName); + + // Put the item into the database + return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName, $expirationDate); } /** * Unshare an item from a user, group, or delete a private link - * @param string Item type - * @param string Item source - * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string User or group the item is being shared with - * @return Returns true on success or false on failure + * @param string $itemType + * @param string $itemSource + * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK + * @param string $shareWith User or group the item is being shared with + * @return boolean true on success or false on failure */ public static function unshare($itemType, $itemSource, $shareType, $shareWith) { $item = self::getItems($itemType, $itemSource, $shareType, $shareWith, \OC_User::getUser(),self::FORMAT_NONE, null, 1); @@ -660,9 +673,9 @@ class Share extends \OC\Share\Constants { /** * Unshare an item from all users, groups, and remove all links - * @param string Item type - * @param string Item source - * @return Returns true on success or false on failure + * @param string $itemType + * @param string $itemSource + * @return boolean true on success or false on failure */ public static function unshareAll($itemType, $itemSource) { // Get all of the owners of shares of this item. @@ -692,9 +705,9 @@ class Share extends \OC\Share\Constants { /** * Unshare an item shared with the current user - * @param string Item type - * @param string Item target - * @return Returns true on success or false on failure + * @param string $itemType + * @param string $itemTarget + * @return boolean true on success or false on failure * * Unsharing from self is not allowed for items inside collections */ @@ -727,12 +740,13 @@ class Share extends \OC\Share\Constants { } return false; } + /** * sent status if users got informed by mail about share * @param string $itemType * @param string $itemSource * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param bool $status + * @param boolean $status */ public static function setSendMailStatus($itemType, $itemSource, $shareType, $status) { $status = $status ? 1 : 0; @@ -751,12 +765,12 @@ class Share extends \OC\Share\Constants { /** * Set the permissions of an item for a specific user or group - * @param string Item type - * @param string Item source - * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string User or group the item is being shared with - * @param int CRUDS permissions - * @return Returns true on success or false on failure + * @param string $itemType + * @param string $itemSource + * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK + * @param string $shareWith User or group the item is being shared with + * @param int $permissions CRUDS permissions + * @return boolean true on success or false on failure */ public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) { $l = \OC_L10N::get('lib'); @@ -842,7 +856,7 @@ class Share extends \OC\Share\Constants { * @param string $itemType * @param string $itemSource * @param string $date expiration date - * @return \OCP\Share_Backend + * @return boolean */ public static function setExpirationDate($itemType, $itemSource, $date) { $user = \OC_User::getUser(); @@ -873,20 +887,24 @@ class Share extends \OC\Share\Constants { /** * Checks whether a share has expired, calls unshareItem() if yes. * @param array $item Share data (usually database row) - * @return bool True if item was expired, false otherwise. + * @return boolean True if item was expired, false otherwise. */ protected static function expireItem(array $item) { - // get default expire settings - $defaultSettings = Helper::getDefaultExpireSetting(); // calculate expire date if (!empty($item['expiration'])) { $userDefinedExpire = new \DateTime($item['expiration']); - $userDefinedExpireTimestamp = $userDefinedExpire->getTimestamp(); + $expires = $userDefinedExpire->getTimestamp(); } else { - $userDefinedExpireTimestamp = null; + $expires = null; + } + + // only use default expire date for link shares + if((int)$item['share_type'] === self::SHARE_TYPE_LINK) { + // get default expire settings + $defaultSettings = Helper::getDefaultExpireSetting(); + $expires = Helper::calculateExpireDate($defaultSettings, $item['stime'], $expires); } - $expires = Helper::calculateExpireDate($defaultSettings, $item['stime'], $userDefinedExpireTimestamp); if (is_int($expires)) { $now = time(); @@ -925,6 +943,7 @@ class Share extends \OC\Share\Constants { /** * Get the backend class for the specified item type * @param string $itemType + * @throws \Exception * @return \OCP\Share_Backend */ public static function getBackend($itemType) { @@ -957,7 +976,7 @@ class Share extends \OC\Share\Constants { /** * Check if resharing is allowed - * @return Returns true if allowed or false + * @return boolean true if allowed or false * * Resharing is allowed by default if not configured */ @@ -974,7 +993,7 @@ class Share extends \OC\Share\Constants { /** * Get a list of collection item types for the specified item type - * @param string Item type + * @param string $itemType * @return array */ private static function getCollectionItemTypes($itemType) { @@ -998,17 +1017,17 @@ class Share extends \OC\Share\Constants { /** * Get shared items from the database - * @param string Item type - * @param string Item source or target (optional) - * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique - * @param string User or group the item is being shared with - * @param string User that is the owner of shared items (optional) - * @param int Format to convert items to with formatItems() - * @param mixed Parameters to pass to formatItems() - * @param int Number of items to return, -1 to return all matches (optional) - * @param bool Include collection item types (optional) - * @param bool TODO (optional) - * @prams bool check expire date + * @param string $itemType + * @param string $item Item source or target (optional) + * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique + * @param string $shareWith User or group the item is being shared with + * @param string $uidOwner User that is the owner of shared items (optional) + * @param int $format Format to convert items to with formatItems() (optional) + * @param mixed $parameters to pass to formatItems() (optional) + * @param int $limit Number of items to return, -1 to return all matches (optional) + * @param boolean $includeCollections Include collection item types (optional) + * @param boolean $itemShareWithBySource (optional) + * @param boolean $checkExpireDate * @return array * * See public functions getItem(s)... for parameter usage @@ -1343,19 +1362,21 @@ class Share extends \OC\Share\Constants { /** * Put shared item into the database - * @param string Item type - * @param string Item source - * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK - * @param string User or group the item is being shared with - * @param string User that is the owner of shared item - * @param int CRUDS permissions - * @param bool|array Parent folder target (optional) - * @param string token (optional) - * @param string name of the source item (optional) - * @return bool Returns true on success or false on failure + * @param string $itemType Item type + * @param string $itemSource Item source + * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK + * @param string $shareWith User or group the item is being shared with + * @param string $uidOwner User that is the owner of shared item + * @param int $permissions CRUDS permissions + * @param boolean|array $parentFolder Parent folder target (optional) + * @param string $token (optional) + * @param string $itemSourceName name of the source item (optional) + * @param \DateTime $expirationDate (optional) + * @throws \Exception + * @return boolean Returns true on success or false on failure */ private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, - $permissions, $parentFolder = null, $token = null, $itemSourceName = null) { + $permissions, $parentFolder = null, $token = null, $itemSourceName = null, \DateTime $expirationDate = null) { $backend = self::getBackend($itemType); $l = \OC_L10N::get('lib'); // Check if this is a reshare @@ -1385,6 +1406,7 @@ class Share extends \OC\Share\Constants { $suggestedItemTarget = $checkReshare['item_target']; $suggestedFileTarget = $checkReshare['file_target']; $filePath = $checkReshare['file_target']; + $expirationDate = min($expirationDate, $checkReshare['expiration']); } } else { $message = 'Sharing %s failed, because resharing is not allowed'; @@ -1424,9 +1446,7 @@ class Share extends \OC\Share\Constants { $fileSource = null; } } - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' - .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' - .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); + // Share with a group if ($shareType == self::SHARE_TYPE_GROUP) { $groupItemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith['group'], @@ -1442,6 +1462,7 @@ class Share extends \OC\Share\Constants { 'uidOwner' => $uidOwner, 'permissions' => $permissions, 'fileSource' => $fileSource, + 'expiration' => $expirationDate, 'token' => $token, 'run' => &$run, 'error' => &$error @@ -1471,8 +1492,21 @@ class Share extends \OC\Share\Constants { $groupFileTarget = null; } $queriesToExecute = array(); - $queriesToExecute['groupShare'] = array($itemType, $itemSource, $groupItemTarget, $shareType, - $shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token, $parent); + $queriesToExecute['groupShare'] = array( + 'itemType' => $itemType, + 'itemSource' => $itemSource, + 'itemTarget' => $groupItemTarget, + 'shareType' => $shareType, + 'shareWith' => $shareWith['group'], + 'uidOwner' => $uidOwner, + 'permissions' => $permissions, + 'shareTime' => time(), + 'fileSource' => $fileSource, + 'fileTarget' => $groupFileTarget, + 'token' => $token, + 'parent' => $parent, + 'expiration' => $expirationDate, + ); // Loop through all users of this group in case we need to add an extra row foreach ($shareWith['users'] as $uid) { $itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $uid, @@ -1498,19 +1532,32 @@ class Share extends \OC\Share\Constants { } // Insert an extra row for the group share if the item or file target is unique for this user if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) { - $queriesToExecute[] = array($itemType, $itemSource, $itemTarget, - self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(), - $fileSource, $fileTarget, $token); - $id = \OC_DB::insertid('*PREFIX*share'); + $queriesToExecute[] = array( + 'itemType' => $itemType, + 'itemSource' => $itemSource, + 'itemTarget' => $itemTarget, + 'shareType' => self::$shareTypeGroupUserUnique, + 'shareWith' => $uid, + 'uidOwner' => $uidOwner, + 'permissions' => $permissions, + 'shareTime' => time(), + 'fileSource' => $fileSource, + 'fileTarget' => $fileTarget, + 'token' => $token, + //'parent' => $parent, + 'expiration' => $expirationDate, + ); } } - $query->execute($queriesToExecute['groupShare']); + + self::insertShare($queriesToExecute['groupShare']); // Save this id, any extra rows for this group share will need to reference it $parent = \OC_DB::insertid('*PREFIX*share'); unset($queriesToExecute['groupShare']); - foreach ($queriesToExecute as $qe) { - $qe[] = $parent; - $query->execute($qe); + + foreach ($queriesToExecute as $shareQuery) { + $shareQuery['parent'] = $parent; + self::insertShare($shareQuery); } \OC_Hook::emit('OCP\Share', 'post_shared', array( @@ -1525,7 +1572,8 @@ class Share extends \OC\Share\Constants { 'fileSource' => $fileSource, 'fileTarget' => $groupFileTarget, 'id' => $parent, - 'token' => $token + 'token' => $token, + 'expirationDate' => $expirationDate, )); if ($parentFolder === true) { @@ -1547,8 +1595,9 @@ class Share extends \OC\Share\Constants { 'permissions' => $permissions, 'fileSource' => $fileSource, 'token' => $token, + 'expirationDate' => $expirationDate, 'run' => &$run, - 'error' => &$error + 'error' => &$error, )); if ($run === false) { @@ -1572,8 +1621,23 @@ class Share extends \OC\Share\Constants { } else { $fileTarget = null; } - $query->execute(array($itemType, $itemSource, $itemTarget, $shareType, $shareWith, $uidOwner, - $permissions, time(), $fileSource, $fileTarget, $token, $parent)); + + self::insertShare(array( + 'itemType' => $itemType, + 'itemSource' => $itemSource, + 'itemTarget' => $itemTarget, + 'shareType' => $shareType, + 'shareWith' => $shareWith, + 'uidOwner' => $uidOwner, + 'permissions' => $permissions, + 'shareTime' => time(), + 'fileSource' => $fileSource, + 'fileTarget' => $fileTarget, + 'token' => $token, + 'parent' => $parent, + 'expiration' => $expirationDate, + )); + $id = \OC_DB::insertid('*PREFIX*share'); \OC_Hook::emit('OCP\Share', 'post_shared', array( 'itemType' => $itemType, @@ -1587,7 +1651,8 @@ class Share extends \OC\Share\Constants { 'fileSource' => $fileSource, 'fileTarget' => $fileTarget, 'id' => $id, - 'token' => $token + 'token' => $token, + 'expirationDate' => $expirationDate, )); if ($parentFolder === true) { $parentFolders['id'] = $id; @@ -1598,6 +1663,27 @@ class Share extends \OC\Share\Constants { return true; } + private static function insertShare(array $shareData) + { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (' + .' `item_type`, `item_source`, `item_target`, `share_type`,' + .' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' + .' `file_target`, `token`, `parent`, `expiration`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)'); + $query->bindValue(1, $shareData['itemType']); + $query->bindValue(2, $shareData['itemSource']); + $query->bindValue(3, $shareData['itemTarget']); + $query->bindValue(4, $shareData['shareType']); + $query->bindValue(5, $shareData['shareWith']); + $query->bindValue(6, $shareData['uidOwner']); + $query->bindValue(7, $shareData['permissions']); + $query->bindValue(8, $shareData['shareTime']); + $query->bindValue(9, $shareData['fileSource']); + $query->bindValue(10, $shareData['fileTarget']); + $query->bindValue(11, $shareData['token']); + $query->bindValue(12, $shareData['parent']); + $query->bindValue(13, $shareData['expiration'], 'datetime'); + $query->execute(); + } /** * Delete all shares with type SHARE_TYPE_LINK */ @@ -1614,7 +1700,7 @@ class Share extends \OC\Share\Constants { * In case a password protected link is not yet authenticated this function will return false * * @param array $linkItem - * @return bool + * @return boolean */ public static function checkPasswordProtectedShare(array $linkItem) { if (!isset($linkItem['share_with'])) { @@ -1640,9 +1726,9 @@ class Share extends \OC\Share\Constants { } /** - * @breif construct select statement + * construct select statement * @param int $format - * @param bool $fileDependent ist it a file/folder share or a generla share + * @param boolean $fileDependent ist it a file/folder share or a generla share * @param string $uidOwner * @return string select statement */ @@ -1684,7 +1770,7 @@ class Share extends \OC\Share\Constants { /** - * @brief transform db results + * transform db results * @param array $row result */ private static function transformDBResults(&$row) { @@ -1715,13 +1801,13 @@ class Share extends \OC\Share\Constants { } /** - * @brief format result + * format result * @param array $items result - * @prams string $column is it a file share or a general share ('file_target' or 'item_target') - * @params \OCP\Share_Backend $backend sharing backend + * @param string $column is it a file share or a general share ('file_target' or 'item_target') + * @param \OCP\Share_Backend $backend sharing backend * @param int $format - * @param array additional format parameters - * @return array formate result + * @param array $parameters additional format parameters + * @return array format result */ private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE , $parameters = null) { if ($format === self::FORMAT_NONE) { diff --git a/lib/private/subadmin.php b/lib/private/subadmin.php index 5b6072987ad..f5ef00ce4fe 100644 --- a/lib/private/subadmin.php +++ b/lib/private/subadmin.php @@ -31,7 +31,7 @@ OC_Hook::connect('OC_User', 'post_deleteGroup', 'OC_SubAdmin', 'post_deleteGroup class OC_SubAdmin{ /** - * @brief add a SubAdmin + * add a SubAdmin * @param string $uid uid of the SubAdmin * @param string $gid gid of the group * @return boolean @@ -44,7 +44,7 @@ class OC_SubAdmin{ } /** - * @brief delete a SubAdmin + * delete a SubAdmin * @param string $uid uid of the SubAdmin * @param string $gid gid of the group * @return boolean @@ -57,7 +57,7 @@ class OC_SubAdmin{ } /** - * @brief get groups of a SubAdmin + * get groups of a SubAdmin * @param string $uid uid of the SubAdmin * @return array */ @@ -72,7 +72,7 @@ class OC_SubAdmin{ } /** - * @brief get SubAdmins of a group + * get SubAdmins of a group * @param string $gid gid of the group * @return array */ @@ -87,7 +87,7 @@ class OC_SubAdmin{ } /** - * @brief get all SubAdmins + * get all SubAdmins * @return array */ public static function getAllSubAdmins() { @@ -101,7 +101,7 @@ class OC_SubAdmin{ } /** - * @brief checks if a user is a SubAdmin of a group + * checks if a user is a SubAdmin of a group * @param string $uid uid of the subadmin * @param string $gid gid of the group * @return bool @@ -117,7 +117,7 @@ class OC_SubAdmin{ } /** - * @brief checks if a user is a SubAdmin + * checks if a user is a SubAdmin * @param string $uid uid of the subadmin * @return bool */ @@ -137,7 +137,7 @@ class OC_SubAdmin{ } /** - * @brief checks if a user is a accessible by a subadmin + * checks if a user is a accessible by a subadmin * @param string $subadmin uid of the subadmin * @param string $user uid of the user * @return bool @@ -159,15 +159,15 @@ class OC_SubAdmin{ } /* - * @brief alias for self::isSubAdminofGroup() + * alias for self::isSubAdminofGroup() */ public static function isGroupAccessible($subadmin, $group) { return self::isSubAdminofGroup($subadmin, $group); } /** - * @brief delete all SubAdmins by uid - * @param $parameters + * delete all SubAdmins by uid + * @param array $parameters * @return boolean */ public static function post_deleteUser($parameters) { @@ -177,8 +177,8 @@ class OC_SubAdmin{ } /** - * @brief delete all SubAdmins by gid - * @param $parameters + * delete all SubAdmins by gid + * @param array $parameters * @return boolean */ public static function post_deleteGroup($parameters) { diff --git a/lib/private/tags.php b/lib/private/tags.php index 06550068f76..0b62caf2dd8 100644 --- a/lib/private/tags.php +++ b/lib/private/tags.php @@ -121,21 +121,7 @@ class Tags implements \OCP\ITags { * @return boolean. */ public function isEmpty() { - $sql = 'SELECT COUNT(*) FROM `' . self::TAG_TABLE . '` ' - . 'WHERE `uid` = ? AND `type` = ?'; - try { - $stmt = \OCP\DB::prepare($sql); - $result = $stmt->execute(array($this->user, $this->type)); - if (\OCP\DB::isError($result)) { - \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR); - return false; - } - return ((int)$result->fetchOne() === 0); - } catch(\Exception $e) { - \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), - \OCP\Util::ERROR); - return false; - } + return count($this->tags) === 0; } /** @@ -184,6 +170,10 @@ class Tags implements \OCP\ITags { $tagId = $tag; } elseif(is_string($tag)) { $tag = trim($tag); + if($tag === '') { + \OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG); + return false; + } $tagId = $this->array_searchi($tag, $this->tags); } @@ -234,11 +224,15 @@ class Tags implements \OCP\ITags { * Add a new tag. * * @param string $name A string with a name of the tag - * @return false|string the id of the added tag or false if it already exists. + * @return false|string the id of the added tag or false on error. */ public function add($name) { $name = trim($name); + if($name === '') { + \OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG); + return false; + } if($this->hasTag($name)) { \OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', \OCP\Util::DEBUG); return false; @@ -280,6 +274,12 @@ class Tags implements \OCP\ITags { public function rename($from, $to) { $from = trim($from); $to = trim($to); + + if($to === '' || $from === '') { + \OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG); + return false; + } + $id = $this->array_searchi($from, $this->tags); if($id === false) { \OCP\Util::writeLog('core', __METHOD__.', tag: ' . $from. ' does not exist', \OCP\Util::DEBUG); @@ -318,6 +318,8 @@ class Tags implements \OCP\ITags { $names = array($names); } $names = array_map('trim', $names); + array_filter($names); + $newones = array(); foreach($names as $name) { if(($this->in_arrayi( @@ -391,7 +393,7 @@ class Tags implements \OCP\ITags { * * For hooking up on post_deleteUser * - * @param array + * @param array $arguments */ public static function post_deleteUser($arguments) { // Find all objectid/tagId pairs. @@ -492,9 +494,9 @@ class Tags implements \OCP\ITags { */ public function addToFavorites($objid) { if(!$this->hasTag(self::TAG_FAVORITE)) { - $this->add(self::TAG_FAVORITE, true); + $this->add(self::TAG_FAVORITE); } - return $this->tagAs($objid, self::TAG_FAVORITE, $this->type); + return $this->tagAs($objid, self::TAG_FAVORITE); } /** @@ -504,7 +506,7 @@ class Tags implements \OCP\ITags { * @return boolean */ public function removeFromFavorites($objid) { - return $this->unTag($objid, self::TAG_FAVORITE, $this->type); + return $this->unTag($objid, self::TAG_FAVORITE); } /** @@ -512,13 +514,17 @@ class Tags implements \OCP\ITags { * * @param int $objid The id of the object * @param string $tag The id or name of the tag - * @return boolean Returns false on database error. + * @return boolean Returns false on error. */ public function tagAs($objid, $tag) { if(is_string($tag) && !is_numeric($tag)) { $tag = trim($tag); + if($tag === '') { + \OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG); + return false; + } if(!$this->hasTag($tag)) { - $this->add($tag, true); + $this->add($tag); } $tagId = $this->array_searchi($tag, $this->tags); } else { @@ -549,6 +555,10 @@ class Tags implements \OCP\ITags { public function unTag($objid, $tag) { if(is_string($tag) && !is_numeric($tag)) { $tag = trim($tag); + if($tag === '') { + \OCP\Util::writeLog('core', __METHOD__.', Tag name is empty', \OCP\Util::DEBUG); + return false; + } $tagId = $this->array_searchi($tag, $this->tags); } else { $tagId = $tag; @@ -579,6 +589,7 @@ class Tags implements \OCP\ITags { } $names = array_map('trim', $names); + array_filter($names); \OCP\Util::writeLog('core', __METHOD__ . ', before: ' . print_r($this->tags, true), \OCP\Util::DEBUG); diff --git a/lib/private/template.php b/lib/private/template.php index 3d18b52bac9..eaa58b769d7 100644 --- a/lib/private/template.php +++ b/lib/private/template.php @@ -30,9 +30,10 @@ class OC_Template extends \OC\Template\Base { private $renderas; // Create a full page? private $path; // The path to the template private $headers=array(); //custom headers + protected $app; // app id /** - * @brief Constructor + * Constructor * @param string $app app providing the template * @param string $name of the template file (without suffix) * @param string $renderas = ""; produce a full page @@ -62,6 +63,7 @@ class OC_Template extends \OC\Template\Base { // Set the private data $this->renderas = $renderas; $this->path = $path; + $this->app = $app; parent::__construct($template, $requesttoken, $l10n, $themeDefaults); } @@ -95,7 +97,7 @@ class OC_Template extends \OC\Template\Base { } /** - * @brief Returns the formfactor extension for current formfactor + * Returns the formfactor extension for current formfactor */ static public function getFormFactorExtension() { @@ -128,7 +130,7 @@ class OC_Template extends \OC\Template\Base { } /** - * @brief find the template with the given name + * find the template with the given name * @param string $name of the template file (without suffix) * * Will select the template file for the selected theme and formfactor. @@ -152,7 +154,7 @@ class OC_Template extends \OC\Template\Base { } /** - * @brief Add a custom element to the header + * Add a custom element to the header * @param string $tag tag name of the element * @param array $attributes array of attributes for the element * @param string $text the text content for the element @@ -162,7 +164,7 @@ class OC_Template extends \OC\Template\Base { } /** - * @brief Process the template + * Process the template * @return boolean|string * * This function process the template. If $this->renderas is set, it @@ -172,7 +174,7 @@ class OC_Template extends \OC\Template\Base { $data = parent::fetchPage(); if( $this->renderas ) { - $page = new OC_TemplateLayout($this->renderas); + $page = new OC_TemplateLayout($this->renderas, $this->app); // Add custom headers $page->assign('headers', $this->headers, false); @@ -189,7 +191,7 @@ class OC_Template extends \OC\Template\Base { } /** - * @brief Include template + * Include template * @return string returns content of included template * * Includes another template. use <?php echo $this->inc('template'); ?> to @@ -200,7 +202,7 @@ class OC_Template extends \OC\Template\Base { } /** - * @brief Shortcut to print a simple page for users + * Shortcut to print a simple page for users * @param string $application The application we render the template for * @param string $name Name of the template * @param array $parameters Parameters for the template @@ -215,7 +217,7 @@ class OC_Template extends \OC\Template\Base { } /** - * @brief Shortcut to print a simple page for admins + * Shortcut to print a simple page for admins * @param string $application The application we render the template for * @param string $name Name of the template * @param array $parameters Parameters for the template @@ -230,7 +232,7 @@ class OC_Template extends \OC\Template\Base { } /** - * @brief Shortcut to print a simple page for guests + * Shortcut to print a simple page for guests * @param string $application The application we render the template for * @param string $name Name of the template * @param array|string $parameters Parameters for the template @@ -245,7 +247,7 @@ class OC_Template extends \OC\Template\Base { } /** - * @brief Print a fatal error page and terminates the script + * Print a fatal error page and terminates the script * @param string $error_msg The error message to show * @param string $hint An optional hint message * Warning: All data passed to $hint needs to get sanitized using OC_Util::sanitizeHTML @@ -257,7 +259,7 @@ class OC_Template extends \OC\Template\Base { $content->printPage(); die(); } - + /** * print error page using Exception details * @param Exception $exception diff --git a/lib/private/template/base.php b/lib/private/template/base.php index 3d7c685c1cf..dbdfce24324 100644 --- a/lib/private/template/base.php +++ b/lib/private/template/base.php @@ -59,7 +59,7 @@ class Base { } /** - * @brief Assign variables + * Assign variables * @param string $key key * @param array|bool|integer|string $value value * @return bool @@ -75,7 +75,7 @@ class Base { } /** - * @brief Appends a variable + * Appends a variable * @param string $key key * @param mixed $value value * @return boolean|null @@ -94,7 +94,7 @@ class Base { } /** - * @brief Prints the proceeded template + * Prints the proceeded template * @return bool * * This function proceeds the template and prints its output. @@ -111,7 +111,7 @@ class Base { } /** - * @brief Process the template + * Process the template * @return string * * This function processes the template. @@ -121,7 +121,7 @@ class Base { } /** - * @brief doing the actual work + * doing the actual work * @param string $file * @return string content * diff --git a/lib/private/template/functions.php b/lib/private/template/functions.php index 3c42d441efa..46e48274001 100644 --- a/lib/private/template/functions.php +++ b/lib/private/template/functions.php @@ -24,7 +24,7 @@ function print_unescaped($string) { } /** - * @brief make OC_Helper::linkTo available as a simple function + * make OC_Helper::linkTo available as a simple function * @param string $app app * @param string $file file * @param array $args array with param=>value, will be appended to the returned url @@ -45,7 +45,7 @@ function link_to_docs($key) { } /** - * @brief make OC_Helper::imagePath available as a simple function + * make OC_Helper::imagePath available as a simple function * @param string $app app * @param string $image image * @return string link to the image @@ -57,7 +57,7 @@ function image_path( $app, $image ) { } /** - * @brief make OC_Helper::mimetypeIcon available as a simple function + * make OC_Helper::mimetypeIcon available as a simple function * @param string $mimetype mimetype * @return string link to the image * @@ -68,10 +68,10 @@ function mimetype_icon( $mimetype ) { } /** - * @brief make preview_icon available as a simple function + * make preview_icon available as a simple function * Returns the path to the preview of the image. - * @param $path path of file - * @returns link to the preview + * @param string $path path of file + * @return link to the preview * * For further information have a look at OC_Helper::previewIcon */ @@ -87,7 +87,7 @@ function publicPreview_icon ( $path, $token ) { } /** - * @brief make OC_Helper::humanFileSize available as a simple function + * make OC_Helper::humanFileSize available as a simple function * @param int $bytes size in bytes * @return string size as string * @@ -98,7 +98,7 @@ function human_file_size( $bytes ) { } /** - * @brief Strips the timestamp of its time value + * Strips the timestamp of its time value * @param int $timestamp UNIX timestamp to strip * @return $timestamp without time value */ @@ -109,7 +109,7 @@ function strip_time($timestamp){ } /** - * @brief Formats timestamp relatively to the current time using + * 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 diff --git a/lib/private/template/resourcelocator.php b/lib/private/template/resourcelocator.php index 8a3dd5e7fa9..7976c415922 100644 --- a/lib/private/template/resourcelocator.php +++ b/lib/private/template/resourcelocator.php @@ -52,14 +52,10 @@ abstract class ResourceLocator { } /* - * @brief append the $file resource if exist at $root - * @param $root path to check - * @param $file the filename - * @param $web base for path, default map $root to $webroot - */ - /** - * @param string $file - * @param string|false $webroot + * append the $file resource if exist at $root + * @param string $root path to check + * @param string $file the filename + * @param string|null $webroot base for path, default map $root to $webroot */ protected function appendIfExist($root, $file, $webroot = null) { if (is_file($root.'/'.$file)) { diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index b7ac02a753d..a5dd9a0c614 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -15,8 +15,9 @@ class OC_TemplateLayout extends OC_Template { /** * @param string $renderas + * @param string $appid application id */ - public function __construct( $renderas ) { + public function __construct( $renderas, $appid = '' ) { // Decide which page we show if( $renderas == 'user' ) { @@ -43,6 +44,7 @@ class OC_TemplateLayout extends OC_Template { // Add navigation entry $this->assign( 'application', '', false ); + $this->assign( 'appid', $appid ); $navigation = OC_App::getNavigation(); $this->assign( 'navigation', $navigation); $this->assign( 'settingsnavigation', OC_App::getSettingsNavigation()); @@ -98,7 +100,7 @@ class OC_TemplateLayout extends OC_Template { } /** - * @param $styles + * @param array $styles * @return array */ static public function findStylesheetFiles($styles) { @@ -116,7 +118,7 @@ class OC_TemplateLayout extends OC_Template { } /** - * @param $scripts + * @param array $scripts * @return array */ static public function findJavascriptFiles($scripts) { @@ -175,7 +177,7 @@ class OC_TemplateLayout extends OC_Template { } /** - * @param $files + * @param array $files * @return string */ private static function hashScriptNames($files) diff --git a/lib/private/updater.php b/lib/private/updater.php index 7b09f580176..58d3cab73aa 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -35,7 +35,7 @@ class Updater extends BasicEmitter { /** * Check if a new version is available * @param string $updaterUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php' - * @return array | bool + * @return array|bool */ public function check($updaterUrl) { @@ -134,7 +134,10 @@ class Updater extends BasicEmitter { $this->emit('\OC\Updater', 'failure', array($exception->getMessage())); } \OC_Config::setValue('version', implode('.', \OC_Util::getVersion())); - \OC_App::checkAppsRequirements(); + $disabledApps = \OC_App::checkAppsRequirements(); + if (!empty($disabledApps)) { + $this->emit('\OC\Updater', 'disabledApps', array($disabledApps)); + } // load all apps to also upgrade enabled apps \OC_App::loadApps(); diff --git a/lib/private/urlgenerator.php b/lib/private/urlgenerator.php index a56b0fe3378..af5d977eeab 100644 --- a/lib/private/urlgenerator.php +++ b/lib/private/urlgenerator.php @@ -29,8 +29,8 @@ class URLGenerator implements IURLGenerator { } /** - * @brief Creates an url using a defined route - * @param $route + * Creates an url using a defined route + * @param string $route * @param array $parameters * @internal param array $args with param=>value, will be appended to the returned url * @return string the url @@ -43,7 +43,7 @@ class URLGenerator implements IURLGenerator { } /** - * @brief Creates an url + * 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 @@ -92,7 +92,7 @@ class URLGenerator implements IURLGenerator { } /** - * @brief Creates path to an image + * Creates path to an image * @param string $app app * @param string $image image name * @throws \RuntimeException If the image does not exist diff --git a/lib/private/user.php b/lib/private/user.php index 7106d664aca..5d3ebb57c8c 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -62,7 +62,7 @@ class OC_User { private static $incognitoMode = false; /** - * @brief registers backend + * registers backend * @param string $backend name of the backend * @deprecated Add classes by calling useBackend with a class instance instead * @return bool @@ -75,9 +75,9 @@ class OC_User { } /** - * @brief gets available backends + * gets available backends * @deprecated - * @returns array of backends + * @return array an array of backends * * Returns the names of all backends. */ @@ -86,9 +86,9 @@ class OC_User { } /** - * @brief gets used backends + * gets used backends * @deprecated - * @returns array of backends + * @return array an array of backends * * Returns the names of all used backends. */ @@ -97,8 +97,8 @@ class OC_User { } /** - * @brief Adds the backend to the list of used backends - * @param string | OC_User_Backend $backend default: database The backend to use for user management + * Adds the backend to the list of used backends + * @param string|OC_User_Interface $backend default: database The backend to use for user management * @return bool * * Set the User Authentication Module @@ -169,7 +169,7 @@ class OC_User { } /** - * @brief Create a new user + * Create a new user * @param string $uid The username of the user to create * @param string $password The password of the new user * @throws Exception @@ -185,7 +185,7 @@ class OC_User { } /** - * @brief delete a user + * delete a user * @param string $uid The username of the user to delete * @return bool * @@ -223,7 +223,7 @@ class OC_User { } /** - * @brief Try to login a user + * Try to login a user * @param string $uid The username of the user to log in * @param string $password The password of the user * @return boolean|null @@ -236,7 +236,18 @@ class OC_User { } /** - * @brief Try to login a user, assuming authentication + * Try to login a user using the magic cookie (remember login) + * + * @param string $uid The username of the user to log in + * @param string $token + * @return bool + */ + public static function loginWithCookie($uid, $token) { + return self::getUserSession()->loginWithCookie($uid, $token); + } + + /** + * 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. @@ -262,7 +273,7 @@ class OC_User { } /** - * @brief Verify with Apache whether user is authenticated. + * Verify with Apache whether user is authenticated. * * @return boolean|null * true: authenticated @@ -286,14 +297,14 @@ class OC_User { /** - * @brief Sets user id for session and triggers emit + * Sets user id for session and triggers emit */ public static function setUserId($uid) { OC::$session->set('user_id', $uid); } /** - * @brief Sets user display name for session + * Sets user display name for session * @param string $uid * @param null $displayName * @return bool Whether the display name could get set @@ -311,7 +322,7 @@ class OC_User { } /** - * @brief Logs the current user out and kills all the session data + * Logs the current user out and kills all the session data * * Logout, destroys session */ @@ -320,8 +331,8 @@ class OC_User { } /** - * @brief Check if the user is logged in - * @returns bool + * Check if the user is logged in + * @return bool * * Checks if the user is logged in */ @@ -333,7 +344,7 @@ class OC_User { } /** - * @brief set incognito mode, e.g. if a user wants to open a public link + * set incognito mode, e.g. if a user wants to open a public link * @param bool $status */ public static function setIncognitoMode($status) { @@ -358,7 +369,7 @@ class OC_User { } /** - * @brief Check if the user is an admin user + * Check if the user is an admin user * @param string $uid uid of the admin * @return bool */ @@ -371,7 +382,7 @@ class OC_User { /** - * @brief get the user id of the user currently logged in. + * get the user id of the user currently logged in. * @return string uid or false */ public static function getUser() { @@ -384,7 +395,7 @@ class OC_User { } /** - * @brief get the display name of the user currently logged in. + * get the display name of the user currently logged in. * @param string $uid * @return string uid or false */ @@ -407,7 +418,7 @@ class OC_User { } /** - * @brief Autogenerate a password + * Autogenerate a password * @return string * * generates a password @@ -417,7 +428,7 @@ class OC_User { } /** - * @brief Set password + * Set password * @param string $uid The username * @param string $password The new password * @param string $recoveryPassword for the encryption app to reset encryption keys @@ -435,7 +446,7 @@ class OC_User { } /** - * @brief Check whether user can change his avatar + * Check whether user can change his avatar * @param string $uid The username * @return bool * @@ -451,7 +462,7 @@ class OC_User { } /** - * @brief Check whether user can change his password + * Check whether user can change his password * @param string $uid The username * @return bool * @@ -467,7 +478,7 @@ class OC_User { } /** - * @brief Check whether user can change his display name + * Check whether user can change his display name * @param string $uid The username * @return bool * @@ -483,7 +494,7 @@ class OC_User { } /** - * @brief Check if the password is correct + * Check if the password is correct * @param string $uid The username * @param string $password The password * @return string|false user id a string on success, false otherwise @@ -516,8 +527,8 @@ class OC_User { } /** - * @brief Get a list of all users - * @returns array with all uids + * Get a list of all users + * @return array an array of all uids * * Get a list of all users. * @param string $search @@ -534,7 +545,7 @@ class OC_User { } /** - * @brief Get a list of all users display name + * Get a list of all users display name * @param string $search * @param int $limit * @param int $offset @@ -552,7 +563,7 @@ class OC_User { } /** - * @brief check if a user exists + * check if a user exists * @param string $uid the username * @return boolean */ @@ -600,7 +611,7 @@ class OC_User { } /** - * @brief Set cookie value to use in next page load + * Set cookie value to use in next page load * @param string $username username to be set * @param string $token */ @@ -609,14 +620,14 @@ class OC_User { } /** - * @brief Remove cookie for "remember username" + * Remove cookie for "remember username" */ public static function unsetMagicInCookie() { self::getUserSession()->unsetMagicInCookie(); } /** - * @brief Returns the first active backend from self::$_usedBackends. + * Returns the first active backend from self::$_usedBackends. * @return OCP\Authentication\IApacheBackend|null if no backend active, otherwise OCP\Authentication\IApacheBackend */ private static function findFirstActiveUsedBackend() { diff --git a/lib/private/user/backend.php b/lib/private/user/backend.php index f4e5618e04a..56c63085f18 100644 --- a/lib/private/user/backend.php +++ b/lib/private/user/backend.php @@ -61,7 +61,7 @@ abstract class OC_User_Backend implements OC_User_Interface { ); /** - * @brief Get all supported actions + * Get all supported actions * @return int bitwise-or'ed actions * * Returns the supported actions as int to be @@ -79,7 +79,7 @@ abstract class OC_User_Backend implements OC_User_Interface { } /** - * @brief Check if backend implements actions + * Check if backend implements actions * @param int $actions bitwise-or'ed actions * @return boolean * @@ -91,7 +91,7 @@ abstract class OC_User_Backend implements OC_User_Interface { } /** - * @brief delete a user + * delete a user * @param string $uid The username of the user to delete * @return bool * @@ -102,8 +102,8 @@ abstract class OC_User_Backend implements OC_User_Interface { } /** - * @brief Get a list of all users - * @returns array with all uids + * Get a list of all users + * @return array an array of all uids * * Get a list of all users. */ @@ -112,7 +112,7 @@ abstract class OC_User_Backend implements OC_User_Interface { } /** - * @brief check if a user exists + * check if a user exists * @param string $uid the username * @return boolean */ @@ -121,7 +121,7 @@ abstract class OC_User_Backend implements OC_User_Interface { } /** - * @brief get the user's home directory + * get the user's home directory * @param string $uid the username * @return boolean */ @@ -130,7 +130,7 @@ abstract class OC_User_Backend implements OC_User_Interface { } /** - * @brief get display name of the user + * get display name of the user * @param string $uid user ID of the user * @return string display name */ @@ -139,8 +139,8 @@ abstract class OC_User_Backend implements OC_User_Interface { } /** - * @brief Get a list of all display names - * @returns array with all displayNames (value) and the corresponding uids (key) + * Get a list of all display names + * @return array an array of all displayNames (value) and the corresponding uids (key) * * Get a list of all display names and user ids. */ @@ -154,7 +154,7 @@ abstract class OC_User_Backend implements OC_User_Interface { } /** - * @brief Check if a user list is available or not + * Check if a user list is available or not * @return boolean if users can be listed or not */ public function hasUserListings() { diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 681f03981f5..d9263f6b5de 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -56,10 +56,10 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief Create a new user - * @param $uid The username of the user to create - * @param $password The password of the new user - * @returns true/false + * Create a new user + * @param string $uid The username of the user to create + * @param string $password The password of the new user + * @return bool * * Creates a new user. Basic checking of username is done in OC_User * itself, not in its subclasses. @@ -78,9 +78,9 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief delete a user - * @param $uid The username of the user to delete - * @returns true/false + * delete a user + * @param string $uid The username of the user to delete + * @return bool * * Deletes a user */ @@ -97,10 +97,10 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief Set password - * @param $uid The username - * @param $password The new password - * @returns true/false + * Set password + * @param string $uid The username + * @param string $password The new password + * @return bool * * Change the password of a user */ @@ -118,10 +118,10 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief Set display name - * @param $uid The username - * @param $displayName The new display name - * @returns true/false + * Set display name + * @param string $uid The username + * @param string $displayName The new display name + * @return bool * * Change the display name of a user */ @@ -138,8 +138,8 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief get display name of the user - * @param $uid user ID of the user + * get display name of the user + * @param string $uid user ID of the user * @return string display name */ public function getDisplayName($uid) { @@ -148,8 +148,8 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief Get a list of all display names - * @returns array with all displayNames (value) and the correspondig uids (key) + * Get a list of all display names + * @return array an array of all displayNames (value) and the correspondig uids (key) * * Get a list of all display names and user ids. */ @@ -168,10 +168,10 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief Check if the password is correct - * @param $uid The username - * @param $password The password - * @returns string + * Check if the password is correct + * @param string $uid The username + * @param string $password The password + * @return string * * Check if the password is correct without logging in the user * returns the user id or false @@ -183,14 +183,14 @@ class OC_User_Database extends OC_User_Backend { $row = $result->fetchRow(); if ($row) { $storedHash = $row['password']; - if ($storedHash[0] == '$') { //the new phpass based hashing + if ($storedHash[0] === '$') { //the new phpass based hashing $hasher = $this->getHasher(); if ($hasher->CheckPassword($password . OC_Config::getValue('passwordsalt', ''), $storedHash)) { return $row['uid']; } //old sha1 based hashing - } elseif (sha1($password) == $storedHash) { + } elseif (sha1($password) === $storedHash) { //upgrade to new hashing $this->setPassword($row['uid'], $password); return $row['uid']; @@ -201,9 +201,9 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief Load an user in the cache + * Load an user in the cache * @param string $uid the username - * @returns boolean + * @return boolean */ private function loadUser($uid) { if (empty($this->cache[$uid])) { @@ -225,8 +225,8 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief Get a list of all users - * @returns array with all uids + * Get a list of all users + * @return array an array of all uids * * Get a list of all users. */ @@ -241,7 +241,7 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief check if a user exists + * check if a user exists * @param string $uid the username * @return boolean */ @@ -251,7 +251,7 @@ class OC_User_Database extends OC_User_Backend { } /** - * @brief get the user's home directory + * get the user's home directory * @param string $uid the username * @return string|false */ @@ -273,7 +273,7 @@ class OC_User_Database extends OC_User_Backend { /** * counts the users in the database * - * @return int | bool + * @return int|bool */ public function countUsers() { $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`'); diff --git a/lib/private/user/dummy.php b/lib/private/user/dummy.php index 2fb51d02de3..776168048f6 100644 --- a/lib/private/user/dummy.php +++ b/lib/private/user/dummy.php @@ -28,7 +28,7 @@ class OC_User_Dummy extends OC_User_Backend { private $users = array(); /** - * @brief Create a new user + * Create a new user * @param string $uid The username of the user to create * @param string $password The password of the new user * @return bool @@ -46,7 +46,7 @@ class OC_User_Dummy extends OC_User_Backend { } /** - * @brief delete a user + * delete a user * @param string $uid The username of the user to delete * @return bool * @@ -62,7 +62,7 @@ class OC_User_Dummy extends OC_User_Backend { } /** - * @brief Set password + * Set password * @param string $uid The username * @param string $password The new password * @return bool @@ -79,7 +79,7 @@ class OC_User_Dummy extends OC_User_Backend { } /** - * @brief Check if the password is correct + * Check if the password is correct * @param string $uid The username * @param string $password The password * @return string @@ -96,7 +96,7 @@ class OC_User_Dummy extends OC_User_Backend { } /** - * @brief Get a list of all users + * Get a list of all users * @param string $search * @param int $limit * @param int $offset @@ -109,7 +109,7 @@ class OC_User_Dummy extends OC_User_Backend { } /** - * @brief check if a user exists + * check if a user exists * @param string $uid the username * @return boolean */ @@ -127,7 +127,7 @@ class OC_User_Dummy extends OC_User_Backend { /** * counts the users in the database * - * @return int | bool + * @return int|bool */ public function countUsers() { return 0; diff --git a/lib/private/user/example.php b/lib/private/user/example.php index b2d0dc25410..db21d6f9e52 100644 --- a/lib/private/user/example.php +++ b/lib/private/user/example.php @@ -27,10 +27,10 @@ */ abstract class OC_User_Example extends OC_User_Backend { /** - * @brief Create a new user - * @param $uid The username of the user to create - * @param $password The password of the new user - * @returns true/false + * Create a new user + * @param string $uid The username of the user to create + * @param string $password The password of the new user + * @return bool * * Creates a new user. Basic checking of username is done in OC_User * itself, not in its subclasses. @@ -38,20 +38,20 @@ abstract class OC_User_Example extends OC_User_Backend { abstract public function createUser($uid, $password); /** - * @brief Set password - * @param $uid The username - * @param $password The new password - * @returns true/false + * Set password + * @param string $uid The username + * @param string $password The new password + * @return bool * * Change the password of a user */ abstract public function setPassword($uid, $password); /** - * @brief Check if the password is correct - * @param $uid The username - * @param $password The password - * @returns string + * Check if the password is correct + * @param string $uid The username + * @param string $password The password + * @return string * * Check if the password is correct without logging in the user * returns the user id or false @@ -59,9 +59,9 @@ abstract class OC_User_Example extends OC_User_Backend { abstract public function checkPassword($uid, $password); /** - * @brief get the user's home directory - * @param $uid The username - * @returns string + * get the user's home directory + * @param string $uid The username + * @return string * * get the user's home directory * returns the path or false diff --git a/lib/private/user/http.php b/lib/private/user/http.php index a0394521012..2bb8b4c864a 100644 --- a/lib/private/user/http.php +++ b/lib/private/user/http.php @@ -27,7 +27,7 @@ class OC_User_HTTP extends OC_User_Backend { /** * split http://user@host/path into a user and url part - * @param string path + * @param string $url * @return array */ private function parseUrl($url) { @@ -46,7 +46,7 @@ class OC_User_HTTP extends OC_User_Backend { /** * check if an url is a valid login - * @param string url + * @param string $url * @return boolean */ private function matchUrl($url) { @@ -54,10 +54,10 @@ class OC_User_HTTP extends OC_User_Backend { } /** - * @brief Check if the password is correct - * @param $uid The username - * @param $password The password - * @returns string + * Check if the password is correct + * @param string $uid The username + * @param string $password The password + * @return string * * Check if the password is correct without logging in the user * returns the user id or false @@ -87,7 +87,7 @@ class OC_User_HTTP extends OC_User_Backend { } /** - * @brief check if a user exists + * check if a user exists * @param string $uid the username * @return boolean */ @@ -96,7 +96,7 @@ class OC_User_HTTP extends OC_User_Backend { } /** - * @brief get the user's home directory + * get the user's home directory * @param string $uid the username * @return string|false */ diff --git a/lib/private/user/interface.php b/lib/private/user/interface.php index cdcab3e5d00..4cdc47479a3 100644 --- a/lib/private/user/interface.php +++ b/lib/private/user/interface.php @@ -24,58 +24,54 @@ interface OC_User_Interface { /** - * @brief Check if backend implements actions + * Check if backend implements actions * @param $actions bitwise-or'ed actions - * @returns boolean + * @return boolean * * Returns the supported actions as int to be * compared with OC_USER_BACKEND_CREATE_USER etc. - * @return boolean */ public function implementsActions($actions); /** - * @brief delete a user - * @param $uid The username of the user to delete - * @returns true/false - * - * Deletes a user - * @return boolean + * delete a user + * @param string $uid The username of the user to delete + * @return bool */ public function deleteUser($uid); /** - * @brief Get a list of all users - * @returns array with all uids + * Get a list of all users + * @return array an array of all uids * * Get a list of all users. */ public function getUsers($search = '', $limit = null, $offset = null); /** - * @brief check if a user exists + * check if a user exists * @param string $uid the username * @return boolean */ public function userExists($uid); /** - * @brief get display name of the user - * @param $uid user ID of the user - * @return display name + * get display name of the user + * @param string $uid user ID of the user + * @return string display name */ public function getDisplayName($uid); /** - * @brief Get a list of all display names - * @returns array with all displayNames (value) and the corresponding uids (key) + * Get a list of all display names + * @return array an array of all displayNames (value) and the corresponding uids (key) * * Get a list of all display names and user ids. */ public function getDisplayNames($search = '', $limit = null, $offset = null); /** - * @brief Check if a user list is available or not + * Check if a user list is available or not * @return boolean if users can be listed or not */ public function hasUserListings(); diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index 6f6fd80a8ef..f2964fecca3 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -26,7 +26,7 @@ use OC\Hooks\PublicEmitter; */ class Manager extends PublicEmitter { /** - * @var \OC_User_Backend[] $backends + * @var \OC_User_Interface[] $backends */ private $backends = array(); @@ -52,12 +52,18 @@ class Manager extends PublicEmitter { unset($cachedUsers[$i]); } }); + $this->listen('\OC\User', 'postLogin', function ($user) { + $user->updateLastLoginTimestamp(); + }); + $this->listen('\OC\User', 'postRememberedLogin', function ($user) { + $user->updateLastLoginTimestamp(); + }); } /** * register a user backend * - * @param \OC_User_Backend $backend + * @param \OC_User_Interface $backend */ public function registerBackend($backend) { $this->backends[] = $backend; @@ -66,7 +72,7 @@ class Manager extends PublicEmitter { /** * remove a user backend * - * @param \OC_User_Backend $backend + * @param \OC_User_Interface $backend */ public function removeBackend($backend) { $this->cachedUsers = array(); @@ -105,7 +111,7 @@ class Manager extends PublicEmitter { * get or construct the user object * * @param string $uid - * @param \OC_User_Backend $backend + * @param \OC_User_Interface $backend * @return \OC\User\User */ protected function getUserObject($uid, $backend) { @@ -222,7 +228,7 @@ class Manager extends PublicEmitter { * @param string $uid * @param string $password * @throws \Exception - * @return bool | \OC\User\User the created user of false + * @return bool|\OC\User\User the created user of false */ public function createUser($uid, $password) { $l = \OC_L10N::get('lib'); @@ -261,7 +267,7 @@ class Manager extends PublicEmitter { /** * returns how many users per backend exist (if supported by backend) * - * @return array with backend class as key and count number as value + * @return array an array of backend class as key and count number as value */ public function countUsers() { $userCountStatistics = array(); diff --git a/lib/private/user/session.php b/lib/private/user/session.php index 1740bad5abe..5f0dee607ae 100644 --- a/lib/private/user/session.php +++ b/lib/private/user/session.php @@ -22,7 +22,9 @@ use OC\Hooks\Emitter; * - preCreateUser(string $uid, string $password) * - postCreateUser(\OC\User\User $user) * - preLogin(string $user, string $password) - * - postLogin(\OC\User\User $user) + * - postLogin(\OC\User\User $user, string $password) + * - preRememberedLogin(string $uid) + * - postRememberedLogin(\OC\User\User $user) * - logout() * * @package OC\User @@ -82,7 +84,7 @@ class Session implements Emitter, \OCP\IUserSession { /** * set the currently active user * - * @param \OC\User\User $user + * @param \OC\User\User|null $user */ public function setUser($user) { if (is_null($user)) { @@ -115,7 +117,7 @@ class Session implements Emitter, \OCP\IUserSession { /** * set the login name * - * @param string $loginName for the logged in user + * @param string|null $loginName for the logged in user */ public function setLoginName($loginName) { if (is_null($loginName)) { @@ -171,6 +173,39 @@ class Session implements Emitter, \OCP\IUserSession { } /** + * perform login using the magic cookie (remember login) + * + * @param string $uid the username + * @param string $currentToken + * @return bool + */ + public function loginWithCookie($uid, $currentToken) { + $this->manager->emit('\OC\User', 'preRememberedLogin', array($uid)); + $user = $this->manager->get($uid); + if(is_null($user)) { + // user does not exist + return false; + } + + // get stored tokens + $tokens = \OC_Preferences::getKeys($uid, 'login_token'); + // test cookies token against stored tokens + if(!in_array($currentToken, $tokens, true)) { + return false; + } + // replace successfully used token with a new one + \OC_Preferences::deleteKey($uid, 'login_token', $currentToken); + $newToken = \OC_Util::generateRandomBytes(32); + \OC_Preferences::setValue($uid, 'login_token', $newToken, time()); + $this->setMagicInCookie($user->getUID(), $newToken); + + //login + $this->setUser($user); + $this->manager->emit('\OC\User', 'postRememberedLogin', array($user)); + return true; + } + + /** * logout the user from the session */ public function logout() { @@ -191,7 +226,7 @@ class Session implements Emitter, \OCP\IUserSession { $expires = time() + \OC_Config::getValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15); setcookie("oc_username", $username, $expires, \OC::$WEBROOT, '', $secure_cookie); setcookie("oc_token", $token, $expires, \OC::$WEBROOT, '', $secure_cookie, true); - setcookie("oc_remember_login", true, $expires, \OC::$WEBROOT, '', $secure_cookie); + setcookie("oc_remember_login", "1", $expires, \OC::$WEBROOT, '', $secure_cookie); } /** diff --git a/lib/private/user/user.php b/lib/private/user/user.php index ef5364cbf7b..8aba7188e24 100644 --- a/lib/private/user/user.php +++ b/lib/private/user/user.php @@ -23,7 +23,7 @@ class User { private $displayName; /** - * @var \OC_User_Backend $backend + * @var \OC_User_Interface $backend */ private $backend; @@ -33,7 +33,7 @@ class User { private $enabled; /** - * @var Emitter | Manager $emitter + * @var Emitter|Manager $emitter */ private $emitter; @@ -43,23 +43,23 @@ class User { private $home; /** + * @var int $lastLogin + */ + private $lastLogin; + + /** * @var \OC\AllConfig $config */ private $config; /** * @param string $uid - * @param \OC_User_Backend $backend + * @param \OC_User_Interface $backend * @param \OC\Hooks\Emitter $emitter * @param \OC\AllConfig $config */ 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); - } else { - $this->displayName = $uid; - } $this->backend = $backend; $this->emitter = $emitter; $this->config = $config; @@ -69,6 +69,7 @@ class User { } else { $this->enabled = true; } + $this->lastLogin = \OC_Preferences::getValue($uid, 'login', 'lastLogin', 0); } /** @@ -86,6 +87,13 @@ class User { * @return string */ public function getDisplayName() { + if (!isset($this->displayName)) { + if ($this->backend and $this->backend->implementsActions(OC_USER_BACKEND_GET_DISPLAYNAME)) { + $this->displayName = $this->backend->getDisplayName($this->uid); + } else { + $this->displayName = $this->uid; + } + } return $this->displayName; } @@ -106,6 +114,25 @@ class User { } /** + * returns the timestamp of the user's last login or 0 if the user did never + * login + * + * @return int + */ + public function getLastLogin() { + return $this->lastLogin; + } + + /** + * updates the timestamp of the most recent login of this user + */ + public function updateLastLoginTimestamp() { + $this->lastLogin = time(); + \OC_Preferences::setValue( + $this->uid, 'login', 'lastLogin', $this->lastLogin); + } + + /** * Delete the user * * @return bool diff --git a/lib/private/util.php b/lib/private/util.php index e2005d31c38..306e37b9478 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -13,7 +13,7 @@ class OC_Util { private static $fsSetup=false; /** - * @brief Can be set up + * Can be set up * @param string $user * @return boolean * @description configure the initial filesystem based on the configuration @@ -57,7 +57,10 @@ class OC_Util { // set up quota for home storages, even for other users // which can happen when using sharing - if ($storage instanceof \OC\Files\Storage\Home) { + /** + * @var \OC\Files\Storage\Storage $storage + */ + if ($storage->instanceOfStorage('\OC\Files\Storage\Home')) { $user = $storage->getUser()->getUID(); $quota = OC_Util::getUserQuota($user); if ($quota !== \OC\Files\SPACE_UNLIMITED) { @@ -87,6 +90,39 @@ class OC_Util { } /** + * check if a password is required for each public link + * @return boolean + */ + public static function isPublicLinkPasswordRequired() { + $appConfig = \OC::$server->getAppConfig(); + $enforcePassword = $appConfig->getValue('core', 'shareapi_enforce_links_password', 'no'); + return ($enforcePassword === 'yes') ? true : false; + } + + /** + * check if sharing is disabled for the current user + * + * @return boolean + */ + public static function isSharingDisabledForUser() { + if (\OC_Appconfig::getValue('core', 'shareapi_exclude_groups', 'no') === 'yes') { + $user = \OCP\User::getUser(); + $groupsList = \OC_Appconfig::getValue('core', 'shareapi_exclude_groups_list', ''); + $excludedGroups = explode(',', $groupsList); + $usersGroups = \OC_Group::getUserGroups($user); + if (!empty($usersGroups)) { + $remainingGroups = array_diff($usersGroups, $excludedGroups); + // if the user is only in groups which are disabled for sharing then + // sharing is also disabled for the user + if (empty($remainingGroups)) { + return true; + } + } + } + return false; + } + + /** * Get the quota of a user * @param string $user * @return int Quota bytes @@ -105,7 +141,7 @@ class OC_Util { } /** - * @brief copies the user skeleton files into the fresh user home files + * copies the user skeleton files into the fresh user home files * @param string $userDirectory */ public static function copySkeleton($userDirectory) { @@ -113,7 +149,7 @@ class OC_Util { } /** - * @brief copies a directory recursively + * copies a directory recursively * @param string $source * @param string $target * @return void @@ -143,7 +179,7 @@ class OC_Util { } /** - * @brief get the current installed version of ownCloud + * get the current installed version of ownCloud * @return array */ public static function getVersion() { @@ -152,7 +188,7 @@ class OC_Util { } /** - * @brief get the current installed version string of ownCloud + * get the current installed version string of ownCloud * @return string */ public static function getVersionString() { @@ -213,7 +249,7 @@ class OC_Util { } /** - * @brief add a javascript file + * add a javascript file * * @param string $application * @param string|null $file filename @@ -232,7 +268,7 @@ class OC_Util { } /** - * @brief add a css file + * add a css file * * @param string $application * @param string|null $file filename @@ -251,7 +287,7 @@ class OC_Util { } /** - * @brief Add a custom element to the header + * Add a custom element to the header * @param string $tag tag name of the element * @param array $attributes array of attributes for the element * @param string $text the text content for the element @@ -266,7 +302,7 @@ class OC_Util { } /** - * @brief formats a timestamp in the "right" way + * formats a timestamp in the "right" way * * @param int $timestamp * @param bool $dateOnly option to omit time from the result @@ -286,7 +322,7 @@ class OC_Util { } /** - * @brief check if the current server configuration is suitable for ownCloud + * check if the current server configuration is suitable for ownCloud * @return array arrays with error messages and hints */ public static function checkServer() { @@ -480,6 +516,12 @@ class OC_Util { ); $webServerRestart = true; } + if (!self::isAnnotationsWorking()) { + $errors[] = array( + 'error'=>'PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible.', + 'hint'=>'This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator.' + ); + } if($webServerRestart) { $errors[] = array( @@ -530,7 +572,7 @@ class OC_Util { /** - * @brief check if there are still some encrypted files stored + * check if there are still some encrypted files stored * @return boolean */ public static function encryptedFiles() { @@ -551,7 +593,28 @@ class OC_Util { } /** - * @brief Check for correct file permissions of data directory + * check if a backup from the encryption keys exists + * @return boolean + */ + public static function backupKeysExists() { + //check if encryption was enabled in the past + $backupExists = false; + if (OC_App::isEnabled('files_encryption') === false) { + $view = new OC\Files\View('/' . OCP\User::getUser()); + $backupPath = '/files_encryption/keyfiles.backup'; + if ($view->is_dir($backupPath)) { + $dircontent = $view->getDirectoryContent($backupPath); + if (!empty($dircontent)) { + $backupExists = true; + } + } + } + + return $backupExists; + } + + /** + * Check for correct file permissions of data directory * @param string $dataDirectory * @return array arrays with error messages and hints */ @@ -624,7 +687,7 @@ class OC_Util { /** - * @brief Check if the app is enabled, redirects to home if not + * Check if the app is enabled, redirects to home if not * @param string $app * @return void */ @@ -651,7 +714,7 @@ class OC_Util { } /** - * @brief Check if the user is a admin, redirects to home if not + * Check if the user is a admin, redirects to home if not * @return void */ public static function checkAdminUser() { @@ -684,7 +747,7 @@ class OC_Util { } /** - * @brief Check if the user is a subadmin, redirects to home if not + * Check if the user is a subadmin, redirects to home if not * @return null|boolean $groups where the current user is subadmin */ public static function checkSubAdminUser() { @@ -697,7 +760,7 @@ class OC_Util { } /** - * @brief Redirect to the user default page + * Redirect to the user default page * @return void */ public static function redirectToDefaultPage() { @@ -721,7 +784,7 @@ class OC_Util { } /** - * @brief get an id unique for this instance + * get an id unique for this instance * @return string */ public static function getInstanceId() { @@ -735,7 +798,7 @@ class OC_Util { } /** - * @brief Static lifespan (in seconds) when a request token expires. + * Static lifespan (in seconds) when a request token expires. * @see OC_Util::callRegister() * @see OC_Util::isCallRegistered() * @description @@ -746,7 +809,7 @@ class OC_Util { public static $callLifespan = 3600; // 3600 secs = 1 hour /** - * @brief Register an get/post call. Important to prevent CSRF attacks. + * Register an get/post call. Important to prevent CSRF attacks. * @todo Write howto: CSRF protection guide * @return string Generated token. * @description @@ -771,7 +834,7 @@ class OC_Util { } /** - * @brief Check an ajax get/post call if the request token is valid. + * Check an ajax get/post call if the request token is valid. * @return boolean False if request token is not set or is invalid. * @see OC_Util::$callLifespan * @see OC_Util::callRegister() @@ -781,7 +844,7 @@ class OC_Util { } /** - * @brief Check an ajax get/post call if the request token is valid. Exit if not. + * Check an ajax get/post call if the request token is valid. Exit if not. * @todo Write howto * @return void */ @@ -792,13 +855,13 @@ class OC_Util { } /** - * @brief Public function to sanitize HTML + * Public function to sanitize HTML * * This function is used to sanitize HTML and should be applied on any * string or array of strings before displaying it on a web page. * - * @param string|array of strings - * @return array with sanitized strings or a single sanitized string, depends on the input parameter. + * @param string|array &$value + * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter. */ public static function sanitizeHTML( &$value ) { if (is_array($value)) { @@ -811,7 +874,7 @@ class OC_Util { } /** - * @brief Public function to encode url parameters + * Public function to encode url parameters * * This function is used to encode path to file before output. * Encoding is done according to RFC 3986 with one exception: @@ -827,7 +890,7 @@ class OC_Util { } /** - * @brief Check if the .htaccess file is working + * Check if the .htaccess file is working * @throws OC\HintException If the testfile can't get written. * @return bool * @description Check if the .htaccess file is working by creating a test @@ -837,7 +900,7 @@ class OC_Util { if (!\OC_Config::getValue("check_for_working_htaccess", true)) { return true; } - + // testdata $fileName = '/htaccesstest.txt'; $testContent = 'testcontent'; @@ -875,7 +938,7 @@ class OC_Util { } /** - * @brief test if webDAV is working properly + * test if webDAV is working properly * @return bool * @description * The basic assumption is that if the server returns 401/Not Authenticated for an unauthenticated PROPFIND @@ -939,7 +1002,19 @@ class OC_Util { } /** - * @brief Check if the PHP module fileinfo is loaded. + * Check if it's possible to get the inline annotations + * + * @return bool + */ + public static function isAnnotationsWorking() { + $reflection = new \ReflectionMethod(__METHOD__); + $docs = $reflection->getDocComment(); + + return (is_string($docs) && strlen($docs) > 50); + } + + /** + * Check if the PHP module fileinfo is loaded. * @return bool */ public static function fileInfoLoaded() { @@ -947,7 +1022,7 @@ class OC_Util { } /** - * @brief Check if a PHP version older then 5.3.8 is installed. + * Check if a PHP version older then 5.3.8 is installed. * @return bool */ public static function isPHPoutdated() { @@ -955,7 +1030,7 @@ class OC_Util { } /** - * @brief Check if the ownCloud server can connect to the internet + * Check if the ownCloud server can connect to the internet * @return bool */ public static function isInternetConnectionWorking() { @@ -987,7 +1062,7 @@ class OC_Util { } /** - * @brief Check if the connection to the internet is disabled on purpose + * Check if the connection to the internet is disabled on purpose * @return string */ public static function isInternetConnectionEnabled(){ @@ -995,7 +1070,7 @@ class OC_Util { } /** - * @brief clear all levels of output buffering + * clear all levels of output buffering * @return void */ public static function obEnd(){ @@ -1006,9 +1081,9 @@ class OC_Util { /** - * @brief Generates a cryptographic secure pseudo-random string - * @param Int $length of the random string - * @return String + * Generates a cryptographic secure pseudo-random string + * @param int $length of the random string + * @return string * Please also update secureRNGAvailable if you change something here */ public static function generateRandomBytes($length = 30) { @@ -1043,7 +1118,7 @@ class OC_Util { } /** - * @brief Checks if a secure random number generator is available + * Checks if a secure random number generator is available * @return bool */ public static function secureRNGAvailable() { @@ -1082,7 +1157,7 @@ class OC_Util { curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($curl, CURLOPT_URL, $url); - + curl_setopt($curl, CURLOPT_USERAGENT, "ownCloud Server Crawler"); if(OC_Config::getValue('proxy', '') != '') { @@ -1091,17 +1166,16 @@ class OC_Util { if(OC_Config::getValue('proxyuserpwd', '') != '') { curl_setopt($curl, CURLOPT_PROXYUSERPWD, OC_Config::getValue('proxyuserpwd')); } - - if (ini_get('open_basedir') === '' && ini_get('safe_mode' === 'Off')) { + + if (ini_get('open_basedir') === '' && ini_get('safe_mode') === 'Off') { curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_MAXREDIRS, $max_redirects); $data = curl_exec($curl); } else { curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false); $mr = $max_redirects; - if ($mr > 0) { + if ($mr > 0) { $newURL = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL); - $rcurl = curl_copy_handle($curl); curl_setopt($rcurl, CURLOPT_HEADER, true); curl_setopt($rcurl, CURLOPT_NOBODY, true); @@ -1125,9 +1199,9 @@ class OC_Util { curl_close($rcurl); if ($mr > 0) { curl_setopt($curl, CURLOPT_URL, $newURL); - } + } } - + if($mr == 0 && $max_redirects > 0) { $data = false; } else { @@ -1196,7 +1270,7 @@ class OC_Util { } /** - * @brief Clear the opcode cache if one exists + * Clear the opcode cache if one exists * This is necessary for writing to the config file * in case the opcode cache does not re-validate files * @return void @@ -1267,7 +1341,7 @@ class OC_Util { /** * Returns whether the given file name is valid - * @param $file string file name to check + * @param string $file file name to check * @return bool true if the file name is valid, false otherwise */ public static function isValidFileName($file) { diff --git a/lib/private/vobject.php b/lib/private/vobject.php index a3e9f7ef790..94e3470ff08 100644 --- a/lib/private/vobject.php +++ b/lib/private/vobject.php @@ -25,28 +25,28 @@ */ class OC_VObject{ /** @var Sabre\VObject\Component */ - protected $vobject; + protected $vObject; /** - * @returns Sabre\VObject\Component + * @return Sabre\VObject\Component */ public function getVObject() { - return $this->vobject; + return $this->vObject; } /** - * @brief Parses the VObject + * Parses the VObject * @param string $data VObject as string - * @returns Sabre\VObject\Reader|null + * @return Sabre\VObject\Reader|null */ public static function parse($data) { try { Sabre\VObject\Property::$classMap['LAST-MODIFIED'] = 'Sabre\VObject\Property\DateTime'; - $vobject = Sabre\VObject\Reader::read($data); - if ($vobject instanceof Sabre\VObject\Component) { - $vobject = new OC_VObject($vobject); + $vObject = Sabre\VObject\Reader::read($data); + if ($vObject instanceof Sabre\VObject\Component) { + $vObject = new OC_VObject($vObject); } - return $vobject; + return $vObject; } catch (Exception $e) { OC_Log::write('vobject', $e->getMessage(), OC_Log::ERROR); return null; @@ -54,7 +54,7 @@ class OC_VObject{ } /** - * @brief Escapes semicolons + * Escapes semicolons * @param array $value * @return string */ @@ -66,7 +66,7 @@ class OC_VObject{ } /** - * @brief Creates an array out of a multivalue property + * Creates an array out of a multivalue property * @param string $value * @return array */ @@ -89,34 +89,34 @@ class OC_VObject{ /** * Constructor - * @param Sabre\VObject\Component or string + * @param Sabre\VObject\Component|string $vobject_or_name */ public function __construct($vobject_or_name) { if (is_object($vobject_or_name)) { - $this->vobject = $vobject_or_name; + $this->vObject = $vobject_or_name; } else { - $this->vobject = new Sabre\VObject\Component($vobject_or_name); + $this->vObject = new Sabre\VObject\Component($vobject_or_name); } } /** * @todo Write documentation - * @param $item + * @param \OC_VObject|\Sabre\VObject\Component $item * @param null $itemValue */ public function add($item, $itemValue = null) { if ($item instanceof OC_VObject) { $item = $item->getVObject(); } - $this->vobject->add($item, $itemValue); + $this->vObject->add($item, $itemValue); } /** - * @brief Add property to vobject + * Add property to vobject * @param object $name of property * @param object $value of property * @param array|object $parameters of property - * @returns Sabre\VObject\Property newly created + * @return Sabre\VObject\Property newly created */ public function addProperty($name, $value, $parameters=array()) { if(is_array($value)) { @@ -127,26 +127,26 @@ class OC_VObject{ $property->parameters[] = new Sabre\VObject\Parameter($name, $value); } - $this->vobject->add($property); + $this->vObject->add($property); return $property; } public function setUID() { $uid = substr(md5(rand().time()), 0, 10); - $this->vobject->add('UID', $uid); + $this->vObject->add('UID', $uid); } /** * @todo Write documentation - * @param mixed $name + * @param mixed $name * @param string $string */ public function setString($name, $string) { if ($string != '') { $string = strtr($string, array("\r\n"=>"\n")); - $this->vobject->__set($name, $string); + $this->vObject->__set($name, $string); }else{ - $this->vobject->__unset($name); + $this->vObject->__unset($name); } } @@ -167,31 +167,31 @@ class OC_VObject{ if ($datetime instanceof DateTime) { $datetime_element = new Sabre\VObject\Property\DateTime($name); $datetime_element->setDateTime($datetime, $dateType); - $this->vobject->__set($name, $datetime_element); + $this->vObject->__set($name, $datetime_element); }else{ - $this->vobject->__unset($name); + $this->vObject->__unset($name); } } /** * @todo Write documentation - * @param $name + * @param string $name * @return string */ public function getAsString($name) { - return $this->vobject->__isset($name) ? - $this->vobject->__get($name)->value : + return $this->vObject->__isset($name) ? + $this->vObject->__get($name)->value : ''; } /** * @todo Write documentation - * @param $name + * @param string $name * @return array */ public function getAsArray($name) { $values = array(); - if ($this->vobject->__isset($name)) { + if ($this->vObject->__isset($name)) { $values = explode(',', $this->getAsString($name)); $values = array_map('trim', $values); } @@ -200,14 +200,14 @@ class OC_VObject{ /** * @todo Write documentation - * @param $name + * @param string $name * @return array|OC_VObject|\Sabre\VObject\Property */ public function &__get($name) { if ($name == 'children') { - return $this->vobject->children; + return $this->vObject->children; } - $return = $this->vobject->__get($name); + $return = $this->vObject->__get($name); if ($return instanceof Sabre\VObject\Component) { $return = new OC_VObject($return); } @@ -220,7 +220,7 @@ class OC_VObject{ * @param string $value */ public function __set($name, $value) { - return $this->vobject->__set($name, $value); + return $this->vObject->__set($name, $value); } /** @@ -228,7 +228,7 @@ class OC_VObject{ * @param string $name */ public function __unset($name) { - return $this->vobject->__unset($name); + return $this->vObject->__unset($name); } /** @@ -237,16 +237,16 @@ class OC_VObject{ * @return bool */ public function __isset($name) { - return $this->vobject->__isset($name); + return $this->vObject->__isset($name); } /** * @todo Write documentation - * @param $function - * @param $arguments + * @param callable $function + * @param array $arguments * @return mixed */ public function __call($function, $arguments) { - return call_user_func_array(array($this->vobject, $function), $arguments); + return call_user_func_array(array($this->vObject, $function), $arguments); } } |