summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/allconfig.php77
-rw-r--r--lib/app.php31
-rw-r--r--lib/appframework/core/api.php217
-rw-r--r--lib/appframework/dependencyinjection/dicontainer.php55
-rw-r--r--lib/base.php1
-rw-r--r--lib/db.php6
-rw-r--r--lib/db/connection.php2
-rw-r--r--lib/db/oracleconnection.php50
-rw-r--r--lib/files/cache/cache.php4
-rw-r--r--lib/files/cache/scanner.php52
-rw-r--r--lib/files/view.php14
-rw-r--r--lib/l10n/ca.php3
-rw-r--r--lib/l10n/cs_CZ.php3
-rw-r--r--lib/l10n/da.php3
-rw-r--r--lib/l10n/de.php3
-rw-r--r--lib/l10n/de_DE.php3
-rw-r--r--lib/l10n/en_GB.php11
-rw-r--r--lib/l10n/et_EE.php3
-rw-r--r--lib/l10n/fi_FI.php7
-rw-r--r--lib/l10n/fr.php3
-rw-r--r--lib/l10n/gl.php3
-rw-r--r--lib/l10n/it.php3
-rw-r--r--lib/l10n/ja_JP.php3
-rw-r--r--lib/l10n/lt_LT.php3
-rw-r--r--lib/l10n/nl.php16
-rw-r--r--lib/l10n/nn_NO.php2
-rw-r--r--lib/l10n/pa.php16
-rw-r--r--lib/l10n/pt_BR.php3
-rw-r--r--lib/l10n/pt_PT.php2
-rw-r--r--lib/l10n/ro.php8
-rw-r--r--lib/l10n/ru.php17
-rw-r--r--lib/l10n/sr@latin.php8
-rw-r--r--lib/legacy/preferences.php146
-rw-r--r--lib/navigationmanager.php64
-rw-r--r--lib/preferences.php153
-rw-r--r--lib/public/app.php16
-rw-r--r--lib/public/appframework/iapi.php89
-rw-r--r--lib/public/appframework/iappcontainer.php12
-rw-r--r--lib/public/iconfig.php65
-rw-r--r--lib/public/idbconnection.php74
-rw-r--r--lib/public/inavigationmanager.php27
-rw-r--r--lib/public/iservercontainer.php46
-rw-r--r--lib/public/itagmanager.php48
-rw-r--r--lib/public/itags.php164
-rw-r--r--lib/public/iusersession.php30
-rw-r--r--lib/public/share.php41
-rw-r--r--lib/public/user.php2
-rw-r--r--lib/search/provider/file.php3
-rw-r--r--lib/search/result.php4
-rw-r--r--lib/server.php141
-rw-r--r--lib/tagmanager.php68
-rw-r--r--lib/tags.php642
-rw-r--r--lib/user.php60
-rw-r--r--lib/user/http.php6
-rw-r--r--lib/user/manager.php19
-rw-r--r--lib/user/session.php21
-rw-r--r--lib/user/user.php18
-rw-r--r--lib/vcategories.php821
58 files changed, 2057 insertions, 1355 deletions
diff --git a/lib/allconfig.php b/lib/allconfig.php
new file mode 100644
index 00000000000..72aabf60793
--- /dev/null
+++ b/lib/allconfig.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OC;
+
+/**
+ * Class to combine all the configuration options ownCloud offers
+ */
+class AllConfig implements \OCP\IConfig {
+ /**
+ * Sets a new system wide value
+ * @param string $key the key of the value, under which will be saved
+ * @param string $value the value that should be stored
+ * @todo need a use case for this
+ */
+// public function setSystemValue($key, $value) {
+// \OCP\Config::setSystemValue($key, $value);
+// }
+
+ /**
+ * Looks up a system wide defined value
+ * @param string $key the key of the value, under which it was saved
+ * @return string the saved value
+ */
+ public function getSystemValue($key) {
+ return \OCP\Config::getSystemValue($key, '');
+ }
+
+
+ /**
+ * Writes a new app wide value
+ * @param string $appName the appName that we want to store the value under
+ * @param string $key the key of the value, under which will be saved
+ * @param string $value the value that should be stored
+ */
+ public function setAppValue($appName, $key, $value) {
+ \OCP\Config::setAppValue($appName, $key, $value);
+ }
+
+ /**
+ * Looks up an app wide defined value
+ * @param string $appName the appName that we stored the value under
+ * @param string $key the key of the value, under which it was saved
+ * @return string the saved value
+ */
+ public function getAppValue($appName, $key) {
+ return \OCP\Config::getAppValue($appName, $key, '');
+ }
+
+
+ /**
+ * Set a user defined value
+ * @param string $userId the userId of the user that we want to store the value under
+ * @param string $appName the appName that we want to store the value under
+ * @param string $key the key under which the value is being stored
+ * @param string $value the value that you want to store
+ */
+ public function setUserValue($userId, $appName, $key, $value) {
+ \OCP\Config::setUserValue($userId, $appName, $key, $value);
+ }
+
+ /**
+ * Shortcut for getting a user defined value
+ * @param string $userId the userId of the user that we want to store the value under
+ * @param string $appName the appName that we stored the value under
+ * @param string $key the key under which the value is being stored
+ */
+ public function getUserValue($userId, $appName, $key){
+ return \OCP\Config::getUserValue($userId, $appName, $key);
+ }
+}
diff --git a/lib/app.php b/lib/app.php
index d98af2dc296..0ab1ee57f63 100644
--- a/lib/app.php
+++ b/lib/app.php
@@ -27,8 +27,6 @@
* upgrading and removing apps.
*/
class OC_App{
- static private $activeapp = '';
- static private $navigation = array();
static private $settingsForms = array();
static private $adminForms = array();
static private $personalForms = array();
@@ -271,7 +269,7 @@ class OC_App{
/**
* @brief adds an entry to the navigation
- * @param string $data array containing the data
+ * @param array $data array containing the data
* @return bool
*
* This function adds a new entry to the navigation visible to users. $data
@@ -287,11 +285,7 @@ class OC_App{
* the navigation. Lower values come first.
*/
public static function addNavigationEntry( $data ) {
- $data['active']=false;
- if(!isset($data['icon'])) {
- $data['icon']='';
- }
- OC_App::$navigation[] = $data;
+ OC::$server->getNavigationManager()->add($data);
return true;
}
@@ -305,9 +299,7 @@ class OC_App{
* highlighting the current position of the user.
*/
public static function setActiveNavigationEntry( $id ) {
- // load all the apps, to make sure we have all the navigation entries
- self::loadApps();
- self::$activeapp = $id;
+ OC::$server->getNavigationManager()->setActiveEntry($id);
return true;
}
@@ -315,15 +307,14 @@ class OC_App{
* @brief Get the navigation entries for the $app
* @param string $app app
* @return array of the $data added with addNavigationEntry
+ *
+ * Warning: destroys the existing entries
*/
public static function getAppNavigationEntries($app) {
if(is_file(self::getAppPath($app).'/appinfo/app.php')) {
- $save = self::$navigation;
- self::$navigation = array();
+ OC::$server->getNavigationManager()->clear();
require $app.'/appinfo/app.php';
- $app_entries = self::$navigation;
- self::$navigation = $save;
- return $app_entries;
+ return OC::$server->getNavigationManager()->getAll();
}
return array();
}
@@ -336,7 +327,7 @@ class OC_App{
* setActiveNavigationEntry
*/
public static function getActiveNavigationEntry() {
- return self::$activeapp;
+ return OC::$server->getNavigationManager()->getActiveEntry();
}
/**
@@ -419,8 +410,9 @@ class OC_App{
// This is private as well. It simply works, so don't ask for more details
private static function proceedNavigation( $list ) {
+ $activeapp = OC::$server->getNavigationManager()->getActiveEntry();
foreach( $list as &$naventry ) {
- if( $naventry['id'] == self::$activeapp ) {
+ if( $naventry['id'] == $activeapp ) {
$naventry['active'] = true;
}
else{
@@ -572,7 +564,8 @@ class OC_App{
* - active: boolean, signals if the user is on this navigation entry
*/
public static function getNavigation() {
- $navigation = self::proceedNavigation( self::$navigation );
+ $entries = OC::$server->getNavigationManager()->getAll();
+ $navigation = self::proceedNavigation( $entries );
return $navigation;
}
diff --git a/lib/appframework/core/api.php b/lib/appframework/core/api.php
index 337e3b57d6d..39522ee3dd5 100644
--- a/lib/appframework/core/api.php
+++ b/lib/appframework/core/api.php
@@ -47,24 +47,6 @@ class API implements IApi{
/**
- * used to return the appname of the set application
- * @return string the name of your application
- */
- public function getAppName(){
- return $this->appName;
- }
-
-
- /**
- * Creates a new navigation entry
- * @param array $entry containing: id, name, order, icon and href key
- */
- public function addNavigationEntry(array $entry){
- \OCP\App::addNavigationEntry($entry);
- }
-
-
- /**
* Gets the userid of the current user
* @return string the user id of the current user
*/
@@ -74,14 +56,6 @@ class API implements IApi{
/**
- * Sets the current navigation entry to the currently running app
- */
- public function activateNavigationEntry(){
- \OCP\App::setActiveNavigationEntry($this->appName);
- }
-
-
- /**
* Adds a new javascript file
* @param string $scriptName the name of the javascript in js/ without the suffix
* @param string $appName the name of the app, defaults to the current one
@@ -124,79 +98,6 @@ class API implements IApi{
\OCP\Util::addStyle($this->appName . '/3rdparty', $name);
}
- /**
- * Looks up a systemwide defined value
- * @param string $key the key of the value, under which it was saved
- * @return string the saved value
- */
- public function getSystemValue($key){
- return \OCP\Config::getSystemValue($key, '');
- }
-
-
- /**
- * Sets a new systemwide value
- * @param string $key the key of the value, under which will be saved
- * @param string $value the value that should be stored
- */
- public function setSystemValue($key, $value){
- return \OCP\Config::setSystemValue($key, $value);
- }
-
-
- /**
- * Looks up an appwide defined value
- * @param string $key the key of the value, under which it was saved
- * @return string the saved value
- */
- public function getAppValue($key, $appName=null){
- if($appName === null){
- $appName = $this->appName;
- }
- return \OCP\Config::getAppValue($appName, $key, '');
- }
-
-
- /**
- * Writes a new appwide value
- * @param string $key the key of the value, under which will be saved
- * @param string $value the value that should be stored
- */
- public function setAppValue($key, $value, $appName=null){
- if($appName === null){
- $appName = $this->appName;
- }
- return \OCP\Config::setAppValue($appName, $key, $value);
- }
-
-
-
- /**
- * Shortcut for setting a user defined value
- * @param string $key the key under which the value is being stored
- * @param string $value the value that you want to store
- * @param string $userId the userId of the user that we want to store the value under, defaults to the current one
- */
- public function setUserValue($key, $value, $userId=null){
- if($userId === null){
- $userId = $this->getUserId();
- }
- \OCP\Config::setUserValue($userId, $this->appName, $key, $value);
- }
-
-
- /**
- * Shortcut for getting a user defined value
- * @param string $key the key under which the value is being stored
- * @param string $userId the userId of the user that we want to store the value under, defaults to the current one
- */
- public function getUserValue($key, $userId=null){
- if($userId === null){
- $userId = $this->getUserId();
- }
- return \OCP\Config::getUserValue($userId, $this->appName, $key);
- }
-
/**
* Returns the translation object
@@ -209,28 +110,6 @@ class API implements IApi{
/**
- * 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 \OCP\DB a query object
- */
- 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);
- }
-
-
- /**
* Returns the URL for a route
* @param string $routeName the name of the route
* @param array $arguments an array with arguments which will be filled into the url
@@ -294,37 +173,6 @@ class API implements IApi{
/**
- * Checks if the current user is logged in
- * @return bool true if logged in
- */
- public function isLoggedIn(){
- return \OCP\User::isLoggedIn();
- }
-
-
- /**
- * Checks if a user is an admin
- * @param string $userId the id of the user
- * @return bool true if admin
- */
- public function isAdminUser($userId){
- # TODO: use public api
- return \OC_User::isAdminUser($userId);
- }
-
-
- /**
- * Checks if a user is an subadmin
- * @param string $userId the id of the user
- * @return bool true if subadmin
- */
- public function isSubAdminUser($userId){
- # TODO: use public api
- return \OC_SubAdmin::isSubAdmin($userId);
- }
-
-
- /**
* Checks if the CSRF check was correct
* @return bool true if CSRF check passed
*/
@@ -372,26 +220,6 @@ class API implements IApi{
/**
- * Returns a template
- * @param string $templateName the name of the template
- * @param string $renderAs how it should be rendered
- * @param string $appName the name of the app
- * @return \OCP\Template a new template
- */
- public function getTemplate($templateName, $renderAs='user', $appName=null){
- if($appName === null){
- $appName = $this->appName;
- }
-
- if($renderAs === 'blank'){
- return new \OCP\Template($appName, $templateName);
- } else {
- return new \OCP\Template($appName, $templateName, $renderAs);
- }
- }
-
-
- /**
* turns an owncloud path into a path on the filesystem
* @param string path the path to the file on the oc filesystem
* @return string the filepath in the filesystem
@@ -468,6 +296,26 @@ class API implements IApi{
}
/**
+ * Returns a template
+ * @param string $templateName the name of the template
+ * @param string $renderAs how it should be rendered
+ * @param string $appName the name of the app
+ * @return \OCP\Template a new template
+ */
+ public function getTemplate($templateName, $renderAs='user', $appName=null){
+ if($appName === null){
+ $appName = $this->appName;
+ }
+
+ if($renderAs === 'blank'){
+ return new \OCP\Template($appName, $templateName);
+ } else {
+ return new \OCP\Template($appName, $templateName, $renderAs);
+ }
+ }
+
+
+ /**
* Tells ownCloud to include a template in the admin overview
* @param string $mainPath the path to the main php file without the php
* suffix, relative to your apps directory! not the template directory
@@ -481,23 +329,6 @@ class API implements IApi{
\OCP\App::registerAdmin($appName, $mainPath);
}
- /**
- * Do a user login
- * @param string $user the username
- * @param string $password the password
- * @return bool true if successful
- */
- public function login($user, $password) {
- return \OC_User::login($user, $password);
- }
-
- /**
- * @brief Loggs the user out including all the session data
- * Logout, destroys session
- */
- public function logout() {
- return \OCP\User::logout();
- }
/**
* get the filesystem info
@@ -514,12 +345,4 @@ class API implements IApi{
return \OC\Files\Filesystem::getFileInfo($path);
}
- /**
- * get the view
- *
- * @return OC\Files\View instance
- */
- public function getView() {
- return \OC\Files\Filesystem::getView();
- }
}
diff --git a/lib/appframework/dependencyinjection/dicontainer.php b/lib/appframework/dependencyinjection/dicontainer.php
index 2ef885d7b2c..3755d45fa09 100644
--- a/lib/appframework/dependencyinjection/dicontainer.php
+++ b/lib/appframework/dependencyinjection/dicontainer.php
@@ -34,10 +34,16 @@ use OC\AppFramework\Utility\SimpleContainer;
use OC\AppFramework\Utility\TimeFactory;
use OCP\AppFramework\IApi;
use OCP\AppFramework\IAppContainer;
+use OCP\AppFramework\IMiddleWare;
+use OCP\IServerContainer;
class DIContainer extends SimpleContainer implements IAppContainer{
+ /**
+ * @var array
+ */
+ private $middleWares = array();
/**
* Put your class dependencies in here
@@ -57,31 +63,10 @@ class DIContainer extends SimpleContainer implements IAppContainer{
* Http
*/
$this['Request'] = $this->share(function($c) {
-
- $params = array();
-
- // we json decode the body only in case of content type json
- if (isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'],'json') === true ) {
- $params = json_decode(file_get_contents('php://input'), true);
- $params = is_array($params) ? $params: array();
- }
-
- return new Request(
- array(
- 'get' => $_GET,
- 'post' => $_POST,
- 'files' => $_FILES,
- 'server' => $_SERVER,
- 'env' => $_ENV,
- 'session' => $_SESSION,
- 'cookies' => $_COOKIE,
- 'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
- ? $_SERVER['REQUEST_METHOD']
- : null,
- 'params' => $params,
- 'urlParams' => $c['urlParams']
- )
- );
+ /** @var $c SimpleContainer */
+ /** @var $server IServerContainer */
+ $server = $c->query('ServerContainer');
+ return $server->getRequest();
});
$this['Protocol'] = $this->share(function($c){
@@ -108,6 +93,10 @@ class DIContainer extends SimpleContainer implements IAppContainer{
$dispatcher = new MiddlewareDispatcher();
$dispatcher->registerMiddleware($c['SecurityMiddleware']);
+ foreach($this->middleWares as $middleWare) {
+ $dispatcher->registerMiddleware($middleWare);
+ }
+
return $dispatcher;
});
@@ -138,4 +127,20 @@ class DIContainer extends SimpleContainer implements IAppContainer{
{
return $this->query('ServerContainer');
}
+
+ /**
+ * @param IMiddleWare $middleWare
+ * @return boolean
+ */
+ function registerMiddleWare(IMiddleWare $middleWare) {
+ array_push($this->middleWares, $middleWare);
+ }
+
+ /**
+ * used to return the appname of the set application
+ * @return string the name of your application
+ */
+ function getAppName() {
+ return $this->query('AppName');
+ }
}
diff --git a/lib/base.php b/lib/base.php
index 0650361be91..58894be03ee 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -371,6 +371,7 @@ class OC {
self::$loader->registerPrefix('Doctrine\\Common', 'doctrine/common/lib');
self::$loader->registerPrefix('Doctrine\\DBAL', 'doctrine/dbal/lib');
self::$loader->registerPrefix('Symfony\\Component\\Routing', 'symfony/routing');
+ self::$loader->registerPrefix('Symfony\\Component\\Console', 'symfony/console');
self::$loader->registerPrefix('Sabre\\VObject', '3rdparty');
self::$loader->registerPrefix('Sabre_', '3rdparty');
self::$loader->registerPrefix('Patchwork', '3rdparty');
diff --git a/lib/db.php b/lib/db.php
index b9505b88d82..1e5d12649df 100644
--- a/lib/db.php
+++ b/lib/db.php
@@ -87,6 +87,7 @@ class OC_DB {
'driver' => 'pdo_sqlite',
);
$connectionParams['adapter'] = '\OC\DB\AdapterSqlite';
+ $connectionParams['wrapperClass'] = 'OC\DB\Connection';
break;
case 'mysql':
$connectionParams = array(
@@ -99,6 +100,7 @@ class OC_DB {
'driver' => 'pdo_mysql',
);
$connectionParams['adapter'] = '\OC\DB\Adapter';
+ $connectionParams['wrapperClass'] = 'OC\DB\Connection';
break;
case 'pgsql':
$connectionParams = array(
@@ -110,6 +112,7 @@ class OC_DB {
'driver' => 'pdo_pgsql',
);
$connectionParams['adapter'] = '\OC\DB\AdapterPgSql';
+ $connectionParams['wrapperClass'] = 'OC\DB\Connection';
break;
case 'oci':
$connectionParams = array(
@@ -124,6 +127,7 @@ class OC_DB {
$connectionParams['port'] = $port;
}
$connectionParams['adapter'] = '\OC\DB\AdapterOCI8';
+ $connectionParams['wrapperClass'] = 'OC\DB\OracleConnection';
$eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\OracleSessionInit);
break;
case 'mssql':
@@ -137,11 +141,11 @@ class OC_DB {
'driver' => 'pdo_sqlsrv',
);
$connectionParams['adapter'] = '\OC\DB\AdapterSQLSrv';
+ $connectionParams['wrapperClass'] = 'OC\DB\Connection';
break;
default:
return false;
}
- $connectionParams['wrapperClass'] = 'OC\DB\Connection';
$connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_' );
try {
self::$connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config, $eventManager);
diff --git a/lib/db/connection.php b/lib/db/connection.php
index 2581969dbd0..2d3193a148a 100644
--- a/lib/db/connection.php
+++ b/lib/db/connection.php
@@ -12,7 +12,7 @@ use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\Common\EventManager;
-class Connection extends \Doctrine\DBAL\Connection {
+class Connection extends \Doctrine\DBAL\Connection implements \OCP\IDBConnection {
/**
* @var string $tablePrefix
*/
diff --git a/lib/db/oracleconnection.php b/lib/db/oracleconnection.php
new file mode 100644
index 00000000000..e2fc4644f47
--- /dev/null
+++ b/lib/db/oracleconnection.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\DB;
+
+class OracleConnection extends Connection {
+ /**
+ * Quote the keys of the array
+ */
+ private function quoteKeys(array $data) {
+ $return = array();
+ foreach($data as $key => $value) {
+ $return[$this->quoteIdentifier($key)] = $value;
+ }
+ return $return;
+ }
+
+ /*
+ * {@inheritDoc}
+ */
+ public function insert($tableName, array $data, array $types = array()) {
+ $tableName = $this->quoteIdentifier($tableName);
+ $data = $this->quoteKeys($data);
+ return parent::insert($tableName, $data, $types);
+ }
+
+ /*
+ * {@inheritDoc}
+ */
+ public function update($tableName, array $data, array $identifier, array $types = array()) {
+ $tableName = $this->quoteIdentifier($tableName);
+ $data = $this->quoteKeys($data);
+ $identifier = $this->quoteKeys($identifier);
+ return parent::update($tableName, $data, $identifier, $types);
+ }
+
+ /*
+ * {@inheritDoc}
+ */
+ public function delete($tableName, array $identifier) {
+ $tableName = $this->quoteIdentifier($tableName);
+ $identifier = $this->quoteKeys($identifier);
+ return parent::delete($tableName, $identifier);
+ }
+}
diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php
index 39e36684b7b..e69733727af 100644
--- a/lib/files/cache/cache.php
+++ b/lib/files/cache/cache.php
@@ -201,7 +201,6 @@ class Cache {
$data['path'] = $file;
$data['parent'] = $this->getParentId($file);
$data['name'] = \OC_Util::basename($file);
- $data['encrypted'] = isset($data['encrypted']) ? ((int)$data['encrypted']) : 0;
list($queryParts, $params) = $this->buildParts($data);
$queryParts[] = '`storage`';
@@ -265,6 +264,9 @@ class Cache {
$params[] = $value;
$queryParts[] = '`mtime`';
}
+ } elseif ($name === 'encrypted') {
+ // Boolean to integer conversion
+ $value = $value ? 1 : 0;
}
$params[] = $value;
$queryParts[] = '`' . $name . '`';
diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php
index 9d180820e9d..96f84609cf2 100644
--- a/lib/files/cache/scanner.php
+++ b/lib/files/cache/scanner.php
@@ -36,6 +36,11 @@ class Scanner extends BasicEmitter {
*/
private $cache;
+ /**
+ * @var \OC\Files\Cache\Permissions $permissionsCache
+ */
+ private $permissionsCache;
+
const SCAN_RECURSIVE = true;
const SCAN_SHALLOW = false;
@@ -46,6 +51,7 @@ class Scanner extends BasicEmitter {
$this->storage = $storage;
$this->storageId = $this->storage->getId();
$this->cache = $storage->getCache();
+ $this->permissionsCache = $storage->getPermissionsCache();
}
/**
@@ -96,22 +102,48 @@ class Scanner extends BasicEmitter {
}
}
$newData = $data;
- if ($reuseExisting and $cacheData = $this->cache->get($file)) {
- // only reuse data if the file hasn't explicitly changed
- if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) {
- if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) {
- $data['size'] = $cacheData['size'];
+ $cacheData = $this->cache->get($file);
+ if ($cacheData) {
+ $this->permissionsCache->remove($cacheData['fileid']);
+ if ($reuseExisting) {
+ // prevent empty etag
+ $etag = $cacheData['etag'];
+ $propagateETagChange = false;
+ if (empty($etag)) {
+ $etag = $data['etag'];
+ $propagateETagChange = true;
}
- if ($reuseExisting & self::REUSE_ETAG) {
- $data['etag'] = $cacheData['etag'];
+ // only reuse data if the file hasn't explicitly changed
+ if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) {
+ if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) {
+ $data['size'] = $cacheData['size'];
+ }
+ if ($reuseExisting & self::REUSE_ETAG) {
+ $data['etag'] = $etag;
+ if ($propagateETagChange) {
+ $parent = $file;
+ while ($parent !== '') {
+ $parent = dirname($parent);
+ if ($parent === '.') {
+ $parent = '';
+ }
+ $parentCacheData = $this->cache->get($parent);
+ $this->cache->update($parentCacheData['fileid'], array(
+ 'etag' => $this->storage->getETag($parent),
+ ));
+ }
+ }
+ }
}
+ // Only update metadata that has changed
+ $newData = array_diff($data, $cacheData);
}
- // Only update metadata that has changed
- $newData = array_diff($data, $cacheData);
}
if (!empty($newData)) {
$this->cache->put($file, $newData);
}
+ } else {
+ $this->cache->remove($file);
}
return $data;
}
@@ -159,7 +191,7 @@ class Scanner extends BasicEmitter {
$newChildren = array();
if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) {
\OC_DB::beginTransaction();
- if(is_resource($dh)) {
+ if (is_resource($dh)) {
while (($file = readdir($dh)) !== false) {
$child = ($path) ? $path . '/' . $file : $file;
if (!Filesystem::isIgnoredDir($file)) {
diff --git a/lib/files/view.php b/lib/files/view.php
index 968b755a661..aa08a5f7cc9 100644
--- a/lib/files/view.php
+++ b/lib/files/view.php
@@ -500,7 +500,7 @@ class View {
} else {
if ($this->is_dir($path1) && ($dh = $this->opendir($path1))) {
$result = $this->mkdir($path2);
- if(is_resource($dh)) {
+ if (is_resource($dh)) {
while (($file = readdir($dh)) !== false) {
if (!Filesystem::isIgnoredDir($file)) {
$result = $this->copy($path1 . '/' . $file, $path2 . '/' . $file);
@@ -975,7 +975,7 @@ class View {
/**
* search for files by mimetype
*
- * @param string $query
+ * @param string $mimetype
* @return array
*/
public function searchByMime($mimetype) {
@@ -998,7 +998,7 @@ class View {
$results = $cache->$method($query);
foreach ($results as $result) {
- if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) {
+ if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') {
$result['path'] = substr($mountPoint . $result['path'], $rootLength);
$files[] = $result;
}
@@ -1012,9 +1012,11 @@ class View {
$relativeMountPoint = substr($mountPoint, $rootLength);
$results = $cache->$method($query);
- foreach ($results as $result) {
- $result['path'] = $relativeMountPoint . $result['path'];
- $files[] = $result;
+ if ($results) {
+ foreach ($results as $result) {
+ $result['path'] = $relativeMountPoint . $result['path'];
+ $files[] = $result;
+ }
}
}
}
diff --git a/lib/l10n/ca.php b/lib/l10n/ca.php
index 166455e652c..a8769224705 100644
--- a/lib/l10n/ca.php
+++ b/lib/l10n/ca.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Usuaris",
"Admin" => "Administració",
"Failed to upgrade \"%s\"." => "Ha fallat l'actualització \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Les imatges de perfil personals encara no funcionen amb encriptació",
+"Unknown filetype" => "Tipus de fitxer desconegut",
+"Invalid image" => "Imatge no vàlida",
"web services under your control" => "controleu els vostres serveis web",
"cannot open \"%s\"" => "no es pot obrir \"%s\"",
"ZIP download is turned off." => "La baixada en ZIP està desactivada.",
diff --git a/lib/l10n/cs_CZ.php b/lib/l10n/cs_CZ.php
index fed9ad03c01..ed31ae79529 100644
--- a/lib/l10n/cs_CZ.php
+++ b/lib/l10n/cs_CZ.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Uživatelé",
"Admin" => "Administrace",
"Failed to upgrade \"%s\"." => "Selhala aktualizace verze \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Vlastní profilové obrázky zatím nefungují v kombinaci se šifrováním",
+"Unknown filetype" => "Neznámý typ souboru",
+"Invalid image" => "Chybný obrázek",
"web services under your control" => "webové služby pod Vaší kontrolou",
"cannot open \"%s\"" => "nelze otevřít \"%s\"",
"ZIP download is turned off." => "Stahování v ZIPu je vypnuto.",
diff --git a/lib/l10n/da.php b/lib/l10n/da.php
index 26903142763..05a43f42ed9 100644
--- a/lib/l10n/da.php
+++ b/lib/l10n/da.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Brugere",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Upgradering af \"%s\" fejlede",
+"Custom profile pictures don't work with encryption yet" => "Personligt profilbillede virker endnu ikke sammen med kryptering",
+"Unknown filetype" => "Ukendt filtype",
+"Invalid image" => "Ugyldigt billede",
"web services under your control" => "Webtjenester under din kontrol",
"cannot open \"%s\"" => "Kan ikke åbne \"%s\"",
"ZIP download is turned off." => "ZIP-download er slået fra.",
diff --git a/lib/l10n/de.php b/lib/l10n/de.php
index 7a3e2c43e6b..87e7a67b47b 100644
--- a/lib/l10n/de.php
+++ b/lib/l10n/de.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Benutzer",
"Admin" => "Administration",
"Failed to upgrade \"%s\"." => "Konnte \"%s\" nicht aktualisieren.",
+"Custom profile pictures don't work with encryption yet" => "Individuelle Profilbilder werden noch nicht von der Verschlüsselung unterstützt",
+"Unknown filetype" => "Unbekannter Dateityp",
+"Invalid image" => "Ungültiges Bild",
"web services under your control" => "Web-Services unter Deiner Kontrolle",
"cannot open \"%s\"" => "Öffnen von \"%s\" fehlgeschlagen",
"ZIP download is turned off." => "Der ZIP-Download ist deaktiviert.",
diff --git a/lib/l10n/de_DE.php b/lib/l10n/de_DE.php
index 0a72f443e4d..09be0eea22d 100644
--- a/lib/l10n/de_DE.php
+++ b/lib/l10n/de_DE.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Benutzer",
"Admin" => "Administrator",
"Failed to upgrade \"%s\"." => "Konnte \"%s\" nicht aktualisieren.",
+"Custom profile pictures don't work with encryption yet" => "Individuelle Profilbilder werden noch nicht von der Verschlüsselung unterstützt",
+"Unknown filetype" => "Unbekannter Dateityp",
+"Invalid image" => "Ungültiges Bild",
"web services under your control" => "Web-Services unter Ihrer Kontrolle",
"cannot open \"%s\"" => "Öffnen von \"%s\" fehlgeschlagen",
"ZIP download is turned off." => "Der ZIP-Download ist deaktiviert.",
diff --git a/lib/l10n/en_GB.php b/lib/l10n/en_GB.php
index f799c071c76..d02f553eda8 100644
--- a/lib/l10n/en_GB.php
+++ b/lib/l10n/en_GB.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Users",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Failed to upgrade \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Custom profile pictures don't work with encryption yet",
+"Unknown filetype" => "Unknown filetype",
+"Invalid image" => "Invalid image",
"web services under your control" => "web services under your control",
"cannot open \"%s\"" => "cannot open \"%s\"",
"ZIP download is turned off." => "ZIP download is turned off.",
@@ -54,13 +57,13 @@ $TRANSLATIONS = array(
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Your web server is not yet properly setup to allow files synchronisation because the WebDAV interface seems to be broken.",
"Please double check the <a href='%s'>installation guides</a>." => "Please double check the <a href='%s'>installation guides</a>.",
"seconds ago" => "seconds ago",
-"_%n minute ago_::_%n minutes ago_" => array("","%n minutes ago"),
-"_%n hour ago_::_%n hours ago_" => array("","%n hours ago"),
+"_%n minute ago_::_%n minutes ago_" => array("%n minute ago","%n minutes ago"),
+"_%n hour ago_::_%n hours ago_" => array("%n hour ago","%n hours ago"),
"today" => "today",
"yesterday" => "yesterday",
-"_%n day go_::_%n days ago_" => array("","%n days ago"),
+"_%n day go_::_%n days ago_" => array("%n day go","%n days ago"),
"last month" => "last month",
-"_%n month ago_::_%n months ago_" => array("","%n months ago"),
+"_%n month ago_::_%n months ago_" => array("%n month ago","%n months ago"),
"last year" => "last year",
"years ago" => "years ago",
"Caused by:" => "Caused by:",
diff --git a/lib/l10n/et_EE.php b/lib/l10n/et_EE.php
index 8e3aa55c4ed..85dfaeb52d5 100644
--- a/lib/l10n/et_EE.php
+++ b/lib/l10n/et_EE.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Kasutajad",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Ebaõnnestunud uuendus \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Kohandatud profiili pildid ei toimi veel koos krüpteeringuga",
+"Unknown filetype" => "Tundmatu failitüüp",
+"Invalid image" => "Vigane pilt",
"web services under your control" => "veebitenused sinu kontrolli all",
"cannot open \"%s\"" => "ei suuda avada \"%s\"",
"ZIP download is turned off." => "ZIP-ina allalaadimine on välja lülitatud.",
diff --git a/lib/l10n/fi_FI.php b/lib/l10n/fi_FI.php
index 2e69df43ad2..1d2bdab749c 100644
--- a/lib/l10n/fi_FI.php
+++ b/lib/l10n/fi_FI.php
@@ -1,11 +1,16 @@
<?php
$TRANSLATIONS = array(
"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Sovellusta \"%s\" ei voi asentaa, koska se ei ole yhteensopiva käytössä olevan ownCloud-version kanssa.",
+"No app name specified" => "Sovelluksen nimeä ei määritelty",
"Help" => "Ohje",
"Personal" => "Henkilökohtainen",
"Settings" => "Asetukset",
"Users" => "Käyttäjät",
"Admin" => "Ylläpitäjä",
+"Failed to upgrade \"%s\"." => "Kohteen \"%s\" päivitys epäonnistui.",
+"Custom profile pictures don't work with encryption yet" => "Omavalintaiset profiilikuvat eivät toimi salauksen kanssa vielä",
+"Unknown filetype" => "Tuntematon tiedostotyyppi",
+"Invalid image" => "Virheellinen kuva",
"web services under your control" => "verkkopalvelut hallinnassasi",
"ZIP download is turned off." => "ZIP-lataus on poistettu käytöstä.",
"Files need to be downloaded one by one." => "Tiedostot on ladattava yksittäin.",
@@ -15,6 +20,8 @@ $TRANSLATIONS = array(
"No path specified when installing app from local file" => "Polkua ei määritelty sovellusta asennettaessa paikallisesta tiedostosta",
"Archives of type %s are not supported" => "Tyypin %s arkistot eivät ole tuettuja",
"App does not provide an info.xml file" => "Sovellus ei sisällä info.xml-tiedostoa",
+"App can't be installed because of not allowed code in the App" => "Sovellusta ei voi asentaa, koska sovellus sisältää kiellettyä koodia",
+"App can't be installed because it is not compatible with this version of ownCloud" => "Sovellusta ei voi asentaa, koska se ei ole yhteensopiva käytössä olevan ownCloud-version kanssa",
"App directory already exists" => "Sovelluskansio on jo olemassa",
"Can't create app folder. Please fix permissions. %s" => "Sovelluskansion luominen ei onnistu. Korjaa käyttöoikeudet. %s",
"Application is not enabled" => "Sovellusta ei ole otettu käyttöön",
diff --git a/lib/l10n/fr.php b/lib/l10n/fr.php
index da3ec4ce372..ab3d618849e 100644
--- a/lib/l10n/fr.php
+++ b/lib/l10n/fr.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Utilisateurs",
"Admin" => "Administration",
"Failed to upgrade \"%s\"." => "Echec de la mise à niveau \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Les images de profil personnalisées ne fonctionnent pas encore avec le système de chiffrement.",
+"Unknown filetype" => "Type de fichier inconnu",
+"Invalid image" => "Image invalide",
"web services under your control" => "services web sous votre contrôle",
"cannot open \"%s\"" => "impossible d'ouvrir \"%s\"",
"ZIP download is turned off." => "Téléchargement ZIP désactivé.",
diff --git a/lib/l10n/gl.php b/lib/l10n/gl.php
index a8fee3b1bc1..406272d690f 100644
--- a/lib/l10n/gl.php
+++ b/lib/l10n/gl.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Usuarios",
"Admin" => "Administración",
"Failed to upgrade \"%s\"." => "Non foi posíbel anovar «%s».",
+"Custom profile pictures don't work with encryption yet" => "As imaxes personalizadas de perfil aínda non funcionan co cifrado",
+"Unknown filetype" => "Tipo de ficheiro descoñecido",
+"Invalid image" => "Imaxe incorrecta",
"web services under your control" => "servizos web baixo o seu control",
"cannot open \"%s\"" => "non foi posíbel abrir «%s»",
"ZIP download is turned off." => "As descargas ZIP están desactivadas.",
diff --git a/lib/l10n/it.php b/lib/l10n/it.php
index c3a040048ec..b00789bc86f 100644
--- a/lib/l10n/it.php
+++ b/lib/l10n/it.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Utenti",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Aggiornamento non riuscito \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Le immagini personalizzate del profilo non funzionano ancora con la cifratura",
+"Unknown filetype" => "Tipo di file sconosciuto",
+"Invalid image" => "Immagine non valida",
"web services under your control" => "servizi web nelle tue mani",
"cannot open \"%s\"" => "impossibile aprire \"%s\"",
"ZIP download is turned off." => "Lo scaricamento in formato ZIP è stato disabilitato.",
diff --git a/lib/l10n/ja_JP.php b/lib/l10n/ja_JP.php
index 2d37001ca19..b9e6a0e6924 100644
--- a/lib/l10n/ja_JP.php
+++ b/lib/l10n/ja_JP.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "ユーザ",
"Admin" => "管理",
"Failed to upgrade \"%s\"." => "\"%s\" へのアップグレードに失敗しました。",
+"Custom profile pictures don't work with encryption yet" => "暗号無しでは利用不可なカスタムプロフィール画像",
+"Unknown filetype" => "不明なファイルタイプ",
+"Invalid image" => "無効な画像",
"web services under your control" => "管理下のウェブサービス",
"cannot open \"%s\"" => "\"%s\" が開けません",
"ZIP download is turned off." => "ZIPダウンロードは無効です。",
diff --git a/lib/l10n/lt_LT.php b/lib/l10n/lt_LT.php
index 1fd9b9ea634..db8d96c1018 100644
--- a/lib/l10n/lt_LT.php
+++ b/lib/l10n/lt_LT.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Vartotojai",
"Admin" => "Administravimas",
"Failed to upgrade \"%s\"." => "Nepavyko pakelti „%s“ versijos.",
+"Custom profile pictures don't work with encryption yet" => "Saviti profilio paveiksliukai dar neveikia su šifravimu",
+"Unknown filetype" => "Nežinomas failo tipas",
+"Invalid image" => "Netinkamas paveikslėlis",
"web services under your control" => "jūsų valdomos web paslaugos",
"cannot open \"%s\"" => "nepavyksta atverti „%s“",
"ZIP download is turned off." => "ZIP atsisiuntimo galimybė yra išjungta.",
diff --git a/lib/l10n/nl.php b/lib/l10n/nl.php
index e546c1f3179..20374f1f0f8 100644
--- a/lib/l10n/nl.php
+++ b/lib/l10n/nl.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "App \"%s\" kan niet worden geïnstalleerd omdat die niet compatible is met deze versie van ownCloud.",
"No app name specified" => "De app naam is niet gespecificeerd.",
"Help" => "Help",
"Personal" => "Persoonlijk",
@@ -7,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Gebruikers",
"Admin" => "Beheerder",
"Failed to upgrade \"%s\"." => "Upgrade \"%s\" mislukt.",
+"Custom profile pictures don't work with encryption yet" => "Maatwerk profielafbeelding werkt nog niet met versleuteling",
+"Unknown filetype" => "Onbekend bestandsformaat",
+"Invalid image" => "Ongeldige afbeelding",
"web services under your control" => "Webdiensten in eigen beheer",
"cannot open \"%s\"" => "Kon \"%s\" niet openen",
"ZIP download is turned off." => "ZIP download is uitgeschakeld.",
@@ -14,6 +18,18 @@ $TRANSLATIONS = array(
"Back to Files" => "Terug naar bestanden",
"Selected files too large to generate zip file." => "De geselecteerde bestanden zijn te groot om een zip bestand te maken.",
"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Download de bestanden in kleinere brokken, appart of vraag uw administrator.",
+"No source specified when installing app" => "Geen bron opgegeven bij installatie van de app",
+"No href specified when installing app from http" => "Geen href opgegeven bij installeren van de app vanaf http",
+"No path specified when installing app from local file" => "Geen pad opgegeven bij installeren van de app vanaf een lokaal bestand",
+"Archives of type %s are not supported" => "Archiefbestanden van type %s niet ondersteund",
+"Failed to open archive when installing app" => "Kon archiefbestand bij installatie van de app niet openen",
+"App does not provide an info.xml file" => "De app heeft geen info.xml bestand",
+"App can't be installed because of not allowed code in the App" => "De app kan niet worden geïnstalleerd wegens onjuiste code in de app",
+"App can't be installed because it is not compatible with this version of ownCloud" => "De app kan niet worden geïnstalleerd omdat die niet compatible is met deze versie van ownCloud",
+"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "De app kan niet worden geïnstallerd omdat het de <shipped>true</shipped> tag bevat die niet is toegestaan voor niet gepubliceerde apps",
+"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "De app kan niet worden geïnstalleerd omdat de versie in info.xml/version niet dezelfde is als de versie zoals die in de app store staat vermeld",
+"App directory already exists" => "App directory bestaat al",
+"Can't create app folder. Please fix permissions. %s" => "Kan de app map niet aanmaken, Herstel de permissies. %s",
"Application is not enabled" => "De applicatie is niet actief",
"Authentication error" => "Authenticatie fout",
"Token expired. Please reload page." => "Token verlopen. Herlaad de pagina.",
diff --git a/lib/l10n/nn_NO.php b/lib/l10n/nn_NO.php
index d5da8c64415..e8bf8dfdef4 100644
--- a/lib/l10n/nn_NO.php
+++ b/lib/l10n/nn_NO.php
@@ -5,6 +5,8 @@ $TRANSLATIONS = array(
"Settings" => "Innstillingar",
"Users" => "Brukarar",
"Admin" => "Administrer",
+"Unknown filetype" => "Ukjend filtype",
+"Invalid image" => "Ugyldig bilete",
"web services under your control" => "Vev tjenester under din kontroll",
"Authentication error" => "Feil i autentisering",
"Files" => "Filer",
diff --git a/lib/l10n/pa.php b/lib/l10n/pa.php
new file mode 100644
index 00000000000..069fea6e710
--- /dev/null
+++ b/lib/l10n/pa.php
@@ -0,0 +1,16 @@
+<?php
+$TRANSLATIONS = array(
+"Settings" => "ਸੈਟਿੰਗ",
+"Files" => "ਫਾਇਲਾਂ",
+"seconds ago" => "ਸਕਿੰਟ ਪਹਿਲਾਂ",
+"_%n minute ago_::_%n minutes ago_" => array("",""),
+"_%n hour ago_::_%n hours ago_" => array("",""),
+"today" => "ਅੱਜ",
+"yesterday" => "ਕੱਲ੍ਹ",
+"_%n day go_::_%n days ago_" => array("",""),
+"last month" => "ਪਿਛਲੇ ਮਹੀਨੇ",
+"_%n month ago_::_%n months ago_" => array("",""),
+"last year" => "ਪਿਛਲੇ ਸਾਲ",
+"years ago" => "ਸਾਲਾਂ ਪਹਿਲਾਂ"
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/pt_BR.php b/lib/l10n/pt_BR.php
index 72bc1f36a1e..7a580799701 100644
--- a/lib/l10n/pt_BR.php
+++ b/lib/l10n/pt_BR.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Usuários",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Falha na atualização de \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Fotos de perfil personalizados ainda não funcionam com criptografia",
+"Unknown filetype" => "Tipo de arquivo desconhecido",
+"Invalid image" => "Imagem inválida",
"web services under your control" => "serviços web sob seu controle",
"cannot open \"%s\"" => "não pode abrir \"%s\"",
"ZIP download is turned off." => "Download ZIP está desligado.",
diff --git a/lib/l10n/pt_PT.php b/lib/l10n/pt_PT.php
index bf540012249..6e2bcba7b10 100644
--- a/lib/l10n/pt_PT.php
+++ b/lib/l10n/pt_PT.php
@@ -6,6 +6,8 @@ $TRANSLATIONS = array(
"Users" => "Utilizadores",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "A actualização \"%s\" falhou.",
+"Unknown filetype" => "Ficheiro desconhecido",
+"Invalid image" => "Imagem inválida",
"web services under your control" => "serviços web sob o seu controlo",
"cannot open \"%s\"" => "Não foi possível abrir \"%s\"",
"ZIP download is turned off." => "Descarregamento em ZIP está desligado.",
diff --git a/lib/l10n/ro.php b/lib/l10n/ro.php
index b338b349239..76dafcd03e0 100644
--- a/lib/l10n/ro.php
+++ b/lib/l10n/ro.php
@@ -5,6 +5,8 @@ $TRANSLATIONS = array(
"Settings" => "Setări",
"Users" => "Utilizatori",
"Admin" => "Admin",
+"Unknown filetype" => "Tip fișier necunoscut",
+"Invalid image" => "Imagine invalidă",
"web services under your control" => "servicii web controlate de tine",
"ZIP download is turned off." => "Descărcarea ZIP este dezactivată.",
"Files need to be downloaded one by one." => "Fișierele trebuie descărcate unul câte unul.",
@@ -19,11 +21,11 @@ $TRANSLATIONS = array(
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Serverul de web nu este încă setat corespunzător pentru a permite sincronizarea fișierelor deoarece interfața WebDAV pare a fi întreruptă.",
"Please double check the <a href='%s'>installation guides</a>." => "Vă rugăm să verificați <a href='%s'>ghiduri de instalare</a>.",
"seconds ago" => "secunde în urmă",
-"_%n minute ago_::_%n minutes ago_" => array("","",""),
-"_%n hour ago_::_%n hours ago_" => array("","",""),
+"_%n minute ago_::_%n minutes ago_" => array("","","acum %n minute"),
+"_%n hour ago_::_%n hours ago_" => array("","","acum %n ore"),
"today" => "astăzi",
"yesterday" => "ieri",
-"_%n day go_::_%n days ago_" => array("","",""),
+"_%n day go_::_%n days ago_" => array("","","acum %n zile"),
"last month" => "ultima lună",
"_%n month ago_::_%n months ago_" => array("","",""),
"last year" => "ultimul an",
diff --git a/lib/l10n/ru.php b/lib/l10n/ru.php
index c3b6a077b72..501065f8b5f 100644
--- a/lib/l10n/ru.php
+++ b/lib/l10n/ru.php
@@ -1,11 +1,16 @@
<?php
$TRANSLATIONS = array(
+"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Приложение \"%s\" нельзя установить, так как оно не совместимо с текущей версией ownCloud.",
+"No app name specified" => "Не выбрано имя приложения",
"Help" => "Помощь",
"Personal" => "Личное",
"Settings" => "Конфигурация",
"Users" => "Пользователи",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Не смог обновить \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Пользовательские картинки профиля ещё не поддерживают шифрование",
+"Unknown filetype" => "Неизвестный тип файла",
+"Invalid image" => "Изображение повреждено",
"web services under your control" => "веб-сервисы под вашим управлением",
"cannot open \"%s\"" => "не могу открыть \"%s\"",
"ZIP download is turned off." => "ZIP-скачивание отключено.",
@@ -13,6 +18,18 @@ $TRANSLATIONS = array(
"Back to Files" => "Назад к файлам",
"Selected files too large to generate zip file." => "Выбранные файлы слишком велики, чтобы создать zip файл.",
"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Загрузите файл маленьшими порциями, раздельно или вежливо попросите Вашего администратора.",
+"No source specified when installing app" => "Не указан источник при установке приложения",
+"No href specified when installing app from http" => "Не указан атрибут href при установке приложения через http",
+"No path specified when installing app from local file" => "Не указан путь при установке приложения из локального файла",
+"Archives of type %s are not supported" => "Архивы %s не поддерживаются",
+"Failed to open archive when installing app" => "Не возможно открыть архив при установке приложения",
+"App does not provide an info.xml file" => "Приложение не имеет файла info.xml",
+"App can't be installed because of not allowed code in the App" => "Приложение невозможно установить. В нем содержится запрещенный код.",
+"App can't be installed because it is not compatible with this version of ownCloud" => "Приложение невозможно установить. Не совместимо с текущей версией ownCloud.",
+"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Приложение невозможно установить. Оно содержит параметр <shipped>true</shipped> который не допустим для приложений, не входящих в поставку.",
+"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Приложение невозможно установить. Версия в info.xml/version не совпадает с версией заявленной в магазине приложений",
+"App directory already exists" => "Папка приложения уже существует",
+"Can't create app folder. Please fix permissions. %s" => "Не удалось создать директорию. Исправьте права доступа. %s",
"Application is not enabled" => "Приложение не разрешено",
"Authentication error" => "Ошибка аутентификации",
"Token expired. Please reload page." => "Токен просрочен. Перезагрузите страницу.",
diff --git a/lib/l10n/sr@latin.php b/lib/l10n/sr@latin.php
index 5ba51bc0ba7..d8fa9289221 100644
--- a/lib/l10n/sr@latin.php
+++ b/lib/l10n/sr@latin.php
@@ -8,9 +8,15 @@ $TRANSLATIONS = array(
"Authentication error" => "Greška pri autentifikaciji",
"Files" => "Fajlovi",
"Text" => "Tekst",
+"seconds ago" => "Pre par sekundi",
"_%n minute ago_::_%n minutes ago_" => array("","",""),
"_%n hour ago_::_%n hours ago_" => array("","",""),
+"today" => "Danas",
+"yesterday" => "juče",
"_%n day go_::_%n days ago_" => array("","",""),
-"_%n month ago_::_%n months ago_" => array("","","")
+"last month" => "prošlog meseca",
+"_%n month ago_::_%n months ago_" => array("","",""),
+"last year" => "prošle godine",
+"years ago" => "pre nekoliko godina"
);
$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/legacy/preferences.php b/lib/legacy/preferences.php
new file mode 100644
index 00000000000..a663db7598b
--- /dev/null
+++ b/lib/legacy/preferences.php
@@ -0,0 +1,146 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Frank Karlitschek
+ * @author Jakob Sack
+ * @copyright 2012 Frank Karlitschek frank@owncloud.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * This class provides an easy way for storing user preferences.
+ */
+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
+ *
+ * This function returns a list of all users that have at least one entry
+ * in the preferences table.
+ */
+ public static function getUsers() {
+ return self::$object->getUsers();
+ }
+
+ /**
+ * @brief Get all apps of a user
+ * @param string $user user
+ * @return array with app ids
+ *
+ * This function returns a list of all apps of the user that have at least
+ * one entry in the preferences table.
+ */
+ public static function getApps( $user ) {
+ return self::$object->getApps( $user );
+ }
+
+ /**
+ * @brief 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
+ *
+ * This function gets all keys of an app of an user. Please note that the
+ * values are not returned.
+ */
+ public static function getKeys( $user, $app ) {
+ return self::$object->getKeys( $user, $app );
+ }
+
+ /**
+ * @brief Gets the preference
+ * @param string $user user
+ * @param string $app app
+ * @param string $key key
+ * @param string $default = null, default value if the key does not exist
+ * @return string the value or $default
+ *
+ * This function gets a value from the preferences table. If the key does
+ * not exist the default value will be returned
+ */
+ public static function getValue( $user, $app, $key, $default = null ) {
+ return self::$object->getValue( $user, $app, $key, $default );
+ }
+
+ /**
+ * @brief sets a value in the preferences
+ * @param string $user user
+ * @param string $app app
+ * @param string $key key
+ * @param string $value value
+ * @return bool
+ *
+ * Adds a value to the preferences. If the key did not exist before, it
+ * will be added automagically.
+ */
+ public static function setValue( $user, $app, $key, $value ) {
+ self::$object->setValue( $user, $app, $key, $value );
+ return true;
+ }
+
+ /**
+ * @brief Deletes a key
+ * @param string $user user
+ * @param string $app app
+ * @param string $key key
+ *
+ * Deletes a key.
+ */
+ public static function deleteKey( $user, $app, $key ) {
+ self::$object->deleteKey( $user, $app, $key );
+ return true;
+ }
+
+ /**
+ * @brief Remove app of user from preferences
+ * @param string $user user
+ * @param string $app app
+ * @return bool
+ *
+ * Removes all keys in preferences belonging to the app and the user.
+ */
+ public static function deleteApp( $user, $app ) {
+ self::$object->deleteApp( $user, $app );
+ return true;
+ }
+
+ /**
+ * @brief Remove user from preferences
+ * @param string $user user
+ * @return bool
+ *
+ * Removes all keys in preferences belonging to the user.
+ */
+ public static function deleteUser( $user ) {
+ self::$object->deleteUser( $user );
+ return true;
+ }
+
+ /**
+ * @brief Remove app from all users
+ * @param string $app app
+ * @return bool
+ *
+ * Removes all keys in preferences belonging to the app.
+ */
+ public static function deleteAppFromAllUsers( $app ) {
+ self::$object->deleteAppFromAllUsers( $app );
+ return true;
+ }
+}
diff --git a/lib/navigationmanager.php b/lib/navigationmanager.php
new file mode 100644
index 00000000000..1f657b9ad80
--- /dev/null
+++ b/lib/navigationmanager.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OC;
+
+/**
+ * Manages the ownCloud navigation
+ */
+class NavigationManager implements \OCP\INavigationManager {
+ protected $entries = array();
+ protected $activeEntry;
+
+ /**
+ * Creates a new navigation entry
+ * @param array $entry containing: id, name, order, icon and href key
+ */
+ public function add(array $entry) {
+ $entry['active'] = false;
+ if(!isset($entry['icon'])) {
+ $entry['icon'] = '';
+ }
+ $this->entries[] = $entry;
+ }
+
+ /**
+ * @brief returns all the added Menu entries
+ * @return array of the added entries
+ */
+ public function getAll() {
+ return $this->entries;
+ }
+
+ /**
+ * @brief removes all the entries
+ */
+ public function clear() {
+ $this->entries = array();
+ }
+
+ /**
+ * Sets the current navigation entry of the currently running app
+ * @param string $id of the app entry to activate (from added $entry)
+ */
+ public function setActiveEntry($id) {
+ $this->activeEntry = $id;
+ }
+
+ /**
+ * @brief gets the active Menu entry
+ * @return string id or empty string
+ *
+ * This function returns the id of the active navigation entry (set by
+ * setActiveEntry
+ */
+ public function getActiveEntry() {
+ return $this->activeEntry;
+ }
+}
diff --git a/lib/preferences.php b/lib/preferences.php
index 11ca760830e..359d9a83589 100644
--- a/lib/preferences.php
+++ b/lib/preferences.php
@@ -34,10 +34,21 @@
*
*/
+namespace OC;
+
+use \OC\DB\Connection;
+
+
/**
* This class provides an easy way for storing user preferences.
*/
-class OC_Preferences{
+class Preferences {
+ protected $conn;
+
+ public function __construct(Connection $conn) {
+ $this->conn = $conn;
+ }
+
/**
* @brief Get all users using the preferences
* @return array with user ids
@@ -45,14 +56,13 @@ class OC_Preferences{
* This function returns a list of all users that have at least one entry
* in the preferences table.
*/
- public static function getUsers() {
- // No need for more comments
- $query = OC_DB::prepare( 'SELECT DISTINCT( `userid` ) FROM `*PREFIX*preferences`' );
- $result = $query->execute();
+ public function getUsers() {
+ $query = 'SELECT DISTINCT `userid` FROM `*PREFIX*preferences`';
+ $result = $this->conn->executeQuery( $query );
$users = array();
- while( $row = $result->fetchRow()) {
- $users[] = $row["userid"];
+ while( $userid = $result->fetchColumn()) {
+ $users[] = $userid;
}
return $users;
@@ -66,14 +76,13 @@ class OC_Preferences{
* This function returns a list of all apps of the user that have at least
* one entry in the preferences table.
*/
- public static function getApps( $user ) {
- // No need for more comments
- $query = OC_DB::prepare( 'SELECT DISTINCT( `appid` ) FROM `*PREFIX*preferences` WHERE `userid` = ?' );
- $result = $query->execute( array( $user ));
+ public function getApps( $user ) {
+ $query = 'SELECT DISTINCT `appid` FROM `*PREFIX*preferences` WHERE `userid` = ?';
+ $result = $this->conn->executeQuery( $query, array( $user ) );
$apps = array();
- while( $row = $result->fetchRow()) {
- $apps[] = $row["appid"];
+ while( $appid = $result->fetchColumn()) {
+ $apps[] = $appid;
}
return $apps;
@@ -88,14 +97,13 @@ class OC_Preferences{
* This function gets all keys of an app of an user. Please note that the
* values are not returned.
*/
- public static function getKeys( $user, $app ) {
- // No need for more comments
- $query = OC_DB::prepare( 'SELECT `configkey` FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ?' );
- $result = $query->execute( array( $user, $app ));
+ public function getKeys( $user, $app ) {
+ $query = 'SELECT `configkey` FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ?';
+ $result = $this->conn->executeQuery( $query, array( $user, $app ));
$keys = array();
- while( $row = $result->fetchRow()) {
- $keys[] = $row["configkey"];
+ while( $key = $result->fetchColumn()) {
+ $keys[] = $key;
}
return $keys;
@@ -112,16 +120,14 @@ class OC_Preferences{
* This function gets a value from the preferences table. If the key does
* not exist the default value will be returned
*/
- public static function getValue( $user, $app, $key, $default = null ) {
+ public function getValue( $user, $app, $key, $default = null ) {
// Try to fetch the value, return default if not exists.
- $query = OC_DB::prepare( 'SELECT `configvalue` FROM `*PREFIX*preferences`'
- .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?' );
- $result = $query->execute( array( $user, $app, $key ));
-
- $row = $result->fetchRow();
+ $query = 'SELECT `configvalue` FROM `*PREFIX*preferences`'
+ .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?';
+ $row = $this->conn->fetchAssoc( $query, array( $user, $app, $key ));
if($row) {
return $row["configvalue"];
- }else{
+ } else {
return $default;
}
}
@@ -132,29 +138,36 @@ class OC_Preferences{
* @param string $app app
* @param string $key key
* @param string $value value
- * @return bool
*
* Adds a value to the preferences. If the key did not exist before, it
* will be added automagically.
*/
- public static function setValue( $user, $app, $key, $value ) {
+ public function setValue( $user, $app, $key, $value ) {
// Check if the key does exist
- $query = OC_DB::prepare( 'SELECT `configvalue` FROM `*PREFIX*preferences`'
- .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?' );
- $values=$query->execute(array($user, $app, $key))->fetchAll();
- $exists=(count($values)>0);
+ $query = 'SELECT COUNT(*) FROM `*PREFIX*preferences`'
+ .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?';
+ $count = $this->conn->fetchColumn( $query, array( $user, $app, $key ));
+ $exists = $count > 0;
if( !$exists ) {
- $query = OC_DB::prepare( 'INSERT INTO `*PREFIX*preferences`'
- .' ( `userid`, `appid`, `configkey`, `configvalue` ) VALUES( ?, ?, ?, ? )' );
- $query->execute( array( $user, $app, $key, $value ));
+ $data = array(
+ 'userid' => $user,
+ 'appid' => $app,
+ 'configkey' => $key,
+ 'configvalue' => $value,
+ );
+ $this->conn->insert('*PREFIX*preferences', $data);
+ } else {
+ $data = array(
+ 'configvalue' => $value,
+ );
+ $where = array(
+ 'userid' => $user,
+ 'appid' => $app,
+ 'configkey' => $key,
+ );
+ $this->conn->update('*PREFIX*preferences', $data, $where);
}
- else{
- $query = OC_DB::prepare( 'UPDATE `*PREFIX*preferences` SET `configvalue` = ?'
- .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?' );
- $query->execute( array( $value, $user, $app, $key ));
- }
- return true;
}
/**
@@ -162,62 +175,58 @@ class OC_Preferences{
* @param string $user user
* @param string $app app
* @param string $key key
- * @return bool
*
* Deletes a key.
*/
- public static function deleteKey( $user, $app, $key ) {
- // No need for more comments
- $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*preferences`'
- .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?' );
- $query->execute( array( $user, $app, $key ));
-
- return true;
+ public function deleteKey( $user, $app, $key ) {
+ $where = array(
+ 'userid' => $user,
+ 'appid' => $app,
+ 'configkey' => $key,
+ );
+ $this->conn->delete('*PREFIX*preferences', $where);
}
/**
* @brief Remove app of user from preferences
* @param string $user user
* @param string $app app
- * @return bool
*
- * Removes all keys in appconfig belonging to the app and the user.
+ * Removes all keys in preferences belonging to the app and the user.
*/
- public static function deleteApp( $user, $app ) {
- // No need for more comments
- $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ?' );
- $query->execute( array( $user, $app ));
-
- return true;
+ public function deleteApp( $user, $app ) {
+ $where = array(
+ 'userid' => $user,
+ 'appid' => $app,
+ );
+ $this->conn->delete('*PREFIX*preferences', $where);
}
/**
* @brief Remove user from preferences
* @param string $user user
- * @return bool
*
- * Removes all keys in appconfig belonging to the user.
+ * Removes all keys in preferences belonging to the user.
*/
- public static function deleteUser( $user ) {
- // No need for more comments
- $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*preferences` WHERE `userid` = ?' );
- $query->execute( array( $user ));
-
- return true;
+ public function deleteUser( $user ) {
+ $where = array(
+ 'userid' => $user,
+ );
+ $this->conn->delete('*PREFIX*preferences', $where);
}
/**
* @brief Remove app from all users
* @param string $app app
- * @return bool
*
* Removes all keys in preferences belonging to the app.
*/
- public static function deleteAppFromAllUsers( $app ) {
- // No need for more comments
- $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*preferences` WHERE `appid` = ?' );
- $query->execute( array( $app ));
-
- return true;
+ public function deleteAppFromAllUsers( $app ) {
+ $where = array(
+ 'appid' => $app,
+ );
+ $this->conn->delete('*PREFIX*preferences', $where);
}
}
+
+require_once __DIR__.'/legacy/'.basename(__FILE__);
diff --git a/lib/public/app.php b/lib/public/app.php
index a1ecf524cc8..0a5721b334e 100644
--- a/lib/public/app.php
+++ b/lib/public/app.php
@@ -35,10 +35,10 @@ namespace OCP;
*/
class App {
/**
- * @brief Makes owncloud aware of this app
+ * @brief Makes ownCloud aware of this app
* @brief This call is deprecated and not necessary to use.
* @param $data array with all information
- * @returns true/false
+ * @returns boolean
*
* @deprecated this method is deprecated
* Do not call it anymore
@@ -52,7 +52,7 @@ class App {
/**
* @brief adds an entry to the navigation
* @param $data array containing the data
- * @returns true/false
+ * @returns boolean
*
* This function adds a new entry to the navigation visible to users. $data
* is an associative array.
@@ -72,8 +72,8 @@ class App {
/**
* @brief marks a navigation entry as active
- * @param $id id of the entry
- * @returns true/false
+ * @param $id string id of the entry
+ * @returns boolean
*
* This function sets a navigation entry as active and removes the 'active'
* property from all other entries. The templates can use this for
@@ -104,7 +104,7 @@ class App {
/**
* @brief Read app metadata from the info.xml file
* @param string $app id of the app or the path of the info.xml file
- * @param boolean path (optional)
+ * @param boolean $path (optional)
* @returns array
*/
public static function getAppInfo( $app, $path=false ) {
@@ -114,7 +114,7 @@ class App {
/**
* @brief checks whether or not an app is enabled
* @param $app app
- * @returns true/false
+ * @returns boolean
*
* This function checks whether or not an app is enabled.
*/
@@ -133,7 +133,7 @@ class App {
/**
* @brief Get the last version of the app, either from appinfo/version or from appinfo/info.xml
* @param $app app
- * @returns true/false
+ * @returns boolean
*/
public static function getAppVersion( $app ) {
return \OC_App::getAppVersion( $app );
diff --git a/lib/public/appframework/iapi.php b/lib/public/appframework/iapi.php
index 5374f0dcaf5..fa6af5f5965 100644
--- a/lib/public/appframework/iapi.php
+++ b/lib/public/appframework/iapi.php
@@ -30,19 +30,6 @@ namespace OCP\AppFramework;
*/
interface IApi {
- /**
- * used to return the appname of the set application
- * @return string the name of your application
- */
- function getAppName();
-
-
- /**
- * Creates a new navigation entry
- * @param array $entry containing: id, name, order, icon and href key
- */
- function addNavigationEntry(array $entry);
-
/**
* Gets the userid of the current user
@@ -52,12 +39,6 @@ interface IApi {
/**
- * Sets the current navigation entry to the currently running app
- */
- function activateNavigationEntry();
-
-
- /**
* Adds a new javascript file
* @param string $scriptName the name of the javascript in js/ without the suffix
* @param string $appName the name of the app, defaults to the current one
@@ -87,53 +68,6 @@ interface IApi {
function add3rdPartyStyle($name);
/**
- * Looks up a system-wide defined value
- * @param string $key the key of the value, under which it was saved
- * @return string the saved value
- */
- function getSystemValue($key);
-
- /**
- * Sets a new system-wide value
- * @param string $key the key of the value, under which will be saved
- * @param string $value the value that should be stored
- */
- function setSystemValue($key, $value);
-
-
- /**
- * Looks up an app-specific defined value
- * @param string $key the key of the value, under which it was saved
- * @return string the saved value
- */
- function getAppValue($key, $appName = null);
-
-
- /**
- * Writes a new app-specific value
- * @param string $key the key of the value, under which will be saved
- * @param string $value the value that should be stored
- */
- function setAppValue($key, $value, $appName = null);
-
-
- /**
- * Shortcut for setting a user defined value
- * @param string $key the key under which the value is being stored
- * @param string $value the value that you want to store
- * @param string $userId the userId of the user that we want to store the value under, defaults to the current one
- */
- function setUserValue($key, $value, $userId = null);
-
-
- /**
- * Shortcut for getting a user defined value
- * @param string $key the key under which the value is being stored
- * @param string $userId the userId of the user that we want to store the value under, defaults to the current one
- */
- function getUserValue($key, $userId = null);
-
- /**
* Returns the translation object
* @return \OC_L10N the translation object
*
@@ -143,28 +77,6 @@ interface IApi {
/**
- * 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 \OCP\DB a query object
- *
- * FIXME: returns non public interface / object
- */
- function prepareQuery($sql, $limit=null, $offset=null);
-
-
- /**
- * 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
- *
- * FIXME: move to db object
- */
- function getInsertId($tableName);
-
-
- /**
* Returns the URL for a route
* @param string $routeName the name of the route
* @param array $arguments an array with arguments which will be filled into the url
@@ -235,4 +147,5 @@ interface IApi {
* @return \OCP\Template a new template
*/
function getTemplate($templateName, $renderAs='user', $appName=null);
+
}
diff --git a/lib/public/appframework/iappcontainer.php b/lib/public/appframework/iappcontainer.php
index c8f6229dd9e..7d3b4b3bac7 100644
--- a/lib/public/appframework/iappcontainer.php
+++ b/lib/public/appframework/iappcontainer.php
@@ -34,6 +34,12 @@ use OCP\IContainer;
interface IAppContainer extends IContainer{
/**
+ * used to return the appname of the set application
+ * @return string the name of your application
+ */
+ function getAppName();
+
+ /**
* @return IApi
*/
function getCoreApi();
@@ -42,4 +48,10 @@ interface IAppContainer extends IContainer{
* @return \OCP\IServerContainer
*/
function getServer();
+
+ /**
+ * @param IMiddleWare $middleWare
+ * @return boolean
+ */
+ function registerMiddleWare(IMiddleWare $middleWare);
}
diff --git a/lib/public/iconfig.php b/lib/public/iconfig.php
new file mode 100644
index 00000000000..850bddf6935
--- /dev/null
+++ b/lib/public/iconfig.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OCP;
+
+/**
+ * Access to all the configuration options ownCloud offers
+ */
+interface IConfig {
+ /**
+ * Sets a new system wide value
+ * @param string $key the key of the value, under which will be saved
+ * @param string $value the value that should be stored
+ * @todo need a use case for this
+ */
+// public function setSystemValue($key, $value);
+
+ /**
+ * Looks up a system wide defined value
+ * @param string $key the key of the value, under which it was saved
+ * @return string the saved value
+ */
+ public function getSystemValue($key);
+
+
+ /**
+ * Writes a new app wide value
+ * @param string $appName the appName that we want to store the value under
+ * @param string $key the key of the value, under which will be saved
+ * @param string $value the value that should be stored
+ */
+ public function setAppValue($appName, $key, $value);
+
+ /**
+ * Looks up an app wide defined value
+ * @param string $appName the appName that we stored the value under
+ * @param string $key the key of the value, under which it was saved
+ * @return string the saved value
+ */
+ public function getAppValue($appName, $key);
+
+
+ /**
+ * Set a user defined value
+ * @param string $userId the userId of the user that we want to store the value under
+ * @param string $appName the appName that we want to store the value under
+ * @param string $key the key under which the value is being stored
+ * @param string $value the value that you want to store
+ */
+ public function setUserValue($userId, $appName, $key, $value);
+
+ /**
+ * Shortcut for getting a user defined value
+ * @param string $userId the userId of the user that we want to store the value under
+ * @param string $appName the appName that we stored the value under
+ * @param string $key the key under which the value is being stored
+ */
+ public function getUserValue($userId, $appName, $key);
+}
diff --git a/lib/public/idbconnection.php b/lib/public/idbconnection.php
new file mode 100644
index 00000000000..c741a0f061a
--- /dev/null
+++ b/lib/public/idbconnection.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OCP;
+
+/**
+ * TODO: Description
+ */
+interface IDBConnection {
+ /**
+ * 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 \Doctrine\DBAL\Driver\Statement The prepared statement.
+ */
+ public function prepare($sql, $limit=null, $offset=null);
+
+ /**
+ * Used to get the id of the just inserted element
+ * @param string $tableName the name of the table where we inserted the item
+ * @return int the id of the inserted element
+ */
+ public function lastInsertId($table = null);
+
+ /**
+ * @brief Insert a row if a matching row doesn't exists.
+ * @param $table string The table name (will replace *PREFIX*) to perform the replace on.
+ * @param $input array
+ *
+ * The input array if in the form:
+ *
+ * array ( 'id' => array ( 'value' => 6,
+ * 'key' => true
+ * ),
+ * 'name' => array ('value' => 'Stoyan'),
+ * 'family' => array ('value' => 'Stefanov'),
+ * 'birth_date' => array ('value' => '1975-06-20')
+ * );
+ * @return bool
+ *
+ */
+ public function insertIfNotExist($table, $input);
+
+ /**
+ * @brief Start a transaction
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function beginTransaction();
+
+ /**
+ * @brief Commit the database changes done during a transaction that is in progress
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function commit();
+
+ /**
+ * @brief Rollback the database changes done during a transaction that is in progress
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function rollBack();
+
+ /**
+ * returns the error code and message as a string for logging
+ * @return string
+ */
+ public function getError();
+}
diff --git a/lib/public/inavigationmanager.php b/lib/public/inavigationmanager.php
new file mode 100644
index 00000000000..f89e790c1d0
--- /dev/null
+++ b/lib/public/inavigationmanager.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OCP;
+
+/**
+ * Manages the ownCloud navigation
+ */
+interface INavigationManager {
+ /**
+ * Creates a new navigation entry
+ * @param array $entry containing: id, name, order, icon and href key
+ */
+ public function add(array $entry);
+
+ /**
+ * Sets the current navigation entry of the currently running app
+ * @param string $appId id of the app entry to activate (from added $entry)
+ */
+ public function setActiveEntry($appId);
+}
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index 41def099691..287b8e9d902 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -56,6 +56,14 @@ interface IServerContainer {
function getPreviewManager();
/**
+ * Returns the tag manager which can get and set tags for different object types
+ *
+ * @see \OCP\ITagManager::load()
+ * @return \OCP\ITagManager
+ */
+ function getTagManager();
+
+ /**
* Returns the root folder of ownCloud's data directory
*
* @return \OCP\Files\Folder
@@ -63,6 +71,37 @@ interface IServerContainer {
function getRootFolder();
/**
+ * Returns a view to ownCloud's files folder
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getUserFolder();
+
+ /**
+ * Returns an app-specific view in ownClouds data directory
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getAppFolder();
+
+ /**
+ * Returns the user session
+ *
+ * @return \OCP\IUserSession
+ */
+ function getUserSession();
+
+ /**
+ * @return \OCP\INavigationManager
+ */
+ function getNavigationManager();
+
+ /**
+ * @return \OCP\IConfig
+ */
+ function getConfig();
+
+ /**
* Returns an ICache instance
*
* @return \OCP\ICache
@@ -83,4 +122,11 @@ interface IServerContainer {
*/
function getActivityManager();
+ /**
+ * Returns the current session
+ *
+ * @return \OCP\IDBConnection
+ */
+ function getDatabaseConnection();
+
}
diff --git a/lib/public/itagmanager.php b/lib/public/itagmanager.php
new file mode 100644
index 00000000000..07e1d12fc0f
--- /dev/null
+++ b/lib/public/itagmanager.php
@@ -0,0 +1,48 @@
+<?php
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2013 Thomas Tanghus <thomas@tanghus.net>
+*
+* 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/>.
+*
+*/
+
+/**
+ * Factory class creating instances of \OCP\ITags
+ *
+ * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
+ * anything else that is either parsed from a vobject or that the user chooses
+ * to add.
+ * Tag names are not case-sensitive, but will be saved with the case they
+ * are entered in. If a user already has a tag 'family' for a type, and
+ * tries to add a tag named 'Family' it will be silently ignored.
+ */
+
+namespace OCP;
+
+interface ITagManager {
+
+ /**
+ * Create a new \OCP\ITags instance and load tags from db.
+ *
+ * @see \OCP\ITags
+ * @param string $type The type identifier e.g. 'contact' or 'event'.
+ * @param array $defaultTags An array of default tags to be used if none are stored.
+ * @return \OCP\ITags
+ */
+ public function load($type, $defaultTags=array());
+
+} \ No newline at end of file
diff --git a/lib/public/itags.php b/lib/public/itags.php
new file mode 100644
index 00000000000..5b1ebd189da
--- /dev/null
+++ b/lib/public/itags.php
@@ -0,0 +1,164 @@
+<?php
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2013 Thomas Tanghus <thomas@tanghus.net>
+*
+* 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 OCP;
+
+// FIXME: Where should I put this? Or should it be implemented as a Listener?
+\OC_Hook::connect('OC_User', 'post_deleteUser', 'OC\Tags', 'post_deleteUser');
+
+/**
+ * Class for easily tagging objects by their id
+ *
+ * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
+ * anything else that is either parsed from a vobject or that the user chooses
+ * to add.
+ * Tag names are not case-sensitive, but will be saved with the case they
+ * are entered in. If a user already has a tag 'family' for a type, and
+ * tries to add a tag named 'Family' it will be silently ignored.
+ */
+
+interface ITags {
+
+ /**
+ * Check if any tags are saved for this type and user.
+ *
+ * @return boolean.
+ */
+ public function isEmpty();
+
+ /**
+ * Get the tags for a specific user.
+ *
+ * This returns an array with id/name maps:
+ * [
+ * ['id' => 0, 'name' = 'First tag'],
+ * ['id' => 1, 'name' = 'Second tag'],
+ * ]
+ *
+ * @returns array
+ */
+ public function getTags();
+
+ /**
+ * Get the a list if items tagged with $tag.
+ *
+ * Throws an exception if the tag could not be found.
+ *
+ * @param string|integer $tag Tag id or name.
+ * @return array An array of object ids or false on error.
+ */
+ public function getIdsForTag($tag);
+
+ /**
+ * Checks whether a tag is already saved.
+ *
+ * @param string $name The name to check for.
+ * @return bool
+ */
+ public function hasTag($name);
+
+ /**
+ * Add a new tag.
+ *
+ * @param string $name A string with a name of the tag
+ * @return int the id of the added tag or false if it already exists.
+ */
+ public function add($name);
+
+ /**
+ * Rename tag.
+ *
+ * @param string $from The name of the existing tag
+ * @param string $to The new name of the tag.
+ * @return bool
+ */
+ public function rename($from, $to);
+
+ /**
+ * Add a list of new tags.
+ *
+ * @param string[] $names A string with a name or an array of strings containing
+ * the name(s) of the to add.
+ * @param bool $sync When true, save the tags
+ * @param int|null $id int Optional object id to add to this|these tag(s)
+ * @return bool Returns false on error.
+ */
+ public function addMultiple($names, $sync=false, $id = null);
+
+ /**
+ * Delete tag/object relations from the db
+ *
+ * @param array $ids The ids of the objects
+ * @return boolean Returns false on error.
+ */
+ public function purgeObjects(array $ids);
+
+ /**
+ * Get favorites for an object type
+ *
+ * @return array An array of object ids.
+ */
+ public function getFavorites();
+
+ /**
+ * Add an object to favorites
+ *
+ * @param int $objid The id of the object
+ * @return boolean
+ */
+ public function addToFavorites($objid);
+
+ /**
+ * Remove an object from favorites
+ *
+ * @param int $objid The id of the object
+ * @return boolean
+ */
+ public function removeFromFavorites($objid);
+
+ /**
+ * Creates a tag/object relation.
+ *
+ * @param int $objid The id of the object
+ * @param int|string $tag The id or name of the tag
+ * @return boolean Returns false on database error.
+ */
+ public function tagAs($objid, $tag);
+
+ /**
+ * Delete single tag/object relation from the db
+ *
+ * @param int $objid The id of the object
+ * @param int|string $tag The id or name of the tag
+ * @return boolean
+ */
+ public function unTag($objid, $tag);
+
+ /**
+ * Delete tags from the
+ *
+ * @param string[] $names An array of tags to delete
+ * @return bool Returns false on error
+ */
+ public function delete($names);
+
+} \ No newline at end of file
diff --git a/lib/public/iusersession.php b/lib/public/iusersession.php
new file mode 100644
index 00000000000..5dc1ecf71e6
--- /dev/null
+++ b/lib/public/iusersession.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OCP;
+
+/**
+ * User session
+ */
+interface IUserSession {
+ /**
+ * Do a user login
+ * @param string $user the username
+ * @param string $password the password
+ * @return bool true if successful
+ */
+ public function login($user, $password);
+
+ /**
+ * @brief Logs the user out including all the session data
+ * Logout, destroys session
+ */
+ public function logout();
+
+}
diff --git a/lib/public/share.php b/lib/public/share.php
index 9ab956d84b9..6c5783f1179 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -106,22 +106,22 @@ class Share {
}
return false;
}
-
+
/**
* @brief Prepare a path to be passed to DB as file_target
* @return string Prepared path
*/
public static function prepFileTarget( $path ) {
-
+
// Paths in DB are stored with leading slashes, so add one if necessary
if ( substr( $path, 0, 1 ) !== '/' ) {
-
+
$path = '/' . $path;
-
+
}
-
+
return $path;
-
+
}
/**
@@ -256,7 +256,7 @@ class Share {
return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
$parameters, 1, $includeCollections);
}
-
+
/**
* @brief Get the item of item type shared with the current user by source
* @param string Item type
@@ -293,7 +293,18 @@ class Share {
if (\OC_DB::isError($result)) {
\OC_Log::write('OCP\Share', \OC_DB::getErrorMessage($result) . ', token=' . $token, \OC_Log::ERROR);
}
- return $result->fetchRow();
+ $row = $result->fetchRow();
+
+ if (!empty($row['expiration'])) {
+ $now = new \DateTime();
+ $expirationDate = new \DateTime($row['expiration'], new \DateTimeZone('UTC'));
+ if ($now > $expirationDate) {
+ self::delete($row['id']);
+ return false;
+ }
+ }
+
+ return $row;
}
/**
@@ -450,6 +461,7 @@ class Share {
$uidOwner, self::FORMAT_NONE, null, 1)) {
// remember old token
$oldToken = $checkExists['token'];
+ $oldPermissions = $checkExists['permissions'];
//delete the old share
self::delete($checkExists['id']);
}
@@ -460,8 +472,11 @@ class Share {
$hasher = new \PasswordHash(8, $forcePortable);
$shareWith = $hasher->HashPassword($shareWith.\OC_Config::getValue('passwordsalt', ''));
} else {
- // reuse the already set password
- $shareWith = $checkExists['share_with'];
+ // reuse the already set password, but only if we change permissions
+ // otherwise the user disabled the password protection
+ if ($checkExists && (int)$permissions !== (int)$oldPermissions) {
+ $shareWith = $checkExists['share_with'];
+ }
}
// Generate token
@@ -745,10 +760,10 @@ class Share {
/**
* @brief Get the backend class for the specified item type
- * @param string Item type
- * @return Sharing backend object
+ * @param string $itemType
+ * @return Share_Backend
*/
- private static function getBackend($itemType) {
+ public static function getBackend($itemType) {
if (isset(self::$backends[$itemType])) {
return self::$backends[$itemType];
} else if (isset(self::$backendTypes[$itemType]['class'])) {
diff --git a/lib/public/user.php b/lib/public/user.php
index 23ff991642d..576a64d7048 100644
--- a/lib/public/user.php
+++ b/lib/public/user.php
@@ -102,7 +102,7 @@ class User {
* @brief Check if the password is correct
* @param $uid The username
* @param $password The password
- * @returns true/false
+ * @returns mixed username on success, false otherwise
*
* Check if the password is correct without logging in the user
*/
diff --git a/lib/search/provider/file.php b/lib/search/provider/file.php
index 4d88c2a87f1..9bd50931517 100644
--- a/lib/search/provider/file.php
+++ b/lib/search/provider/file.php
@@ -10,6 +10,7 @@ class OC_Search_Provider_File extends OC_Search_Provider{
$mime = $fileData['mimetype'];
$name = basename($path);
+ $container = dirname($path);
$text = '';
$skip = false;
if($mime=='httpd/unix-directory') {
@@ -37,7 +38,7 @@ class OC_Search_Provider_File extends OC_Search_Provider{
}
}
if(!$skip) {
- $results[] = new OC_Search_Result($name, $text, $link, $type);
+ $results[] = new OC_Search_Result($name, $text, $link, $type, $container);
}
}
return $results;
diff --git a/lib/search/result.php b/lib/search/result.php
index 08beaea151c..42275c2df11 100644
--- a/lib/search/result.php
+++ b/lib/search/result.php
@@ -7,6 +7,7 @@ class OC_Search_Result{
public $text;
public $link;
public $type;
+ public $container;
/**
* create a new search result
@@ -15,10 +16,11 @@ class OC_Search_Result{
* @param string $link link for the result
* @param string $type the type of result as human readable string ('File', 'Music', etc)
*/
- public function __construct($name, $text, $link, $type) {
+ public function __construct($name, $text, $link, $type, $container) {
$this->name=$name;
$this->text=$text;
$this->link=$link;
$this->type=$type;
+ $this->container=$container;
}
}
diff --git a/lib/server.php b/lib/server.php
index f4dc22a2be4..cabb15324ec 100644
--- a/lib/server.php
+++ b/lib/server.php
@@ -4,6 +4,7 @@ namespace OC;
use OC\AppFramework\Http\Request;
use OC\AppFramework\Utility\SimpleContainer;
+use OC\Cache\UserCache;
use OC\Files\Node\Root;
use OC\Files\View;
use OCP\IServerContainer;
@@ -24,7 +25,7 @@ class Server extends SimpleContainer implements IServerContainer {
$params = array();
// we json decode the body only in case of content type json
- if (isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'],'json') === true ) {
+ if (isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'],'json') !== false ) {
$params = json_decode(file_get_contents('php://input'), true);
$params = is_array($params) ? $params: array();
}
@@ -48,14 +49,68 @@ class Server extends SimpleContainer implements IServerContainer {
$this->registerService('PreviewManager', function($c) {
return new PreviewManager();
});
+ $this->registerService('TagManager', function($c) {
+ $user = \OC_User::getUser();
+ return new TagManager($user);
+ });
$this->registerService('RootFolder', function($c) {
// TODO: get user and user manager from container as well
$user = \OC_User::getUser();
- $user = \OC_User::getManager()->get($user);
+ /** @var $c SimpleContainer */
+ $userManager = $c->query('UserManager');
+ $user = $userManager->get($user);
$manager = \OC\Files\Filesystem::getMountManager();
$view = new View();
return new Root($manager, $view, $user);
});
+ $this->registerService('UserManager', function($c) {
+ return new \OC\User\Manager();
+ });
+ $this->registerService('UserSession', function($c) {
+ /** @var $c SimpleContainer */
+ $manager = $c->query('UserManager');
+ $userSession = new \OC\User\Session($manager, \OC::$session);
+ $userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
+ \OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
+ });
+ $userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password));
+ });
+ $userSession->listen('\OC\User', 'preDelete', function ($user) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID()));
+ });
+ $userSession->listen('\OC\User', 'postDelete', function ($user) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID()));
+ });
+ $userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
+ });
+ $userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
+ });
+ $userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
+ \OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password));
+ });
+ $userSession->listen('\OC\User', 'postLogin', function ($user, $password) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
+ });
+ $userSession->listen('\OC\User', 'logout', function () {
+ \OC_Hook::emit('OC_User', 'logout', array());
+ });
+ return $userSession;
+ });
+ $this->registerService('NavigationManager', function($c) {
+ return new \OC\NavigationManager();
+ });
+ $this->registerService('AllConfig', function($c) {
+ return new \OC\AllConfig();
+ });
$this->registerService('UserCache', function($c) {
return new UserCache();
});
@@ -89,6 +144,16 @@ class Server extends SimpleContainer implements IServerContainer {
}
/**
+ * Returns the tag manager which can get and set tags for different object types
+ *
+ * @see \OCP\ITagManager::load()
+ * @return \OCP\ITagManager
+ */
+ function getTagManager() {
+ return $this->query('TagManager');
+ }
+
+ /**
* Returns the root folder of ownCloud's data directory
*
* @return \OCP\Files\Folder
@@ -98,6 +163,70 @@ class Server extends SimpleContainer implements IServerContainer {
}
/**
+ * Returns a view to ownCloud's files folder
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getUserFolder() {
+
+ $dir = '/files';
+ $root = $this->getRootFolder();
+ $folder = null;
+ if(!$root->nodeExists($dir)) {
+ $folder = $root->newFolder($dir);
+ } else {
+ $folder = $root->get($dir);
+ }
+ return $folder;
+ }
+
+ /**
+ * Returns an app-specific view in ownClouds data directory
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getAppFolder() {
+
+ $dir = '/' . \OC_App::getCurrentApp();
+ $root = $this->getRootFolder();
+ $folder = null;
+ if(!$root->nodeExists($dir)) {
+ $folder = $root->newFolder($dir);
+ } else {
+ $folder = $root->get($dir);
+ }
+ return $folder;
+ }
+
+ /**
+ * @return \OC\User\Manager
+ */
+ function getUserManager() {
+ return $this->query('UserManager');
+ }
+
+ /**
+ * @return \OC\User\Session
+ */
+ function getUserSession() {
+ return $this->query('UserSession');
+ }
+
+ /**
+ * @return \OC\NavigationManager
+ */
+ function getNavigationManager() {
+ return $this->query('NavigationManager');
+ }
+
+ /**
+ * @return \OC\Config
+ */
+ function getConfig() {
+ return $this->query('AllConfig');
+ }
+
+ /**
* Returns an ICache instance
*
* @return \OCP\ICache
@@ -115,4 +244,12 @@ class Server extends SimpleContainer implements IServerContainer {
return \OC::$session;
}
+ /**
+ * Returns the current session
+ *
+ * @return \OCP\IDBConnection
+ */
+ function getDatabaseConnection() {
+ return \OC_DB::getConnection();
+ }
}
diff --git a/lib/tagmanager.php b/lib/tagmanager.php
new file mode 100644
index 00000000000..9a371a11253
--- /dev/null
+++ b/lib/tagmanager.php
@@ -0,0 +1,68 @@
+<?php
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2013 Thomas Tanghus <thomas@tanghus.net>
+*
+* 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/>.
+*
+*/
+
+/**
+ * Factory class creating instances of \OCP\ITags
+ *
+ * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
+ * anything else that is either parsed from a vobject or that the user chooses
+ * to add.
+ * Tag names are not case-sensitive, but will be saved with the case they
+ * are entered in. If a user already has a tag 'family' for a type, and
+ * tries to add a tag named 'Family' it will be silently ignored.
+ */
+
+namespace OC;
+
+class TagManager implements \OCP\ITagManager {
+
+ /**
+ * User
+ *
+ * @var string
+ */
+ private $user = null;
+
+ /**
+ * Constructor.
+ *
+ * @param string $user The user whos data the object will operate on.
+ */
+ public function __construct($user) {
+
+ $this->user = $user;
+
+ }
+
+ /**
+ * Create a new \OCP\ITags instance and load tags from db.
+ *
+ * @see \OCP\ITags
+ * @param string $type The type identifier e.g. 'contact' or 'event'.
+ * @param array $defaultTags An array of default tags to be used if none are stored.
+ * @return \OCP\ITags
+ */
+ public function load($type, $defaultTags=array()) {
+ return new Tags($this->user, $type, $defaultTags);
+ }
+
+} \ No newline at end of file
diff --git a/lib/tags.php b/lib/tags.php
new file mode 100644
index 00000000000..9fdb35a7d6e
--- /dev/null
+++ b/lib/tags.php
@@ -0,0 +1,642 @@
+<?php
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2012-2013 Thomas Tanghus <thomas@tanghus.net>
+* @copyright 2012 Bart Visscher bartv@thisnet.nl
+*
+* 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/>.
+*
+*/
+
+/**
+ * Class for easily tagging objects by their id
+ *
+ * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
+ * anything else that is either parsed from a vobject or that the user chooses
+ * to add.
+ * Tag names are not case-sensitive, but will be saved with the case they
+ * are entered in. If a user already has a tag 'family' for a type, and
+ * tries to add a tag named 'Family' it will be silently ignored.
+ */
+
+namespace OC;
+
+class Tags implements \OCP\ITags {
+
+ /**
+ * Tags
+ *
+ * @var array
+ */
+ private $tags = array();
+
+ /**
+ * Used for storing objectid/categoryname pairs while rescanning.
+ *
+ * @var array
+ */
+ private static $relations = array();
+
+ /**
+ * Type
+ *
+ * @var string
+ */
+ private $type = null;
+
+ /**
+ * User
+ *
+ * @var string
+ */
+ private $user = null;
+
+ const TAG_TABLE = '*PREFIX*vcategory';
+ const RELATION_TABLE = '*PREFIX*vcategory_to_object';
+
+ const TAG_FAVORITE = '_$!<Favorite>!$_';
+
+ /**
+ * Constructor.
+ *
+ * @param string $user The user whos data the object will operate on.
+ */
+ public function __construct($user, $type, $defaultTags = array()) {
+ $this->user = $user;
+ $this->type = $type;
+ $this->loadTags($defaultTags);
+ }
+
+ /**
+ * Load tags from db.
+ *
+ * @param string $type The type identifier e.g. 'contact' or 'event'.
+ * @param array $defaultTags An array of default tags to be used if none are stored.
+ */
+ protected function loadTags($defaultTags=array()) {
+ $this->tags = array();
+ $result = null;
+ $sql = 'SELECT `id`, `category` FROM `' . self::TAG_TABLE . '` '
+ . 'WHERE `uid` = ? AND `type` = ? ORDER BY `category`';
+ 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);
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+
+ if(!is_null($result)) {
+ while( $row = $result->fetchRow()) {
+ $this->tags[$row['id']] = $row['category'];
+ }
+ }
+
+ if(count($defaultTags) > 0 && count($this->tags) === 0) {
+ $this->addMultiple($defaultTags, true);
+ }
+ \OCP\Util::writeLog('core', __METHOD__.', tags: ' . print_r($this->tags, true),
+ \OCP\Util::DEBUG);
+
+ }
+
+ /**
+ * Check if any tags are saved for this type and user.
+ *
+ * @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;
+ }
+ }
+
+ /**
+ * Get the tags for a specific user.
+ *
+ * This returns an array with id/name maps:
+ * [
+ * ['id' => 0, 'name' = 'First tag'],
+ * ['id' => 1, 'name' = 'Second tag'],
+ * ]
+ *
+ * @return array
+ */
+ public function getTags() {
+ if(!count($this->tags)) {
+ return array();
+ }
+
+ $tags = array_values($this->tags);
+ uasort($tags, 'strnatcasecmp');
+ $tagMap = array();
+
+ foreach($tags as $tag) {
+ if($tag !== self::TAG_FAVORITE) {
+ $tagMap[] = array(
+ 'id' => $this->array_searchi($tag, $this->tags),
+ 'name' => $tag
+ );
+ }
+ }
+ return $tagMap;
+
+ }
+
+ /**
+ * Get the a list if items tagged with $tag.
+ *
+ * Throws an exception if the tag could not be found.
+ *
+ * @param string|integer $tag Tag id or name.
+ * @return array An array of object ids or false on error.
+ */
+ public function getIdsForTag($tag) {
+ $result = null;
+ if(is_numeric($tag)) {
+ $tagId = $tag;
+ } elseif(is_string($tag)) {
+ $tag = trim($tag);
+ $tagId = $this->array_searchi($tag, $this->tags);
+ }
+
+ if($tagId === false) {
+ $l10n = \OC_L10N::get('core');
+ throw new \Exception(
+ $l10n->t('Could not find category "%s"', $tag)
+ );
+ }
+
+ $ids = array();
+ $sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE
+ . '` WHERE `categoryid` = ?';
+
+ try {
+ $stmt = \OCP\DB::prepare($sql);
+ $result = $stmt->execute(array($tagId));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+
+ if(!is_null($result)) {
+ while( $row = $result->fetchRow()) {
+ $ids[] = (int)$row['objid'];
+ }
+ }
+
+ return $ids;
+ }
+
+ /**
+ * Checks whether a tag is already saved.
+ *
+ * @param string $name The name to check for.
+ * @return bool
+ */
+ public function hasTag($name) {
+ return $this->in_arrayi($name, $this->tags);
+ }
+
+ /**
+ * Add a new tag.
+ *
+ * @param string $name A string with a name of the tag
+ * @return int the id of the added tag or false if it already exists.
+ */
+ public function add($name) {
+ $name = trim($name);
+
+ if($this->hasTag($name)) {
+ \OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', \OCP\Util::DEBUG);
+ return false;
+ }
+ try {
+ $result = \OCP\DB::insertIfNotExist(
+ self::TAG_TABLE,
+ array(
+ 'uid' => $this->user,
+ 'type' => $this->type,
+ 'category' => $name,
+ )
+ );
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ } elseif((int)$result === 0) {
+ \OCP\Util::writeLog('core', __METHOD__.', Tag already exists: ' . $name, \OCP\Util::DEBUG);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ $id = \OCP\DB::insertid(self::TAG_TABLE);
+ \OCP\Util::writeLog('core', __METHOD__.', id: ' . $id, \OCP\Util::DEBUG);
+ $this->tags[$id] = $name;
+ return $id;
+ }
+
+ /**
+ * Rename tag.
+ *
+ * @param string $from The name of the existing tag
+ * @param string $to The new name of the tag.
+ * @return bool
+ */
+ public function rename($from, $to) {
+ $from = trim($from);
+ $to = trim($to);
+ $id = $this->array_searchi($from, $this->tags);
+ if($id === false) {
+ \OCP\Util::writeLog('core', __METHOD__.', tag: ' . $from. ' does not exist', \OCP\Util::DEBUG);
+ return false;
+ }
+
+ $sql = 'UPDATE `' . self::TAG_TABLE . '` SET `category` = ? '
+ . 'WHERE `uid` = ? AND `type` = ? AND `id` = ?';
+ try {
+ $stmt = \OCP\DB::prepare($sql);
+ $result = $stmt->execute(array($to, $this->user, $this->type, $id));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ $this->tags[$id] = $to;
+ return true;
+ }
+
+ /**
+ * Add a list of new tags.
+ *
+ * @param string[] $names A string with a name or an array of strings containing
+ * the name(s) of the to add.
+ * @param bool $sync When true, save the tags
+ * @param int|null $id int Optional object id to add to this|these tag(s)
+ * @return bool Returns false on error.
+ */
+ public function addMultiple($names, $sync=false, $id = null) {
+ if(!is_array($names)) {
+ $names = array($names);
+ }
+ $names = array_map('trim', $names);
+ $newones = array();
+ foreach($names as $name) {
+ if(($this->in_arrayi(
+ $name, $this->tags) == false) && $name !== '') {
+ $newones[] = $name;
+ }
+ if(!is_null($id) ) {
+ // Insert $objectid, $categoryid pairs if not exist.
+ self::$relations[] = array('objid' => $id, 'tag' => $name);
+ }
+ }
+ $this->tags = array_merge($this->tags, $newones);
+ if($sync === true) {
+ $this->save();
+ }
+
+ return true;
+ }
+
+ /**
+ * Save the list of tags and their object relations
+ */
+ protected function save() {
+ if(is_array($this->tags)) {
+ foreach($this->tags as $tag) {
+ try {
+ \OCP\DB::insertIfNotExist(self::TAG_TABLE,
+ array(
+ 'uid' => $this->user,
+ 'type' => $this->type,
+ 'category' => $tag,
+ ));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+ }
+ // reload tags to get the proper ids.
+ $this->loadTags();
+ // Loop through temporarily cached objectid/tagname pairs
+ // and save relations.
+ $tags = $this->tags;
+ // For some reason this is needed or array_search(i) will return 0..?
+ ksort($tags);
+ foreach(self::$relations as $relation) {
+ $tagId = $this->array_searchi($relation['tag'], $tags);
+ \OCP\Util::writeLog('core', __METHOD__ . 'catid, ' . $relation['tag'] . ' ' . $tagId, \OCP\Util::DEBUG);
+ if($tagId) {
+ try {
+ \OCP\DB::insertIfNotExist(self::RELATION_TABLE,
+ array(
+ 'objid' => $relation['objid'],
+ 'categoryid' => $tagId,
+ 'type' => $this->type,
+ ));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+ }
+ }
+ self::$relations = array(); // reset
+ } else {
+ \OCP\Util::writeLog('core', __METHOD__.', $this->tags is not an array! '
+ . print_r($this->tags, true), \OCP\Util::ERROR);
+ }
+ }
+
+ /**
+ * Delete tags and tag/object relations for a user.
+ *
+ * For hooking up on post_deleteUser
+ *
+ * @param array
+ */
+ public static function post_deleteUser($arguments) {
+ // Find all objectid/tagId pairs.
+ $result = null;
+ try {
+ $stmt = \OCP\DB::prepare('SELECT `id` FROM `' . self::TAG_TABLE . '` '
+ . 'WHERE `uid` = ?');
+ $result = $stmt->execute(array($arguments['uid']));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+
+ if(!is_null($result)) {
+ try {
+ $stmt = \OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` '
+ . 'WHERE `categoryid` = ?');
+ while( $row = $result->fetchRow()) {
+ try {
+ $stmt->execute(array($row['id']));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+ }
+ try {
+ $stmt = \OCP\DB::prepare('DELETE FROM `' . self::TAG_TABLE . '` '
+ . 'WHERE `uid` = ?');
+ $result = $stmt->execute(array($arguments['uid']));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__ . ', exception: '
+ . $e->getMessage(), \OCP\Util::ERROR);
+ }
+ }
+
+ /**
+ * Delete tag/object relations from the db
+ *
+ * @param array $ids The ids of the objects
+ * @return boolean Returns false on error.
+ */
+ public function purgeObjects(array $ids) {
+ if(count($ids) === 0) {
+ // job done ;)
+ return true;
+ }
+ $updates = $ids;
+ try {
+ $query = 'DELETE FROM `' . self::RELATION_TABLE . '` ';
+ $query .= 'WHERE `objid` IN (' . str_repeat('?,', count($ids)-1) . '?) ';
+ $query .= 'AND `type`= ?';
+ $updates[] = $this->type;
+ $stmt = \OCP\DB::prepare($query);
+ $result = $stmt->execute($updates);
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Get favorites for an object type
+ *
+ * @return array An array of object ids.
+ */
+ public function getFavorites() {
+ try {
+ return $this->getIdsForTag(self::TAG_FAVORITE);
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(),
+ \OCP\Util::ERROR);
+ return array();
+ }
+ }
+
+ /**
+ * Add an object to favorites
+ *
+ * @param int $objid The id of the object
+ * @return boolean
+ */
+ public function addToFavorites($objid) {
+ if(!$this->hasTag(self::TAG_FAVORITE)) {
+ $this->add(self::TAG_FAVORITE, true);
+ }
+ return $this->tagAs($objid, self::TAG_FAVORITE, $this->type);
+ }
+
+ /**
+ * Remove an object from favorites
+ *
+ * @param int $objid The id of the object
+ * @return boolean
+ */
+ public function removeFromFavorites($objid) {
+ return $this->unTag($objid, self::TAG_FAVORITE, $this->type);
+ }
+
+ /**
+ * Creates a tag/object relation.
+ *
+ * @param int $objid The id of the object
+ * @param int|string $tag The id or name of the tag
+ * @return boolean Returns false on database error.
+ */
+ public function tagAs($objid, $tag) {
+ if(is_string($tag) && !is_numeric($tag)) {
+ $tag = trim($tag);
+ if(!$this->hasTag($tag)) {
+ $this->add($tag, true);
+ }
+ $tagId = $this->array_searchi($tag, $this->tags);
+ } else {
+ $tagId = $tag;
+ }
+ try {
+ \OCP\DB::insertIfNotExist(self::RELATION_TABLE,
+ array(
+ 'objid' => $objid,
+ 'categoryid' => $tagId,
+ 'type' => $this->type,
+ ));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Delete single tag/object relation from the db
+ *
+ * @param int $objid The id of the object
+ * @param int|string $tag The id or name of the tag
+ * @return boolean
+ */
+ public function unTag($objid, $tag) {
+ if(is_string($tag) && !is_numeric($tag)) {
+ $tag = trim($tag);
+ $tagId = $this->array_searchi($tag, $this->tags);
+ } else {
+ $tagId = $tag;
+ }
+
+ try {
+ $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
+ . 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?';
+ $stmt = \OCP\DB::prepare($sql);
+ $stmt->execute(array($objid, $tagId, $this->type));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Delete tags from the
+ *
+ * @param string[] $names An array of tags to delete
+ * @return bool Returns false on error
+ */
+ public function delete($names) {
+ if(!is_array($names)) {
+ $names = array($names);
+ }
+
+ $names = array_map('trim', $names);
+
+ \OCP\Util::writeLog('core', __METHOD__ . ', before: '
+ . print_r($this->tags, true), \OCP\Util::DEBUG);
+ foreach($names as $name) {
+ $id = null;
+
+ if($this->hasTag($name)) {
+ $id = $this->array_searchi($name, $this->tags);
+ unset($this->tags[$id]);
+ }
+ try {
+ $stmt = \OCP\DB::prepare('DELETE FROM `' . self::TAG_TABLE . '` WHERE '
+ . '`uid` = ? AND `type` = ? AND `category` = ?');
+ $result = $stmt->execute(array($this->user, $this->type, $name));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__ . ', exception: '
+ . $e->getMessage(), \OCP\Util::ERROR);
+ return false;
+ }
+ if(!is_null($id) && $id !== false) {
+ try {
+ $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
+ . 'WHERE `categoryid` = ?';
+ $stmt = \OCP\DB::prepare($sql);
+ $result = $stmt->execute(array($id));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core',
+ __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ // case-insensitive in_array
+ private function in_arrayi($needle, $haystack) {
+ if(!is_array($haystack)) {
+ return false;
+ }
+ return in_array(strtolower($needle), array_map('strtolower', $haystack));
+ }
+
+ // case-insensitive array_search
+ private function array_searchi($needle, $haystack) {
+ if(!is_array($haystack)) {
+ return false;
+ }
+ return array_search(strtolower($needle), array_map('strtolower', $haystack));
+ }
+}
diff --git a/lib/user.php b/lib/user.php
index 0f6f40aec9a..15e807088b4 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -37,54 +37,15 @@
* logout()
*/
class OC_User {
- public static $userSession = null;
-
public static function getUserSession() {
- if (!self::$userSession) {
- $manager = new \OC\User\Manager();
- self::$userSession = new \OC\User\Session($manager, \OC::$session);
- self::$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
- \OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
- });
- self::$userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) {
- /** @var $user \OC\User\User */
- \OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password));
- });
- self::$userSession->listen('\OC\User', 'preDelete', function ($user) {
- /** @var $user \OC\User\User */
- \OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID()));
- });
- self::$userSession->listen('\OC\User', 'postDelete', function ($user) {
- /** @var $user \OC\User\User */
- \OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID()));
- });
- self::$userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) {
- /** @var $user \OC\User\User */
- OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
- });
- self::$userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) {
- /** @var $user \OC\User\User */
- OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
- });
- self::$userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
- \OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password));
- });
- self::$userSession->listen('\OC\User', 'postLogin', function ($user, $password) {
- /** @var $user \OC\User\User */
- \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
- });
- self::$userSession->listen('\OC\User', 'logout', function () {
- \OC_Hook::emit('OC_User', 'logout', array());
- });
- }
- return self::$userSession;
+ return OC::$server->getUserSession();
}
/**
* @return \OC\User\Manager
*/
public static function getManager() {
- return self::getUserSession()->getManager();
+ return OC::$server->getUserManager();
}
private static $_backends = array();
@@ -177,6 +138,7 @@ class OC_User {
* setup the configured backends in config.php
*/
public static function setupBackends() {
+ OC_App::loadApps(array('prelogin'));
$backends = OC_Config::getValue('user_backends', array());
foreach ($backends as $i => $config) {
$class = $config['class'];
@@ -410,22 +372,18 @@ class OC_User {
* @brief Check if the password is correct
* @param string $uid The username
* @param string $password The password
- * @return bool
+ * @return mixed user id a string on success, false otherwise
*
* Check if the password is correct without logging in the user
* returns the user id or false
*/
public static function checkPassword($uid, $password) {
- $user = self::getManager()->get($uid);
- if ($user) {
- if ($user->checkPassword($password)) {
- return $user->getUID();
- } else {
- return false;
- }
- } else {
- return false;
+ $manager = self::getManager();
+ $username = $manager->checkPassword($uid, $password);
+ if ($username !== false) {
+ return $username->getUID();
}
+ return false;
}
/**
diff --git a/lib/user/http.php b/lib/user/http.php
index 1e044ed4188..e99afe59ba7 100644
--- a/lib/user/http.php
+++ b/lib/user/http.php
@@ -79,7 +79,11 @@ class OC_User_HTTP extends OC_User_Backend {
curl_close($ch);
- return $status==200;
+ if($status === 200) {
+ return $uid;
+ }
+
+ return false;
}
/**
diff --git a/lib/user/manager.php b/lib/user/manager.php
index 8dc9bfe2729..13286bc28a4 100644
--- a/lib/user/manager.php
+++ b/lib/user/manager.php
@@ -119,6 +119,25 @@ class Manager extends PublicEmitter {
}
/**
+ * Check if the password is valid for the user
+ *
+ * @param $loginname
+ * @param $password
+ * @return mixed the User object on success, false otherwise
+ */
+ public function checkPassword($loginname, $password) {
+ foreach ($this->backends as $backend) {
+ if($backend->implementsActions(\OC_USER_BACKEND_CHECK_PASSWORD)) {
+ $uid = $backend->checkPassword($loginname, $password);
+ if ($uid !== false) {
+ return $this->getUserObject($uid, $backend);
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* search by user id
*
* @param string $pattern
diff --git a/lib/user/session.php b/lib/user/session.php
index 9a6c669e935..525c65ab8a1 100644
--- a/lib/user/session.php
+++ b/lib/user/session.php
@@ -27,7 +27,7 @@ use OC\Hooks\Emitter;
*
* @package OC\User
*/
-class Session implements Emitter {
+class Session implements Emitter, \OCP\IUserSession {
/**
* @var \OC\User\Manager $manager
*/
@@ -121,15 +121,16 @@ class Session implements Emitter {
*/
public function login($uid, $password) {
$this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
- $user = $this->manager->get($uid);
- if ($user) {
- $result = $user->checkPassword($password);
- if ($result and $user->isEnabled()) {
- $this->setUser($user);
- $this->manager->emit('\OC\User', 'postLogin', array($user, $password));
- return true;
- } else {
- return false;
+ $user = $this->manager->checkPassword($uid, $password);
+ if($user !== false) {
+ if (!is_null($user)) {
+ if ($user->isEnabled()) {
+ $this->setUser($user);
+ $this->manager->emit('\OC\User', 'postLogin', array($user, $password));
+ return true;
+ } else {
+ return false;
+ }
}
} else {
return false;
diff --git a/lib/user/user.php b/lib/user/user.php
index 8115c43198c..e5f842944f1 100644
--- a/lib/user/user.php
+++ b/lib/user/user.php
@@ -106,24 +106,6 @@ class User {
}
/**
- * Check if the password is valid for the user
- *
- * @param $password
- * @return bool
- */
- public function checkPassword($password) {
- if ($this->backend->implementsActions(\OC_USER_BACKEND_CHECK_PASSWORD)) {
- $result = $this->backend->checkPassword($this->uid, $password);
- if ($result !== false) {
- $this->uid = $result;
- }
- return !($result === false);
- } else {
- return false;
- }
- }
-
- /**
* Set the password of the user
*
* @param string $password
diff --git a/lib/vcategories.php b/lib/vcategories.php
deleted file mode 100644
index 84036958359..00000000000
--- a/lib/vcategories.php
+++ /dev/null
@@ -1,821 +0,0 @@
-<?php
-/**
-* ownCloud
-*
-* @author Thomas Tanghus
-* @copyright 2012 Thomas Tanghus <thomas@tanghus.net>
-* @copyright 2012 Bart Visscher bartv@thisnet.nl
-*
-* 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/>.
-*
-*/
-
-OC_Hook::connect('OC_User', 'post_deleteUser', 'OC_VCategories', 'post_deleteUser');
-
-/**
- * Class for easy access to categories in VCARD, VEVENT, VTODO and VJOURNAL.
- * A Category can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
- * anything else that is either parsed from a vobject or that the user chooses
- * to add.
- * Category names are not case-sensitive, but will be saved with the case they
- * are entered in. If a user already has a category 'family' for a type, and
- * tries to add a category named 'Family' it will be silently ignored.
- */
-class OC_VCategories {
-
- /**
- * Categories
- */
- private $categories = array();
-
- /**
- * Used for storing objectid/categoryname pairs while rescanning.
- */
- private static $relations = array();
-
- private $type = null;
- private $user = null;
-
- const CATEGORY_TABLE = '*PREFIX*vcategory';
- const RELATION_TABLE = '*PREFIX*vcategory_to_object';
-
- const CATEGORY_FAVORITE = '_$!<Favorite>!$_';
-
- const FORMAT_LIST = 0;
- const FORMAT_MAP = 1;
-
- /**
- * @brief Constructor.
- * @param $type The type identifier e.g. 'contact' or 'event'.
- * @param $user The user whos data the object will operate on. This
- * parameter should normally be omitted but to make an app able to
- * update categories for all users it is made possible to provide it.
- * @param $defcategories An array of default categories to be used if none is stored.
- */
- public function __construct($type, $user=null, $defcategories=array()) {
- $this->type = $type;
- $this->user = is_null($user) ? OC_User::getUser() : $user;
-
- $this->loadCategories();
- OCP\Util::writeLog('core', __METHOD__ . ', categories: '
- . print_r($this->categories, true),
- OCP\Util::DEBUG
- );
-
- if($defcategories && count($this->categories) === 0) {
- $this->addMulti($defcategories, true);
- }
- }
-
- /**
- * @brief Load categories from db.
- */
- private function loadCategories() {
- $this->categories = array();
- $result = null;
- $sql = 'SELECT `id`, `category` FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ? AND `type` = ? ORDER BY `category`';
- try {
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($this->user, $this->type));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
-
- if(!is_null($result)) {
- while( $row = $result->fetchRow()) {
- // The keys are prefixed because array_search wouldn't work otherwise :-/
- $this->categories[$row['id']] = $row['category'];
- }
- }
- OCP\Util::writeLog('core', __METHOD__.', categories: ' . print_r($this->categories, true),
- OCP\Util::DEBUG);
- }
-
-
- /**
- * @brief Check if any categories are saved for this type and user.
- * @returns boolean.
- * @param $type The type identifier e.g. 'contact' or 'event'.
- * @param $user The user whos categories will be checked. If not set current user will be used.
- */
- public static function isEmpty($type, $user = null) {
- $user = is_null($user) ? OC_User::getUser() : $user;
- $sql = 'SELECT COUNT(*) FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ? AND `type` = ?';
- try {
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($user, $type));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- return ($result->numRows() === 0);
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- }
-
- /**
- * @brief Get the categories for a specific user.
- * @param
- * @returns array containing the categories as strings.
- */
- public function categories($format = null) {
- if(!$this->categories) {
- return array();
- }
- $categories = array_values($this->categories);
- uasort($categories, 'strnatcasecmp');
- if($format == self::FORMAT_MAP) {
- $catmap = array();
- foreach($categories as $category) {
- if($category !== self::CATEGORY_FAVORITE) {
- $catmap[] = array(
- 'id' => $this->array_searchi($category, $this->categories),
- 'name' => $category
- );
- }
- }
- return $catmap;
- }
-
- // Don't add favorites to normal categories.
- $favpos = array_search(self::CATEGORY_FAVORITE, $categories);
- if($favpos !== false) {
- return array_splice($categories, $favpos);
- } else {
- return $categories;
- }
- }
-
- /**
- * Get the a list if items belonging to $category.
- *
- * Throws an exception if the category could not be found.
- *
- * @param string|integer $category Category id or name.
- * @returns array An array of object ids or false on error.
- */
- public function idsForCategory($category) {
- $result = null;
- if(is_numeric($category)) {
- $catid = $category;
- } elseif(is_string($category)) {
- $catid = $this->array_searchi($category, $this->categories);
- }
- OCP\Util::writeLog('core', __METHOD__.', category: '.$catid.' '.$category, OCP\Util::DEBUG);
- if($catid === false) {
- $l10n = OC_L10N::get('core');
- throw new Exception(
- $l10n->t('Could not find category "%s"', $category)
- );
- }
-
- $ids = array();
- $sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE
- . '` WHERE `categoryid` = ?';
-
- try {
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($catid));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
-
- if(!is_null($result)) {
- while( $row = $result->fetchRow()) {
- $ids[] = (int)$row['objid'];
- }
- }
-
- return $ids;
- }
-
- /**
- * Get the a list if items belonging to $category.
- *
- * Throws an exception if the category could not be found.
- *
- * @param string|integer $category Category id or name.
- * @param array $tableinfo Array in the form {'tablename' => table, 'fields' => ['field1', 'field2']}
- * @param int $limit
- * @param int $offset
- *
- * This generic method queries a table assuming that the id
- * field is called 'id' and the table name provided is in
- * the form '*PREFIX*table_name'.
- *
- * If the category name cannot be resolved an exception is thrown.
- *
- * TODO: Maybe add the getting permissions for objects?
- *
- * @returns array containing the resulting items or false on error.
- */
- public function itemsForCategory($category, $tableinfo, $limit = null, $offset = null) {
- $result = null;
- if(is_numeric($category)) {
- $catid = $category;
- } elseif(is_string($category)) {
- $catid = $this->array_searchi($category, $this->categories);
- }
- OCP\Util::writeLog('core', __METHOD__.', category: '.$catid.' '.$category, OCP\Util::DEBUG);
- if($catid === false) {
- $l10n = OC_L10N::get('core');
- throw new Exception(
- $l10n->t('Could not find category "%s"', $category)
- );
- }
- $fields = '';
- foreach($tableinfo['fields'] as $field) {
- $fields .= '`' . $tableinfo['tablename'] . '`.`' . $field . '`,';
- }
- $fields = substr($fields, 0, -1);
-
- $items = array();
- $sql = 'SELECT `' . self::RELATION_TABLE . '`.`categoryid`, ' . $fields
- . ' FROM `' . $tableinfo['tablename'] . '` JOIN `'
- . self::RELATION_TABLE . '` ON `' . $tableinfo['tablename']
- . '`.`id` = `' . self::RELATION_TABLE . '`.`objid` WHERE `'
- . self::RELATION_TABLE . '`.`categoryid` = ?';
-
- try {
- $stmt = OCP\DB::prepare($sql, $limit, $offset);
- $result = $stmt->execute(array($catid));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
-
- if(!is_null($result)) {
- while( $row = $result->fetchRow()) {
- $items[] = $row;
- }
- }
- //OCP\Util::writeLog('core', __METHOD__.', count: ' . count($items), OCP\Util::DEBUG);
- //OCP\Util::writeLog('core', __METHOD__.', sql: ' . $sql, OCP\Util::DEBUG);
-
- return $items;
- }
-
- /**
- * @brief Checks whether a category is already saved.
- * @param $name The name to check for.
- * @returns bool
- */
- public function hasCategory($name) {
- return $this->in_arrayi($name, $this->categories);
- }
-
- /**
- * @brief Add a new category.
- * @param $name A string with a name of the category
- * @returns int the id of the added category or false if it already exists.
- */
- public function add($name) {
- OCP\Util::writeLog('core', __METHOD__.', name: ' . $name, OCP\Util::DEBUG);
- if($this->hasCategory($name)) {
- OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', OCP\Util::DEBUG);
- return false;
- }
- try {
- OCP\DB::insertIfNotExist(self::CATEGORY_TABLE,
- array(
- 'uid' => $this->user,
- 'type' => $this->type,
- 'category' => $name,
- ));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- $id = OCP\DB::insertid(self::CATEGORY_TABLE);
- OCP\Util::writeLog('core', __METHOD__.', id: ' . $id, OCP\Util::DEBUG);
- $this->categories[$id] = $name;
- return $id;
- }
-
- /**
- * @brief Rename category.
- * @param string $from The name of the existing category
- * @param string $to The new name of the category.
- * @returns bool
- */
- public function rename($from, $to) {
- $id = $this->array_searchi($from, $this->categories);
- if($id === false) {
- OCP\Util::writeLog('core', __METHOD__.', category: ' . $from. ' does not exist', OCP\Util::DEBUG);
- return false;
- }
-
- $sql = 'UPDATE `' . self::CATEGORY_TABLE . '` SET `category` = ? '
- . 'WHERE `uid` = ? AND `type` = ? AND `id` = ?';
- try {
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($to, $this->user, $this->type, $id));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- $this->categories[$id] = $to;
- return true;
- }
-
- /**
- * @brief Add a new category.
- * @param $names A string with a name or an array of strings containing
- * the name(s) of the categor(y|ies) to add.
- * @param $sync bool When true, save the categories
- * @param $id int Optional object id to add to this|these categor(y|ies)
- * @returns bool Returns false on error.
- */
- public function addMulti($names, $sync=false, $id = null) {
- if(!is_array($names)) {
- $names = array($names);
- }
- $names = array_map('trim', $names);
- $newones = array();
- foreach($names as $name) {
- if(($this->in_arrayi(
- $name, $this->categories) == false) && $name != '') {
- $newones[] = $name;
- }
- if(!is_null($id) ) {
- // Insert $objectid, $categoryid pairs if not exist.
- self::$relations[] = array('objid' => $id, 'category' => $name);
- }
- }
- $this->categories = array_merge($this->categories, $newones);
- if($sync === true) {
- $this->save();
- }
-
- return true;
- }
-
- /**
- * @brief Extracts categories from a vobject and add the ones not already present.
- * @param $vobject The instance of OC_VObject to load the categories from.
- */
- public function loadFromVObject($id, $vobject, $sync=false) {
- $this->addMulti($vobject->getAsArray('CATEGORIES'), $sync, $id);
- }
-
- /**
- * @brief Reset saved categories and rescan supplied vobjects for categories.
- * @param $objects An array of vobjects (as text).
- * To get the object array, do something like:
- * // For Addressbook:
- * $categories = new OC_VCategories('contacts');
- * $stmt = OC_DB::prepare( 'SELECT `carddata` FROM `*PREFIX*contacts_cards`' );
- * $result = $stmt->execute();
- * $objects = array();
- * if(!is_null($result)) {
- * while( $row = $result->fetchRow()){
- * $objects[] = array($row['id'], $row['carddata']);
- * }
- * }
- * $categories->rescan($objects);
- */
- public function rescan($objects, $sync=true, $reset=true) {
-
- if($reset === true) {
- $result = null;
- // Find all objectid/categoryid pairs.
- try {
- $stmt = OCP\DB::prepare('SELECT `id` FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ? AND `type` = ?');
- $result = $stmt->execute(array($this->user, $this->type));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
-
- // And delete them.
- if(!is_null($result)) {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` '
- . 'WHERE `categoryid` = ? AND `type`= ?');
- while( $row = $result->fetchRow()) {
- $stmt->execute(array($row['id'], $this->type));
- }
- }
- try {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ? AND `type` = ?');
- $result = $stmt->execute(array($this->user, $this->type));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__ . ', exception: '
- . $e->getMessage(), OCP\Util::ERROR);
- return;
- }
- $this->categories = array();
- }
- // Parse all the VObjects
- foreach($objects as $object) {
- $vobject = OC_VObject::parse($object[1]);
- if(!is_null($vobject)) {
- // Load the categories
- $this->loadFromVObject($object[0], $vobject, $sync);
- } else {
- OC_Log::write('core', __METHOD__ . ', unable to parse. ID: ' . ', '
- . substr($object, 0, 100) . '(...)', OC_Log::DEBUG);
- }
- }
- $this->save();
- }
-
- /**
- * @brief Save the list with categories
- */
- private function save() {
- if(is_array($this->categories)) {
- foreach($this->categories as $category) {
- try {
- OCP\DB::insertIfNotExist(self::CATEGORY_TABLE,
- array(
- 'uid' => $this->user,
- 'type' => $this->type,
- 'category' => $category,
- ));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
- }
- // reload categories to get the proper ids.
- $this->loadCategories();
- // Loop through temporarily cached objectid/categoryname pairs
- // and save relations.
- $categories = $this->categories;
- // For some reason this is needed or array_search(i) will return 0..?
- ksort($categories);
- foreach(self::$relations as $relation) {
- $catid = $this->array_searchi($relation['category'], $categories);
- OC_Log::write('core', __METHOD__ . 'catid, ' . $relation['category'] . ' ' . $catid, OC_Log::DEBUG);
- if($catid) {
- try {
- OCP\DB::insertIfNotExist(self::RELATION_TABLE,
- array(
- 'objid' => $relation['objid'],
- 'categoryid' => $catid,
- 'type' => $this->type,
- ));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
- }
- }
- self::$relations = array(); // reset
- } else {
- OC_Log::write('core', __METHOD__.', $this->categories is not an array! '
- . print_r($this->categories, true), OC_Log::ERROR);
- }
- }
-
- /**
- * @brief Delete categories and category/object relations for a user.
- * For hooking up on post_deleteUser
- * @param string $uid The user id for which entries should be purged.
- */
- public static function post_deleteUser($arguments) {
- // Find all objectid/categoryid pairs.
- $result = null;
- try {
- $stmt = OCP\DB::prepare('SELECT `id` FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ?');
- $result = $stmt->execute(array($arguments['uid']));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
-
- if(!is_null($result)) {
- try {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` '
- . 'WHERE `categoryid` = ?');
- while( $row = $result->fetchRow()) {
- try {
- $stmt->execute(array($row['id']));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
- }
- try {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ?');
- $result = $stmt->execute(array($arguments['uid']));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__ . ', exception: '
- . $e->getMessage(), OCP\Util::ERROR);
- }
- }
-
- /**
- * @brief Delete category/object relations from the db
- * @param array $ids The ids of the objects
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean Returns false on error.
- */
- public function purgeObjects(array $ids, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- if(count($ids) === 0) {
- // job done ;)
- return true;
- }
- $updates = $ids;
- try {
- $query = 'DELETE FROM `' . self::RELATION_TABLE . '` ';
- $query .= 'WHERE `objid` IN (' . str_repeat('?,', count($ids)-1) . '?) ';
- $query .= 'AND `type`= ?';
- $updates[] = $type;
- $stmt = OCP\DB::prepare($query);
- $result = $stmt->execute($updates);
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- return true;
- }
-
- /**
- * Get favorites for an object type
- *
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns array An array of object ids.
- */
- public function getFavorites($type = null) {
- $type = is_null($type) ? $this->type : $type;
-
- try {
- return $this->idsForCategory(self::CATEGORY_FAVORITE);
- } catch(Exception $e) {
- // No favorites
- return array();
- }
- }
-
- /**
- * Add an object to favorites
- *
- * @param int $objid The id of the object
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean
- */
- public function addToFavorites($objid, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- if(!$this->hasCategory(self::CATEGORY_FAVORITE)) {
- $this->add(self::CATEGORY_FAVORITE, true);
- }
- return $this->addToCategory($objid, self::CATEGORY_FAVORITE, $type);
- }
-
- /**
- * Remove an object from favorites
- *
- * @param int $objid The id of the object
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean
- */
- public function removeFromFavorites($objid, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- return $this->removeFromCategory($objid, self::CATEGORY_FAVORITE, $type);
- }
-
- /**
- * @brief Creates a category/object relation.
- * @param int $objid The id of the object
- * @param int|string $category The id or name of the category
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean Returns false on database error.
- */
- public function addToCategory($objid, $category, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- if(is_string($category) && !is_numeric($category)) {
- if(!$this->hasCategory($category)) {
- $this->add($category, true);
- }
- $categoryid = $this->array_searchi($category, $this->categories);
- } else {
- $categoryid = $category;
- }
- try {
- OCP\DB::insertIfNotExist(self::RELATION_TABLE,
- array(
- 'objid' => $objid,
- 'categoryid' => $categoryid,
- 'type' => $type,
- ));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- return true;
- }
-
- /**
- * @brief Delete single category/object relation from the db
- * @param int $objid The id of the object
- * @param int|string $category The id or name of the category
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean
- */
- public function removeFromCategory($objid, $category, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- $categoryid = (is_string($category) && !is_numeric($category))
- ? $this->array_searchi($category, $this->categories)
- : $category;
- try {
- $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
- . 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?';
- OCP\Util::writeLog('core', __METHOD__.', sql: ' . $objid . ' ' . $categoryid . ' ' . $type,
- OCP\Util::DEBUG);
- $stmt = OCP\DB::prepare($sql);
- $stmt->execute(array($objid, $categoryid, $type));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- return true;
- }
-
- /**
- * @brief Delete categories from the db and from all the vobject supplied
- * @param $names An array of categories to delete
- * @param $objects An array of arrays with [id,vobject] (as text) pairs suitable for updating the apps object table.
- */
- public function delete($names, array &$objects=null) {
- if(!is_array($names)) {
- $names = array($names);
- }
-
- OC_Log::write('core', __METHOD__ . ', before: '
- . print_r($this->categories, true), OC_Log::DEBUG);
- foreach($names as $name) {
- $id = null;
- OC_Log::write('core', __METHOD__.', '.$name, OC_Log::DEBUG);
- if($this->hasCategory($name)) {
- $id = $this->array_searchi($name, $this->categories);
- unset($this->categories[$id]);
- }
- try {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` WHERE '
- . '`uid` = ? AND `type` = ? AND `category` = ?');
- $result = $stmt->execute(array($this->user, $this->type, $name));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__ . ', exception: '
- . $e->getMessage(), OCP\Util::ERROR);
- }
- if(!is_null($id) && $id !== false) {
- try {
- $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
- . 'WHERE `categoryid` = ?';
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($id));
- if (OC_DB::isError($result)) {
- OC_Log::write('core',
- __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result),
- OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- }
- }
- OC_Log::write('core', __METHOD__.', after: '
- . print_r($this->categories, true), OC_Log::DEBUG);
- if(!is_null($objects)) {
- foreach($objects as $key=>&$value) {
- $vobject = OC_VObject::parse($value[1]);
- if(!is_null($vobject)) {
- $object = null;
- $componentname = '';
- if (isset($vobject->VEVENT)) {
- $object = $vobject->VEVENT;
- $componentname = 'VEVENT';
- } else
- if (isset($vobject->VTODO)) {
- $object = $vobject->VTODO;
- $componentname = 'VTODO';
- } else
- if (isset($vobject->VJOURNAL)) {
- $object = $vobject->VJOURNAL;
- $componentname = 'VJOURNAL';
- } else {
- $object = $vobject;
- }
- $categories = $object->getAsArray('CATEGORIES');
- foreach($names as $name) {
- $idx = $this->array_searchi($name, $categories);
- if($idx !== false) {
- OC_Log::write('core', __METHOD__
- .', unsetting: '
- . $categories[$this->array_searchi($name, $categories)],
- OC_Log::DEBUG);
- unset($categories[$this->array_searchi($name, $categories)]);
- }
- }
-
- $object->setString('CATEGORIES', implode(',', $categories));
- if($vobject !== $object) {
- $vobject[$componentname] = $object;
- }
- $value[1] = $vobject->serialize();
- $objects[$key] = $value;
- } else {
- OC_Log::write('core', __METHOD__
- .', unable to parse. ID: ' . $value[0] . ', '
- . substr($value[1], 0, 50) . '(...)', OC_Log::DEBUG);
- }
- }
- }
- }
-
- // case-insensitive in_array
- private function in_arrayi($needle, $haystack) {
- if(!is_array($haystack)) {
- return false;
- }
- return in_array(strtolower($needle), array_map('strtolower', $haystack));
- }
-
- // case-insensitive array_search
- private function array_searchi($needle, $haystack) {
- if(!is_array($haystack)) {
- return false;
- }
- return array_search(strtolower($needle), array_map('strtolower', $haystack));
- }
-}