From 9adff4f7f52df660ec066b896161e46abe7a9d5a Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 22 Nov 2013 15:53:56 +0100 Subject: [PATCH 01/33] Change OC_Migrate from MDB2 to Doctrine --- lib/private/db.php | 2 +- lib/private/migrate.php | 96 +++++-------------------------- lib/private/migration/content.php | 35 ++++------- 3 files changed, 26 insertions(+), 107 deletions(-) diff --git a/lib/private/db.php b/lib/private/db.php index 1e5d12649df..237925a5921 100644 --- a/lib/private/db.php +++ b/lib/private/db.php @@ -44,7 +44,7 @@ class OC_DB { /** * @var \OC\DB\Connection $connection */ - static private $connection; //the prefered connection to use, only Doctrine + static private $connection; //the preferred connection to use, only Doctrine static private $prefix=null; static private $type=null; diff --git a/lib/private/migrate.php b/lib/private/migrate.php index 0b319177400..b45848fbcbd 100644 --- a/lib/private/migrate.php +++ b/lib/private/migrate.php @@ -38,7 +38,7 @@ class OC_Migrate{ // Array of temp files to be deleted after zip creation static private $tmpfiles=array(); // Holds the db object - static private $MDB2=false; + static private $migration_database=false; // Schema db object static private $schema=false; // Path to the sqlite db @@ -131,7 +131,7 @@ class OC_Migrate{ if( !self::connectDB() ) { return json_encode( array( 'success' => false ) ); } - self::$content = new OC_Migration_Content( self::$zip, self::$MDB2 ); + self::$content = new OC_Migration_Content( self::$zip, self::$migration_database ); // Export the app info $exportdata = self::exportAppData(); // Add the data dir to the zip @@ -358,24 +358,6 @@ class OC_Migrate{ return $to; } - /** - * @brief connects to a MDB2 database scheme - * @returns bool - */ - static private function connectScheme() { - // We need a mdb2 database connection - self::$MDB2->loadModule( 'Manager' ); - self::$MDB2->loadModule( 'Reverse' ); - - // Connect if this did not happen before - if( !self::$schema ) { - require_once 'MDB2/Schema.php'; - self::$schema=MDB2_Schema::factory( self::$MDB2 ); - } - - return true; - } - /** * @brief creates a migration.db in the users data dir with their app data in * @return bool whether operation was successfull @@ -463,47 +445,15 @@ class OC_Migrate{ return false; } // Already connected - if(!self::$MDB2) { - require_once 'MDB2.php'; - + if(!self::$migration_database) { $datadir = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); - - // DB type - if( class_exists( 'SQLite3' ) ) { - $dbtype = 'sqlite3'; - } else if( is_callable( 'sqlite_open' ) ) { - $dbtype = 'sqlite'; - } else { - OC_Log::write( 'migration', 'SQLite not found', OC_Log::ERROR ); - return false; - } - - // Prepare options array - $options = array( - 'portability' => MDB2_PORTABILITY_ALL & (!MDB2_PORTABILITY_FIX_CASE), - 'log_line_break' => '
', - 'idxname_format' => '%s', - 'debug' => true, - 'quote_identifier' => true - ); - $dsn = array( - 'phptype' => $dbtype, - 'database' => self::$dbpath, - 'mode' => '0644' + $connectionParams = array( + 'path' => self::$dbpath, + 'driver' => 'pdo_sqlite', ); // Try to establish connection - self::$MDB2 = MDB2::factory( $dsn, $options ); - // Die if we could not connect - if( PEAR::isError( self::$MDB2 ) ) { - die( self::$MDB2->getMessage() ); - OC_Log::write( 'migration', 'Failed to create/connect to migration.db', OC_Log::FATAL ); - OC_Log::write( 'migration', self::$MDB2->getUserInfo(), OC_Log::FATAL ); - OC_Log::write( 'migration', self::$MDB2->getMessage(), OC_Log::FATAL ); - return false; - } - // We always, really always want associative arrays - self::$MDB2->setFetchMode(MDB2_FETCHMODE_ASSOC); + self::$migration_database = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); } return true; @@ -515,10 +465,7 @@ class OC_Migrate{ * @return bool whether the operation was successful */ static private function createAppTables( $appid ) { - - if( !self::connectScheme() ) { - return false; - } + $schema_manager = new OC\DB\MDB2SchemaManager(self::$migration_database); // There is a database.xml file $content = file_get_contents(OC_App::getAppPath($appid) . '/appinfo/database.xml' ); @@ -538,29 +485,16 @@ class OC_Migrate{ file_put_contents( $file2, $content ); // Try to create tables - $definition = self::$schema->parseDatabaseDefinitionFile( $file2 ); - - unlink( $file2 ); - - // Die in case something went wrong - if( $definition instanceof MDB2_Schema_Error ) { - OC_Log::write( 'migration', 'Failed to parse database.xml for: '.$appid, OC_Log::FATAL ); - OC_Log::write( 'migration', $definition->getMessage().': '.$definition->getUserInfo(), OC_Log::FATAL ); - return false; - } - - $definition['overwrite'] = true; - - $ret = self::$schema->createDatabase( $definition ); - - // Die in case something went wrong - if( $ret instanceof MDB2_Error ) { + try { + $schema_manager->createDbFromStructure($file2); + } catch(Exception $e) { + unlink( $file2 ); OC_Log::write( 'migration', 'Failed to create tables for: '.$appid, OC_Log::FATAL ); - OC_Log::write( 'migration', $ret->getMessage().': '.$ret->getUserInfo(), OC_Log::FATAL ); + OC_Log::write( 'migration', $e->getMessage(), OC_Log::FATAL ); return false; } - return $tables; + return $tables; } /** @@ -646,7 +580,7 @@ class OC_Migrate{ if( !self::connectDB( $db ) ) { return false; } - $content = new OC_Migration_Content( self::$zip, self::$MDB2 ); + $content = new OC_Migration_Content( self::$zip, self::$migration_database ); $provider->setData( self::$uid, $content, $info ); // Then do the import if( !$appsstatus[$id] = $provider->import( $info->apps->$id, $importinfo ) ) { diff --git a/lib/private/migration/content.php b/lib/private/migration/content.php index 4413d722731..389dd8fc74f 100644 --- a/lib/private/migration/content.php +++ b/lib/private/migration/content.php @@ -27,7 +27,7 @@ class OC_Migration_Content{ private $zip=false; - // Holds the MDB2 object + // Holds the database object private $db=null; // Holds an array of tmpfiles to delete after zip creation private $tmpfiles=array(); @@ -35,7 +35,7 @@ class OC_Migration_Content{ /** * @brief sets up the * @param $zip ZipArchive object - * @param optional $db a MDB2 database object (required for exporttype user) + * @param optional $db a database object (required for exporttype user) * @return bool */ public function __construct( $zip, $db=null ) { @@ -64,16 +64,7 @@ class OC_Migration_Content{ // Optimize the query $query = $this->db->prepare( $query ); - // Die if we have an error (error means: bad query, not 0 results!) - if( PEAR::isError( $query ) ) { - $entry = 'DB Error: "'.$query->getMessage().'"
'; - $entry .= 'Offending command was: '.$query.'
'; - OC_Log::write( 'migration', $entry, OC_Log::FATAL ); - return false; - } else { - return $query; - } - + return $query; } /** @@ -156,20 +147,14 @@ class OC_Migration_Content{ $sql .= $valuessql . " )"; // Make the query $query = $this->prepare( $sql ); - if( !$query ) { - OC_Log::write( 'migration', 'Invalid sql produced: '.$sql, OC_Log::FATAL ); - return false; - exit(); + $query->execute( $values ); + // Do we need to return some values? + if( array_key_exists( 'idcol', $options ) ) { + // Yes we do + $return[] = $row[$options['idcol']]; } else { - $query->execute( $values ); - // Do we need to return some values? - if( array_key_exists( 'idcol', $options ) ) { - // Yes we do - $return[] = $row[$options['idcol']]; - } else { - // Take a guess and return the first field :) - $return[] = reset($row); - } + // Take a guess and return the first field :) + $return[] = reset($row); } $fields = ''; $values = ''; From 14332681fc541aca936dcbd6baf7de220734815f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 22 Nov 2013 17:18:06 +0100 Subject: [PATCH 02/33] ref 3rdparty branch without MDB2 code --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index 42efd966284..daf25846dbb 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit 42efd966284debadf83b761367e529bc45f806d6 +Subproject commit daf25846dbb8a326f4801dc3310cd2b8ab1f84b9 From 34fcf1e9d0b046afb35f3033cf8c3bd4a4c5ca62 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 20 Dec 2013 12:09:19 +0100 Subject: [PATCH 03/33] Wrap the import/export db in a wrapper to make it compatible with the old style --- lib/private/migrate.php | 3 +++ lib/private/migration/content.php | 1 + 2 files changed, 4 insertions(+) diff --git a/lib/private/migrate.php b/lib/private/migrate.php index b45848fbcbd..5354e9d338d 100644 --- a/lib/private/migrate.php +++ b/lib/private/migrate.php @@ -451,6 +451,9 @@ class OC_Migrate{ 'path' => self::$dbpath, 'driver' => 'pdo_sqlite', ); + $connectionParams['adapter'] = '\OC\DB\AdapterSqlite'; + $connectionParams['wrapperClass'] = 'OC\DB\Connection'; + $connectionParams['tablePrefix'] = ''; // Try to establish connection self::$migration_database = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); diff --git a/lib/private/migration/content.php b/lib/private/migration/content.php index 389dd8fc74f..d6eee40786e 100644 --- a/lib/private/migration/content.php +++ b/lib/private/migration/content.php @@ -63,6 +63,7 @@ class OC_Migration_Content{ // Optimize the query $query = $this->db->prepare( $query ); + $query = new OC_DB_StatementWrapper($query, false); return $query; } From ac85dea267261a58ae815c257098a3ae6ed42b80 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 20 Dec 2013 12:22:49 +0100 Subject: [PATCH 04/33] Fix migration import of user files --- lib/private/migrate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/migrate.php b/lib/private/migrate.php index 5354e9d338d..2d2d37795fd 100644 --- a/lib/private/migrate.php +++ b/lib/private/migrate.php @@ -257,7 +257,7 @@ class OC_Migrate{ $userfolder = $extractpath . $json->exporteduser; $newuserfolder = $datadir . '/' . self::$uid; foreach(scandir($userfolder) as $file){ - if($file !== '.' && $file !== '..' && is_dir($file)) { + if($file !== '.' && $file !== '..' && is_dir($userfolder.'/'.$file)) { $file = str_replace(array('/', '\\'), '', $file); // Then copy the folder over From 528ff25edecfbe47d11e5e570746ff35dc547d85 Mon Sep 17 00:00:00 2001 From: tomneedham Date: Tue, 7 Jan 2014 00:38:27 +0000 Subject: [PATCH 05/33] Add WIP unit test for migration --- tests/lib/migrate.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/lib/migrate.php diff --git a/tests/lib/migrate.php b/tests/lib/migrate.php new file mode 100644 index 00000000000..5c6c9ebe7be --- /dev/null +++ b/tests/lib/migrate.php @@ -0,0 +1,32 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_Migrate extends PHPUnit_Framework_TestCase { + + public $users; + + public function testUserSelfExport(){ + // Create a user + $user = uniqid(); + $u = new OC_User(); + $u->createUser($user, 'password'); + $this->users[] = $user; + $exportLocation = \OC_Migrate::export($user); + } + + public function tearDown() { + $u = new OC_User(); + foreach($this->users as $user) { + $u->deleteUser($user); + } + } + + + + +} From 504645cf00f797290a530d93bb27d65150901c4c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 16 Jan 2014 14:07:16 +0100 Subject: [PATCH 06/33] Add bindParam to statement wrapper --- lib/private/db/statementwrapper.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/private/db/statementwrapper.php b/lib/private/db/statementwrapper.php index 5e89261d936..db4a3e1b850 100644 --- a/lib/private/db/statementwrapper.php +++ b/lib/private/db/statementwrapper.php @@ -169,4 +169,18 @@ class OC_DB_StatementWrapper { public function fetchOne($colnum = 0) { return $this->statement->fetchColumn($colnum); } + + /** + * Binds a PHP variable to a corresponding named or question mark placeholder in the + * SQL statement that was use to prepare the statement. + * + * @param mixed $column Either the placeholder name or the 1-indexed placeholder index + * @param mixed $variable The variable to bind + * @param integer|null $type one of the PDO::PARAM_* constants + * @param integer|null $length max length when using an OUT bind + * @return boolean + */ + public function bindParam($column, &$variable, $type = null, $length = null){ + return $this->statement->bindParam($column, $variable, $type, $length); + } } From 1ba14ff848a200465dd11c7953009748a12b3672 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 22 Jan 2014 11:58:09 +0100 Subject: [PATCH 07/33] Moved steps to reproduce to the top This prevents people to put their steps into the "Expected" section. It is better to first read the steps to find out how users reached the issue, then see what was expected and actually happened. --- issue_template.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/issue_template.md b/issue_template.md index 0ddc7667bf3..a9ee4a44c9f 100644 --- a/issue_template.md +++ b/issue_template.md @@ -1,14 +1,14 @@ +### Steps to reproduce +1. +2. +3. + ### Expected behaviour Tell us what should happen ### Actual behaviour Tell us what happens instead -### Steps to reproduce -1. -2. -3. - ### Server configuration Operating system: From 87c94d71ab4d20bf4ef65eb4624df520b4a5d106 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 22 Jan 2014 11:58:59 +0100 Subject: [PATCH 08/33] Added explicit quota + encryption questions --- issue_template.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/issue_template.md b/issue_template.md index a9ee4a44c9f..4ffb8981be9 100644 --- a/issue_template.md +++ b/issue_template.md @@ -22,12 +22,16 @@ ownCloud version: (see ownCloud admin page) Updated from an older ownCloud or fresh install: -List of activated app: +List of activated apps: The content of config/config.php: (Without the database password and passwordsalt) Are you using external storage, if yes which one: +Are you using quota: + +Are you using encryption: + ### Client configuration Browser: From 0067b6c0c16ac7041b294d81826c31966e8bedb5 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 22 Jan 2014 12:04:24 +0100 Subject: [PATCH 09/33] Added boldening of entries for readability --- issue_template.md | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/issue_template.md b/issue_template.md index 4ffb8981be9..bea1f5c4c2d 100644 --- a/issue_template.md +++ b/issue_template.md @@ -10,32 +10,37 @@ Tell us what should happen Tell us what happens instead ### Server configuration -Operating system: +**Operating system**: -Web server: +**Web server:** -Database: +**Database:** -PHP version: +**PHP version:** -ownCloud version: (see ownCloud admin page) +**ownCloud version:** (see ownCloud admin page) -Updated from an older ownCloud or fresh install: +**Updated from an older ownCloud or fresh install:** -List of activated apps: +**List of activated apps:** -The content of config/config.php: (Without the database password and passwordsalt) +**The content of config/config.php:** -Are you using external storage, if yes which one: +``` +Insert your config.php content here +(Without the database password and passwordsalt) +``` + +**Are you using external storage, if yes which one:** local/smb/sftp/... -Are you using quota: +**Are you using quota:** yes/no -Are you using encryption: +**Are you using encryption:** yes/no ### Client configuration -Browser: +**Browser:** -Operating system: +**Operating system:** ### Logs #### Web server error log From 145d9a09abb1f5535361ca98b5e98af5a38e5ad9 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 7 Feb 2014 16:31:29 +0100 Subject: [PATCH 10/33] Do not select input for all text input fields Fix issue #6920 --- core/js/js.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/js/js.js b/core/js/js.js index cb177712a3a..d4d2583f1e5 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -884,11 +884,7 @@ function initCore() { $('a.action.delete').tipsy({gravity:'e', fade:true, live:true}); $('a.action').tipsy({gravity:'s', fade:true, live:true}); $('td .modified').tipsy({gravity:'s', fade:true, live:true}); - $('input').tipsy({gravity:'w', fade:true}); - $('input[type=text]').focus(function(){ - this.select(); - }); } $(document).ready(initCore); From a6399f9ceffcf9865b8a2be155dc4f98bd2ee5dc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Feb 2014 14:00:24 +0100 Subject: [PATCH 11/33] Add the background job list to the public server container --- cron.php | 4 +- lib/private/backgroundjob/job.php | 4 +- lib/private/backgroundjob/joblist.php | 68 +++++++++++++--------- lib/private/server.php | 16 ++++++ lib/public/backgroundjob.php | 14 ++--- lib/public/backgroundjob/ijob.php | 29 ++++++++++ lib/public/backgroundjob/ijoblist.php | 73 ++++++++++++++++++++++++ lib/public/iservercontainer.php | 7 +++ tests/lib/backgroundjob/dummyjoblist.php | 2 + 9 files changed, 179 insertions(+), 38 deletions(-) create mode 100644 lib/public/backgroundjob/ijob.php create mode 100644 lib/public/backgroundjob/ijoblist.php diff --git a/cron.php b/cron.php index 0d2c07b2d95..44ca421328b 100644 --- a/cron.php +++ b/cron.php @@ -97,7 +97,7 @@ try { touch(TemporaryCronClass::$lockfile); // Work - $jobList = new \OC\BackgroundJob\JobList(); + $jobList = \OC::$server->getJobList(); $jobs = $jobList->getAll(); foreach ($jobs as $job) { $job->execute($jobList, $logger); @@ -109,7 +109,7 @@ try { OC_JSON::error(array('data' => array('message' => 'Backgroundjobs are using system cron!'))); } else { // Work and success :-) - $jobList = new \OC\BackgroundJob\JobList(); + $jobList = \OC::$server->getJobList(); $job = $jobList->getNext(); $job->execute($jobList, $logger); $jobList->setLastJob($job); diff --git a/lib/private/backgroundjob/job.php b/lib/private/backgroundjob/job.php index 92bd0f8fdbd..0cef401bc24 100644 --- a/lib/private/backgroundjob/job.php +++ b/lib/private/backgroundjob/job.php @@ -8,7 +8,9 @@ namespace OC\BackgroundJob; -abstract class Job { +use OCP\BackgroundJob\IJob; + +abstract class Job implements IJob { /** * @var int $id */ diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php index 99743a70c77..6b0df9e0d63 100644 --- a/lib/private/backgroundjob/joblist.php +++ b/lib/private/backgroundjob/joblist.php @@ -8,14 +8,26 @@ namespace OC\BackgroundJob; -/** - * Class QueuedJob - * - * create a background job that is to be executed once - * - * @package OC\BackgroundJob - */ class JobList { + /** + * @var \OCP\IDBConnection + */ + private $conn; + + /** + * @var \OCP\IConfig $config + */ + private $config; + + /** + * @param \OCP\IDBConnection $conn + * @param \OCP\IConfig $config + */ + public function __construct($conn, $config) { + $this->conn = $conn; + $this->config = $config; + } + /** * @param Job|string $job * @param mixed $argument @@ -28,7 +40,7 @@ class JobList { $class = $job; } $argument = json_encode($argument); - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*jobs`(`class`, `argument`, `last_run`) VALUES(?, ?, 0)'); + $query = $this->conn->prepare('INSERT INTO `*PREFIX*jobs`(`class`, `argument`, `last_run`) VALUES(?, ?, 0)'); $query->execute(array($class, $argument)); } } @@ -45,10 +57,10 @@ class JobList { } if (!is_null($argument)) { $argument = json_encode($argument); - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*jobs` WHERE `class` = ? AND `argument` = ?'); + $query = $this->conn->prepare('DELETE FROM `*PREFIX*jobs` WHERE `class` = ? AND `argument` = ?'); $query->execute(array($class, $argument)); } else { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*jobs` WHERE `class` = ?'); + $query = $this->conn->prepare('DELETE FROM `*PREFIX*jobs` WHERE `class` = ?'); $query->execute(array($class)); } } @@ -67,9 +79,9 @@ class JobList { $class = $job; } $argument = json_encode($argument); - $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*jobs` WHERE `class` = ? AND `argument` = ?'); - $result = $query->execute(array($class, $argument)); - return (bool)$result->fetchRow(); + $query = $this->conn->prepare('SELECT `id` FROM `*PREFIX*jobs` WHERE `class` = ? AND `argument` = ?'); + $query->execute(array($class, $argument)); + return (bool)$query->fetch(); } /** @@ -78,10 +90,10 @@ class JobList { * @return Job[] */ public function getAll() { - $query = \OC_DB::prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs`'); - $result = $query->execute(); + $query = $this->conn->prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs`'); + $query->execute(); $jobs = array(); - while ($row = $result->fetchRow()) { + while ($row = $query->fetch()) { $jobs[] = $this->buildJob($row); } return $jobs; @@ -94,15 +106,15 @@ class JobList { */ public function getNext() { $lastId = $this->getLastJob(); - $query = \OC_DB::prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` WHERE `id` > ? ORDER BY `id` ASC', 1); - $result = $query->execute(array($lastId)); - if ($row = $result->fetchRow()) { + $query = $this->conn->prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` WHERE `id` > ? ORDER BY `id` ASC', 1); + $query->execute(array($lastId)); + if ($row = $query->fetch()) { return $this->buildJob($row); } else { //begin at the start of the queue - $query = \OC_DB::prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` ORDER BY `id` ASC', 1); - $result = $query->execute(); - if ($row = $result->fetchRow()) { + $query = $this->conn->prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` ORDER BY `id` ASC', 1); + $query->execute(); + if ($row = $query->fetch()) { return $this->buildJob($row); } else { return null; //empty job list @@ -115,9 +127,9 @@ class JobList { * @return Job */ public function getById($id) { - $query = \OC_DB::prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` WHERE `id` = ?'); - $result = $query->execute(array($id)); - if ($row = $result->fetchRow()) { + $query = $this->conn->prepare('SELECT `id`, `class`, `last_run`, `argument` FROM `*PREFIX*jobs` WHERE `id` = ?'); + $query->execute(array($id)); + if ($row = $query->fetch()) { return $this->buildJob($row); } else { return null; @@ -148,7 +160,7 @@ class JobList { * @param Job $job */ public function setLastJob($job) { - \OC_Appconfig::setValue('backgroundjob', 'lastjob', $job->getId()); + $this->config->setAppValue('backgroundjob', 'lastjob', $job->getId()); } /** @@ -157,7 +169,7 @@ class JobList { * @return int */ public function getLastJob() { - return \OC_Appconfig::getValue('backgroundjob', 'lastjob', 0); + $this->config->getAppValue('backgroundjob', 'lastjob', 0); } /** @@ -166,7 +178,7 @@ class JobList { * @param Job $job */ public function setLastRun($job) { - $query = \OC_DB::prepare('UPDATE `*PREFIX*jobs` SET `last_run` = ? WHERE `id` = ?'); + $query = $this->conn->prepare('UPDATE `*PREFIX*jobs` SET `last_run` = ? WHERE `id` = ?'); $query->execute(array(time(), $job->getId())); } } diff --git a/lib/private/server.php b/lib/private/server.php index c9e593ec2ed..b5ffd08ce79 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -148,6 +148,13 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('AvatarManager', function($c) { return new AvatarManager(); }); + $this->registerService('JobList', function ($c) { + /** + * @var Server $c + */ + $config = $c->getConfig(); + return new \OC\BackgroundJob\JobList($c->getDatabaseConnection(), $config); + }); } /** @@ -336,4 +343,13 @@ class Server extends SimpleContainer implements IServerContainer { function getActivityManager() { return $this->query('ActivityManager'); } + + /** + * Returns an job list for controlling background jobs + * + * @return \OCP\BackgroundJob\IJobList + */ + function getJobList(){ + return $this->query('JobList'); + } } diff --git a/lib/public/backgroundjob.php b/lib/public/backgroundjob.php index a7f54491dfa..bcaf6e35454 100644 --- a/lib/public/backgroundjob.php +++ b/lib/public/backgroundjob.php @@ -33,7 +33,7 @@ use \OC\BackgroundJob\JobList; /** * This class provides functions to register backgroundjobs in ownCloud * - * To create a new backgroundjob create a new class that inharits from either \OC\BackgroundJob\Job, + * To create a new backgroundjob create a new class that inherits from either \OC\BackgroundJob\Job, * \OC\BackgroundJob\QueuedJob or \OC\BackgroundJob\TimedJob and register it using * \OCP\BackgroundJob->registerJob($job, $argument), $argument will be passed to the run() function * of the job when the job is executed. @@ -73,7 +73,7 @@ class BackgroundJob { * @param mixed $argument */ public static function registerJob($job, $argument = null) { - $jobList = new JobList(); + $jobList = \OC::$server->getJobList(); $jobList->add($job, $argument); } @@ -99,7 +99,7 @@ class BackgroundJob { * key is string "$klass-$method", value is array( $klass, $method ) */ static public function allRegularTasks() { - $jobList = new JobList(); + $jobList = \OC::$server->getJobList(); $allJobs = $jobList->getAll(); $regularJobs = array(); foreach ($allJobs as $job) { @@ -118,7 +118,7 @@ class BackgroundJob { * @return associative array */ public static function findQueuedTask($id) { - $jobList = new JobList(); + $jobList = \OC::$server->getJobList(); return $jobList->getById($id); } @@ -128,7 +128,7 @@ class BackgroundJob { * @return array with associative arrays */ public static function allQueuedTasks() { - $jobList = new JobList(); + $jobList = \OC::$server->getJobList(); $allJobs = $jobList->getAll(); $queuedJobs = array(); foreach ($allJobs as $job) { @@ -148,7 +148,7 @@ class BackgroundJob { * @return array with associative arrays */ public static function queuedTaskWhereAppIs($app) { - $jobList = new JobList(); + $jobList = \OC::$server->getJobList(); $allJobs = $jobList->getAll(); $queuedJobs = array(); foreach ($allJobs as $job) { @@ -186,7 +186,7 @@ class BackgroundJob { * Deletes a report */ public static function deleteQueuedTask($id) { - $jobList = new JobList(); + $jobList = \OC::$server->getJobList(); $job = $jobList->getById($id); if ($job) { $jobList->remove($job); diff --git a/lib/public/backgroundjob/ijob.php b/lib/public/backgroundjob/ijob.php new file mode 100644 index 00000000000..c427b50401d --- /dev/null +++ b/lib/public/backgroundjob/ijob.php @@ -0,0 +1,29 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP\BackgroundJob; + +interface IJob { + /** + * @param \OCP\BackgroundJob\IJobList $jobList + * @param \OC\Log $logger + */ + public function execute($jobList, $logger = null); + + public function setId($id); + + public function setLastRun($lastRun); + + public function setArgument($argument); + + public function getId(); + + public function getLastRun(); + + public function getArgument(); +} diff --git a/lib/public/backgroundjob/ijoblist.php b/lib/public/backgroundjob/ijoblist.php new file mode 100644 index 00000000000..7e80d51755b --- /dev/null +++ b/lib/public/backgroundjob/ijoblist.php @@ -0,0 +1,73 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP\BackgroundJob; + +interface IJobList { + /** + * @param \OCP\BackgroundJob\IJob |string $job + * @param mixed $argument + */ + public function add($job, $argument = null); + + /** + * @param \OCP\BackgroundJob\IJob|string $job + * @param mixed $argument + */ + public function remove($job, $argument = null); + + /** + * check if a job is in the list + * + * @param $job + * @param mixed $argument + * @return bool + */ + public function has($job, $argument); + + /** + * get all jobs in the list + * + * @return \OCP\BackgroundJob\IJob[] + */ + public function getAll(); + + /** + * get the next job in the list + * + * @return \OCP\BackgroundJob\IJob + */ + public function getNext(); + + /** + * @param int $id + * @return \OCP\BackgroundJob\IJob + */ + public function getById($id); + + /** + * set the job that was last ran + * + * @param \OCP\BackgroundJob\IJob $job + */ + public function setLastJob($job); + + /** + * get the id of the last ran job + * + * @return int + */ + public function getLastJob(); + + /** + * set the lastRun of $job to now + * + * @param \OCP\BackgroundJob\IJob $job + */ + public function setLastRun($job); +} diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index 5473f3ee334..0658bd0b022 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -176,4 +176,11 @@ interface IServerContainer { */ function getAvatarManager(); + /** + * Returns an job list for controlling background jobs + * + * @return \OCP\BackgroundJob\IJobList + */ + function getJobList(); + } diff --git a/tests/lib/backgroundjob/dummyjoblist.php b/tests/lib/backgroundjob/dummyjoblist.php index e1579c273bb..7801269b27e 100644 --- a/tests/lib/backgroundjob/dummyjoblist.php +++ b/tests/lib/backgroundjob/dummyjoblist.php @@ -21,6 +21,8 @@ class DummyJobList extends \OC\BackgroundJob\JobList { private $last = 0; + public function __construct(){} + /** * @param \OC\BackgroundJob\Job|string $job * @param mixed $argument From addd0fba3887edafd03b3c22efa6f8276e1884dc Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 14 Jun 2013 12:13:37 +0200 Subject: [PATCH 12/33] number as number --- tests/lib/db.php | 2 +- tests/lib/dbschema.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lib/db.php b/tests/lib/db.php index f0b271a36f1..2fca67b5638 100644 --- a/tests/lib/db.php +++ b/tests/lib/db.php @@ -30,7 +30,7 @@ class Test_DB extends PHPUnit_Framework_TestCase { public function setUp() { $dbfile = OC::$SERVERROOT.'/tests/data/db_structure.xml'; - $r = '_'.OC_Util::generateRandomBytes('4').'_'; + $r = '_'.OC_Util::generateRandomBytes(4).'_'; $content = file_get_contents( $dbfile ); $content = str_replace( '*dbprefix*', '*dbprefix*'.$r, $content ); file_put_contents( self::$schema_file, $content ); diff --git a/tests/lib/dbschema.php b/tests/lib/dbschema.php index 4a7b7f7aac0..e8a43538004 100644 --- a/tests/lib/dbschema.php +++ b/tests/lib/dbschema.php @@ -16,7 +16,7 @@ class Test_DBSchema extends PHPUnit_Framework_TestCase { $dbfile = OC::$SERVERROOT.'/tests/data/db_structure.xml'; $dbfile2 = OC::$SERVERROOT.'/tests/data/db_structure2.xml'; - $r = '_'.OC_Util::generateRandomBytes('4').'_'; + $r = '_'.OC_Util::generateRandomBytes(4).'_'; $content = file_get_contents( $dbfile ); $content = str_replace( '*dbprefix*', '*dbprefix*'.$r, $content ); file_put_contents( $this->schema_file, $content ); From 1fb5f96c37ab8738ba96b97bc04a75b0fa911aca Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 13 Sep 2013 17:45:27 +0200 Subject: [PATCH 13/33] Style fixes --- apps/files_encryption/lib/proxy.php | 2 +- lib/private/db/mdb2schemareader.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 11048005969..6425ace7f56 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -262,7 +262,7 @@ class Proxy extends \OC_FileProxy { } elseif ( self::shouldEncrypt($path) - and $meta ['mode'] !== 'r' + and $meta['mode'] !== 'r' and $meta['mode'] !== 'rb' ) { $result = fopen('crypt://' . $path, $meta['mode']); diff --git a/lib/private/db/mdb2schemareader.php b/lib/private/db/mdb2schemareader.php index b1fd2454cb0..f9a76786c3e 100644 --- a/lib/private/db/mdb2schemareader.php +++ b/lib/private/db/mdb2schemareader.php @@ -288,12 +288,13 @@ class MDB2SchemaReader { if (!empty($fields)) { if (isset($primary) && $primary) { $table->setPrimaryKey($fields, $name); - } else + } else { if (isset($unique) && $unique) { $table->addUniqueIndex($fields, $name); } else { $table->addIndex($fields, $name); } + } } else { throw new \DomainException('Empty index definition: ' . $name . ' options:' . print_r($fields, true)); } From 3aafa837b884e8bd701d14665d1c93e33ecc7f7e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Feb 2014 13:25:50 +0100 Subject: [PATCH 14/33] Remove internal methods from the public interface --- lib/public/backgroundjob/ijob.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/public/backgroundjob/ijob.php b/lib/public/backgroundjob/ijob.php index c427b50401d..5bf815ef8e0 100644 --- a/lib/public/backgroundjob/ijob.php +++ b/lib/public/backgroundjob/ijob.php @@ -1,6 +1,6 @@ + * Copyright (c) 2014 Robin Appelman * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -15,12 +15,6 @@ interface IJob { */ public function execute($jobList, $logger = null); - public function setId($id); - - public function setLastRun($lastRun); - - public function setArgument($argument); - public function getId(); public function getLastRun(); From 62288971cacf9049ec4521d659a17857ac42d139 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Feb 2014 13:32:16 +0100 Subject: [PATCH 15/33] Additional phpdoc --- lib/private/backgroundjob/joblist.php | 6 ++++-- lib/public/backgroundjob/ijob.php | 21 ++++++++++++++++++++- lib/public/backgroundjob/ijoblist.php | 10 +++++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php index 6b0df9e0d63..5ec81dc3fc6 100644 --- a/lib/private/backgroundjob/joblist.php +++ b/lib/private/backgroundjob/joblist.php @@ -1,6 +1,6 @@ + * Copyright (c) 2014 Robin Appelman * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -8,7 +8,9 @@ namespace OC\BackgroundJob; -class JobList { +use OCP\BackgroundJob\IJobList; + +class JobList implements IJobList { /** * @var \OCP\IDBConnection */ diff --git a/lib/public/backgroundjob/ijob.php b/lib/public/backgroundjob/ijob.php index 5bf815ef8e0..5231e9537a9 100644 --- a/lib/public/backgroundjob/ijob.php +++ b/lib/public/backgroundjob/ijob.php @@ -10,14 +10,33 @@ namespace OCP\BackgroundJob; interface IJob { /** - * @param \OCP\BackgroundJob\IJobList $jobList + * Run the background job with the registered argument + * + * @param \OCP\BackgroundJob\IJobList $jobList The job list that manages the state of this job * @param \OC\Log $logger */ public function execute($jobList, $logger = null); + /** + * Get the id of the background job + * This id is determined by the job list when a job is added to the list + * + * @return int + */ public function getId(); + /** + * Get the last time this job was run as unix timestamp + * + * @return int + */ public function getLastRun(); + /** + * Get the argument associated with the background job + * This is the argument that will be passed to the background job + * + * @return mixed + */ public function getArgument(); } diff --git a/lib/public/backgroundjob/ijoblist.php b/lib/public/backgroundjob/ijoblist.php index 7e80d51755b..72f3fe863da 100644 --- a/lib/public/backgroundjob/ijoblist.php +++ b/lib/public/backgroundjob/ijoblist.php @@ -1,6 +1,6 @@ + * Copyright (c) 2014 Robin Appelman * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -10,12 +10,16 @@ namespace OCP\BackgroundJob; interface IJobList { /** + * Add a job to the list + * * @param \OCP\BackgroundJob\IJob |string $job - * @param mixed $argument + * @param mixed $argument The argument to be passed to $job->run() when the job is exectured */ public function add($job, $argument = null); /** + * Remove a job from the list + * * @param \OCP\BackgroundJob\IJob|string $job * @param mixed $argument */ @@ -51,7 +55,7 @@ interface IJobList { public function getById($id); /** - * set the job that was last ran + * set the job that was last ran to the current time * * @param \OCP\BackgroundJob\IJob $job */ From d6576c640c429d24a6329573c0dfaf99d82ac867 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Feb 2014 13:52:13 +0100 Subject: [PATCH 16/33] Add unit tests for JobList --- lib/private/backgroundjob/joblist.php | 2 +- tests/lib/backgroundjob/job.php | 25 ---- tests/lib/backgroundjob/joblist.php | 203 ++++++++++++++++++++++++++ tests/lib/backgroundjob/testjob.php | 34 +++++ 4 files changed, 238 insertions(+), 26 deletions(-) create mode 100644 tests/lib/backgroundjob/joblist.php create mode 100644 tests/lib/backgroundjob/testjob.php diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php index 5ec81dc3fc6..586e99a3cbc 100644 --- a/lib/private/backgroundjob/joblist.php +++ b/lib/private/backgroundjob/joblist.php @@ -171,7 +171,7 @@ class JobList implements IJobList { * @return int */ public function getLastJob() { - $this->config->getAppValue('backgroundjob', 'lastjob', 0); + return $this->config->getAppValue('backgroundjob', 'lastjob', 0); } /** diff --git a/tests/lib/backgroundjob/job.php b/tests/lib/backgroundjob/job.php index 7d66fa772d2..10a8f46462e 100644 --- a/tests/lib/backgroundjob/job.php +++ b/tests/lib/backgroundjob/job.php @@ -8,31 +8,6 @@ namespace Test\BackgroundJob; - -class TestJob extends \OC\BackgroundJob\Job { - private $testCase; - - /** - * @var callable $callback - */ - private $callback; - - /** - * @param Job $testCase - * @param callable $callback - */ - public function __construct($testCase, $callback) { - $this->testCase = $testCase; - $this->callback = $callback; - } - - public function run($argument) { - $this->testCase->markRun(); - $callback = $this->callback; - $callback($argument); - } -} - class Job extends \PHPUnit_Framework_TestCase { private $run = false; diff --git a/tests/lib/backgroundjob/joblist.php b/tests/lib/backgroundjob/joblist.php new file mode 100644 index 00000000000..c3318f80cb2 --- /dev/null +++ b/tests/lib/backgroundjob/joblist.php @@ -0,0 +1,203 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\BackgroundJob; + +class JobList extends \PHPUnit_Framework_TestCase { + /** + * @var \OC\BackgroundJob\JobList + */ + protected $instance; + + /** + * @var \OCP\IConfig | \PHPUnit_Framework_MockObject_MockObject $config + */ + protected $config; + + public function setUp() { + $conn = \OC::$server->getDatabaseConnection(); + $this->config = $this->getMock('\OCP\IConfig'); + $this->instance = new \OC\BackgroundJob\JobList($conn, $this->config); + } + + public function argumentProvider() { + return array( + array(null), + array(false), + array('foobar'), + array(12), + array(array( + 'asd' => 5, + 'foo' => 'bar' + )) + ); + } + + /** + * @dataProvider argumentProvider + * @param $argument + */ + public function testAddRemove($argument) { + $existingJobs = $this->instance->getAll(); + $job = new TestJob(); + $this->instance->add($job, $argument); + + $jobs = $this->instance->getAll(); + + $this->assertCount(count($existingJobs) + 1, $jobs); + $addedJob = $jobs[count($jobs) - 1]; + $this->assertInstanceOf('\Test\BackgroundJob\TestJob', $addedJob); + $this->assertEquals($argument, $addedJob->getArgument()); + + $this->instance->remove($job, $argument); + + $jobs = $this->instance->getAll(); + $this->assertEquals($existingJobs, $jobs); + } + + /** + * @dataProvider argumentProvider + * @param $argument + */ + public function testRemoveDifferentArgument($argument) { + $existingJobs = $this->instance->getAll(); + $job = new TestJob(); + $this->instance->add($job, $argument); + + $jobs = $this->instance->getAll(); + $this->instance->remove($job, 10); + $jobs2 = $this->instance->getAll(); + + $this->assertEquals($jobs, $jobs2); + + $this->instance->remove($job, $argument); + + $jobs = $this->instance->getAll(); + $this->assertEquals($existingJobs, $jobs); + } + + /** + * @dataProvider argumentProvider + * @param $argument + */ + public function testHas($argument) { + $job = new TestJob(); + $this->assertFalse($this->instance->has($job, $argument)); + $this->instance->add($job, $argument); + + $this->assertTrue($this->instance->has($job, $argument)); + + $this->instance->remove($job, $argument); + + $this->assertFalse($this->instance->has($job, $argument)); + } + + /** + * @dataProvider argumentProvider + * @param $argument + */ + public function testHasDifferentArgument($argument) { + $job = new TestJob(); + $this->instance->add($job, $argument); + + $this->assertFalse($this->instance->has($job, 10)); + + $this->instance->remove($job, $argument); + } + + public function testGetLastJob() { + $this->config->expects($this->once()) + ->method('getAppValue') + ->with('backgroundjob', 'lastjob', 0) + ->will($this->returnValue(15)); + + $this->assertEquals(15, $this->instance->getLastJob()); + } + + public function testGetNext() { + $job = new TestJob(); + $this->instance->add($job, 1); + $this->instance->add($job, 2); + + $jobs = $this->instance->getAll(); + + $savedJob1 = $jobs[count($jobs) - 2]; + $savedJob2 = $jobs[count($jobs) - 1]; + + $this->config->expects($this->once()) + ->method('getAppValue') + ->with('backgroundjob', 'lastjob', 0) + ->will($this->returnValue($savedJob1->getId())); + + $nextJob = $this->instance->getNext(); + + $this->assertEquals($savedJob2, $nextJob); + + $this->instance->remove($job, 1); + $this->instance->remove($job, 2); + } + + public function testGetNextWrapAround() { + $job = new TestJob(); + $this->instance->add($job, 1); + $this->instance->add($job, 2); + + $jobs = $this->instance->getAll(); + + $savedJob2 = $jobs[count($jobs) - 1]; + + $this->config->expects($this->once()) + ->method('getAppValue') + ->with('backgroundjob', 'lastjob', 0) + ->will($this->returnValue($savedJob2->getId())); + + $nextJob = $this->instance->getNext(); + + $this->assertEquals($jobs[0], $nextJob); + + $this->instance->remove($job, 1); + $this->instance->remove($job, 2); + } + + /** + * @dataProvider argumentProvider + * @param $argument + */ + public function testGetById($argument) { + $job = new TestJob(); + $this->instance->add($job, $argument); + + $jobs = $this->instance->getAll(); + + $addedJob = $jobs[count($jobs) - 1]; + + $this->assertEquals($addedJob, $this->instance->getById($addedJob->getId())); + + $this->instance->remove($job, $argument); + } + + public function testSetLastRun() { + $job = new TestJob(); + $this->instance->add($job); + + $jobs = $this->instance->getAll(); + + $addedJob = $jobs[count($jobs) - 1]; + + $timeStart = time(); + $this->instance->setLastRun($addedJob); + $timeEnd = time(); + + $addedJob = $this->instance->getById($addedJob->getId()); + + $this->assertGreaterThanOrEqual($timeStart, $addedJob->getLastRun()); + $this->assertLessThanOrEqual($timeEnd, $addedJob->getLastRun()); + + $this->instance->remove($job); + } +} diff --git a/tests/lib/backgroundjob/testjob.php b/tests/lib/backgroundjob/testjob.php new file mode 100644 index 00000000000..23fc4268d1a --- /dev/null +++ b/tests/lib/backgroundjob/testjob.php @@ -0,0 +1,34 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\BackgroundJob; + + +class TestJob extends \OC\BackgroundJob\Job { + private $testCase; + + /** + * @var callable $callback + */ + private $callback; + + /** + * @param Job $testCase + * @param callable $callback + */ + public function __construct($testCase = null, $callback = null) { + $this->testCase = $testCase; + $this->callback = $callback; + } + + public function run($argument) { + $this->testCase->markRun(); + $callback = $this->callback; + $callback($argument); + } +} From 2c6411b8977e4d17e6489c5a1b768f9de93ba280 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 12 Feb 2014 17:38:32 +0100 Subject: [PATCH 17/33] $default of OC_Config::[gs]etValue can have more then string as type --- lib/private/allconfig.php | 4 ++-- lib/private/config.php | 4 ++-- lib/public/config.php | 4 ++-- lib/public/iconfig.php | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php index a4aa69d43fb..de3ac973637 100644 --- a/lib/private/allconfig.php +++ b/lib/private/allconfig.php @@ -17,7 +17,7 @@ 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 + * @param mixed $value the value that should be stored * @todo need a use case for this */ // public function setSystemValue($key, $value) { @@ -28,7 +28,7 @@ class AllConfig implements \OCP\IConfig { * Looks up a system wide defined value * * @param string $key the key of the value, under which it was saved - * @param string $default the default value to be returned if the value isn't set + * @param mixed $default the default value to be returned if the value isn't set * @return string the saved value */ public function getSystemValue($key, $default = '') { diff --git a/lib/private/config.php b/lib/private/config.php index 8a9d5ca6158..8399d0defbd 100644 --- a/lib/private/config.php +++ b/lib/private/config.php @@ -77,7 +77,7 @@ class Config { /** * @brief Gets a value from config.php * @param string $key key - * @param string $default = null default value + * @param mixed $default = null default value * @return string the value or $default * * This function gets the value from config.php. If it does not exist, @@ -94,7 +94,7 @@ class Config { /** * @brief Sets a value * @param string $key key - * @param string $value value + * @param mixed $value value * * This function sets the value and writes the config.php. * diff --git a/lib/public/config.php b/lib/public/config.php index d9355a0605f..c1cc1034878 100644 --- a/lib/public/config.php +++ b/lib/public/config.php @@ -42,7 +42,7 @@ class Config { /** * Gets a value from config.php * @param string $key key - * @param string $default = null default value + * @param mixed $default = null default value * @return string the value or $default * * This function gets the value from config.php. If it does not exist, @@ -55,7 +55,7 @@ class Config { /** * Sets a value * @param string $key key - * @param string $value value + * @param mixed $value value * @return bool * * This function sets the value and writes the config.php. If the file can diff --git a/lib/public/iconfig.php b/lib/public/iconfig.php index 1d0f8e0015c..585ee2812dc 100644 --- a/lib/public/iconfig.php +++ b/lib/public/iconfig.php @@ -38,7 +38,7 @@ 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 + * @param mixed $value the value that should be stored * @todo need a use case for this */ // public function setSystemValue($key, $value); @@ -47,7 +47,7 @@ interface IConfig { * Looks up a system wide defined value * * @param string $key the key of the value, under which it was saved - * @param string $default the default value to be returned if the value isn't set + * @param mixed $default the default value to be returned if the value isn't set * @return string the saved value */ public function getSystemValue($key, $default = ''); From 181bbd4325ea2b21ff8ecca93eb5ac839d6a739d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 13 Feb 2014 16:28:49 +0100 Subject: [PATCH 18/33] Remove usage of legacy OC_Appconfig --- apps/files/index.php | 8 +++++--- apps/files_encryption/ajax/adminrecovery.php | 2 +- apps/files_encryption/lib/helper.php | 9 +++++---- apps/files_encryption/lib/session.php | 6 ++++-- apps/files_encryption/lib/util.php | 12 ++++++++---- apps/files_encryption/settings-admin.php | 2 +- apps/files_encryption/settings-personal.php | 2 +- apps/files_encryption/tests/share.php | 12 ++++++------ apps/files_external/lib/google.php | 5 +++-- apps/files_sharing/lib/api.php | 6 +++--- apps/files_sharing/public.php | 6 ++++-- apps/files_trashbin/lib/trashbin.php | 2 +- apps/files_versions/lib/versions.php | 2 +- lib/private/cache/fileglobal.php | 5 +++-- lib/private/setup.php | 9 +++++---- lib/private/util.php | 5 +++-- remote.php | 2 +- 17 files changed, 55 insertions(+), 40 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index dd63f29bc28..c9eea6a4174 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -79,6 +79,8 @@ if (\OC\Files\Cache\Upgrade::needUpgrade($user)) { //dont load anything if we ne $needUpgrade = false; } +$config = \OC::$server->getConfig(); + // Make breadcrumb $breadcrumb = \OCA\Files\Helper::makeBreadcrumb($dir); @@ -104,7 +106,7 @@ if ($needUpgrade) { $freeSpace=$storageInfo['free']; $uploadLimit=OCP\Util::uploadLimit(); $maxUploadFilesize=OCP\Util::maxUploadFilesize($dir); - $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); + $publicUploadEnabled = $config->getAppValue('core', 'shareapi_allow_public_upload', 'yes'); // if the encryption app is disabled, than everything is fine (INIT_SUCCESSFUL status code) $encryptionInitStatus = 2; if (OC_App::isEnabled('files_encryption')) { @@ -143,8 +145,8 @@ if ($needUpgrade) { $tmpl->assign('isPublic', false); $tmpl->assign('publicUploadEnabled', $publicUploadEnabled); $tmpl->assign("encryptedFiles", \OCP\Util::encryptedFiles()); - $tmpl->assign("mailNotificationEnabled", \OC_Appconfig::getValue('core', 'shareapi_allow_mail_notification', 'yes')); - $tmpl->assign("allowShareWithLink", \OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes')); + $tmpl->assign("mailNotificationEnabled", $config->getAppValue('core', 'shareapi_allow_mail_notification', 'yes')); + $tmpl->assign("allowShareWithLink", $config->getAppValue('core', 'shareapi_allow_links', 'yes')); $tmpl->assign("encryptionInitStatus", $encryptionInitStatus); $tmpl->assign('disableSharing', false); $tmpl->assign('ajaxLoad', $ajaxLoad); diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php index 6a0186d5a9b..61e43acc2c3 100644 --- a/apps/files_encryption/ajax/adminrecovery.php +++ b/apps/files_encryption/ajax/adminrecovery.php @@ -18,7 +18,7 @@ $l = OC_L10N::get('files_encryption'); $return = false; // Enable recoveryAdmin -$recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); +$recoveryKeyId = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryKeyId'); if (isset($_POST['adminEnableRecovery']) && $_POST['adminEnableRecovery'] === '1') { diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index bb06a57c714..74a3b96a944 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -111,10 +111,11 @@ class Helper { public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) { $view = new \OC\Files\View('/'); + $appConfig = \OC::$server->getAppConfig(); if ($recoveryKeyId === null) { $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8); - \OC_Appconfig::setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId); + $appConfig->setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId); } if (!$view->is_dir('/owncloud_private_key')) { @@ -147,7 +148,7 @@ class Helper { \OC_FileProxy::$enabled = true; // Set recoveryAdmin as enabled - \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); + $appConfig->setValue('files_encryption', 'recoveryAdminEnabled', 1); $return = true; @@ -155,7 +156,7 @@ class Helper { $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser()); $return = $util->checkRecoveryPassword($recoveryPassword); if ($return) { - \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); + $appConfig->setValue('files_encryption', 'recoveryAdminEnabled', 1); } } @@ -218,7 +219,7 @@ class Helper { if ($return) { // Set recoveryAdmin as disabled - \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 0); + \OC::$server->getAppConfig()->setValue('files_encryption', 'recoveryAdminEnabled', 0); } return $return; diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index 25f2198181f..324081beabb 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -51,11 +51,13 @@ class Session { } - $publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId'); + $appConfig = \OC::$server->getAppConfig(); + + $publicShareKeyId = $appConfig->getValue('files_encryption', 'publicShareKeyId'); if ($publicShareKeyId === null) { $publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8); - \OC_Appconfig::setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId); + $appConfig->setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId); } if ( diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index ae3e2a2e15a..13184b50dbf 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -63,8 +63,10 @@ class Util { $this->client = $client; $this->userId = $userId; - $this->publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId'); - $this->recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); + $appConfig = \OC::$server->getAppConfig(); + + $this->publicShareKeyId = $appConfig->getValue('files_encryption', 'publicShareKeyId'); + $this->recoveryKeyId = $appConfig->getValue('files_encryption', 'recoveryKeyId'); $this->userDir = '/' . $this->userId; $this->fileFolderName = 'files'; @@ -1113,9 +1115,11 @@ class Util { */ public function getSharingUsersArray($sharingEnabled, $filePath, $currentUserId = false) { + $appConfig = \OC::$server->getAppConfig(); + // Check if key recovery is enabled if ( - \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled') + $appConfig->getValue('files_encryption', 'recoveryAdminEnabled') && $this->recoveryEnabledForUser() ) { $recoveryEnabled = true; @@ -1144,7 +1148,7 @@ class Util { // Admin UID to list of users to share to if ($recoveryEnabled) { // Find recoveryAdmin user ID - $recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); + $recoveryKeyId = $appConfig->getValue('files_encryption', 'recoveryKeyId'); // Add recoveryAdmin to list of users sharing $userIds[] = $recoveryKeyId; } diff --git a/apps/files_encryption/settings-admin.php b/apps/files_encryption/settings-admin.php index 9ad9bfb8877..88e06613997 100644 --- a/apps/files_encryption/settings-admin.php +++ b/apps/files_encryption/settings-admin.php @@ -11,7 +11,7 @@ $tmpl = new OCP\Template('files_encryption', 'settings-admin'); // Check if an adminRecovery account is enabled for recovering files after lost pwd -$recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled', '0'); +$recoveryAdminEnabled = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryAdminEnabled', '0'); $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index ffcb99602e2..09e9df05352 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -20,7 +20,7 @@ $privateKeySet = $session->getPrivateKey() !== false; // did we tried to initialize the keys for this session? $initialized = $session->getInitialized(); -$recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled'); +$recoveryAdminEnabled = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryAdminEnabled'); $recoveryEnabledForUser = $util->recoveryEnabledForUser(); $result = false; diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php index acf408a07f0..076459c562e 100755 --- a/apps/files_encryption/tests/share.php +++ b/apps/files_encryption/tests/share.php @@ -61,7 +61,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \OC_User::useBackend('database'); // enable resharing - \OC_Appconfig::setValue('core', 'shareapi_allow_resharing', 'yes'); + \OC::$server->getAppConfig()->setValue('core', 'shareapi_allow_resharing', 'yes'); // clear share hooks \OC_Hook::clear('OCP\\Share'); @@ -531,7 +531,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); - $publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId'); + $publicShareKeyId = \OC::$server->getAppConfig()->getValue('files_encryption', 'publicShareKeyId'); // check if share key for public exists $this->assertTrue($this->view->file_exists( @@ -662,7 +662,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123'); - $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); + $recoveryKeyId = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryKeyId'); // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); @@ -755,7 +755,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->assertTrue(\OCA\Encryption\Helper::adminEnableRecovery(null, 'test123')); $this->assertTrue(\OCA\Encryption\Helper::adminDisableRecovery('test123')); - $this->assertEquals(0, \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled')); + $this->assertEquals(0, \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryAdminEnabled')); } /** @@ -769,7 +769,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $result = \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123'); $this->assertTrue($result); - $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); + $recoveryKeyId = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryKeyId'); // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); @@ -863,7 +863,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->assertTrue($util->setRecoveryForUser(0)); \OCA\Encryption\Helper::adminDisableRecovery('test123'); - $this->assertEquals(0, \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled')); + $this->assertEquals(0, \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryAdminEnabled')); } /** diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 426caf008ec..1ab89e5e8c6 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -524,6 +524,7 @@ class Google extends \OC\Files\Storage\Common { } public function hasUpdated($path, $time) { + $appConfig = \OC::$server->getAppConfig(); if ($this->is_file($path)) { return parent::hasUpdated($path, $time); } else { @@ -533,7 +534,7 @@ class Google extends \OC\Files\Storage\Common { if ($folder) { $result = false; $folderId = $folder->getId(); - $startChangeId = \OC_Appconfig::getValue('files_external', $this->getId().'cId'); + $startChangeId = $appConfig->getValue('files_external', $this->getId().'cId'); $params = array( 'includeDeleted' => true, 'includeSubscribed' => true, @@ -578,7 +579,7 @@ class Google extends \OC\Files\Storage\Common { break; } } - \OC_Appconfig::setValue('files_external', $this->getId().'cId', $largestChangeId); + $appConfig->setValue('files_external', $this->getId().'cId', $largestChangeId); return $result; } } diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php index 061e60ad8ed..19a2d22b068 100644 --- a/apps/files_sharing/lib/api.php +++ b/apps/files_sharing/lib/api.php @@ -218,7 +218,7 @@ class Api { //allow password protection $shareWith = isset($_POST['password']) ? $_POST['password'] : null; //check public link share - $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); + $publicUploadEnabled = \OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_public_upload', 'yes'); if(isset($_POST['publicUpload']) && $publicUploadEnabled !== 'yes') { return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator"); } @@ -317,7 +317,7 @@ class Api { $shareType = $share['share_type']; $permissions = isset($params['_put']['permissions']) ? (int)$params['_put']['permissions'] : null; - $publicUploadStatus = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); + $publicUploadStatus = \OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_public_upload', 'yes'); $publicUploadEnabled = ($publicUploadStatus === 'yes') ? true : false; @@ -356,7 +356,7 @@ class Api { */ private static function updatePublicUpload($share, $params) { - $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); + $publicUploadEnabled = \OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_public_upload', 'yes'); if($publicUploadEnabled !== 'yes') { return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator"); } diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index f03ac7205a3..e7a5f5024b8 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -2,7 +2,9 @@ // Load other apps for file previews OC_App::loadApps(); -if (\OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { +$appConfig = \OC::$server->getAppConfig(); + +if ($appConfig->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); @@ -151,7 +153,7 @@ if (isset($path)) { $tmpl->assign('dirToken', $linkItem['token']); $tmpl->assign('sharingToken', $token); $allowPublicUploadEnabled = (bool) ($linkItem['permissions'] & OCP\PERMISSION_CREATE); - if (OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') { + if ($appConfig->getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') { $allowPublicUploadEnabled = false; } if ($linkItem['item_type'] !== 'folder') { diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index 7544980e071..6cef7fa3d25 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -722,7 +722,7 @@ class Trashbin { $quota = \OC_Preferences::getValue($user, 'files', 'quota'); $view = new \OC\Files\View('/' . $user); if ($quota === null || $quota === 'default') { - $quota = \OC_Appconfig::getValue('files', 'default_quota'); + $quota = \OC::$server->getAppConfig()->getValue('files', 'default_quota'); } if ($quota === null || $quota === 'none') { $quota = \OC\Files\Filesystem::free_space('/'); diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index 328ed4305f4..286a368b8cc 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -487,7 +487,7 @@ class Storage { $softQuota = true; $quota = \OC_Preferences::getValue($uid, 'files', 'quota'); if ( $quota === null || $quota === 'default') { - $quota = \OC_Appconfig::getValue('files', 'default_quota'); + $quota = \OC::$server->getAppConfig()->getValue('files', 'default_quota'); } if ( $quota === null || $quota === 'none' ) { $quota = \OC\Files\Filesystem::free_space('/'); diff --git a/lib/private/cache/fileglobal.php b/lib/private/cache/fileglobal.php index bd049bba4d0..95b7ceb099f 100644 --- a/lib/private/cache/fileglobal.php +++ b/lib/private/cache/fileglobal.php @@ -81,13 +81,14 @@ class FileGlobal { } static public function gc() { - $last_run = \OC_AppConfig::getValue('core', 'global_cache_gc_lastrun', 0); + $appConfig = \OC::$server->getAppConfig(); + $last_run = $appConfig->getValue('core', 'global_cache_gc_lastrun', 0); $now = time(); if (($now - $last_run) < 300) { // only do cleanup every 5 minutes return; } - \OC_AppConfig::setValue('core', 'global_cache_gc_lastrun', $now); + $appConfig->setValue('core', 'global_cache_gc_lastrun', $now); $cache_dir = self::getCacheDir(); if($cache_dir and is_dir($cache_dir)) { $dh=opendir($cache_dir); diff --git a/lib/private/setup.php b/lib/private/setup.php index 5232398d1d7..17ef75bc7b5 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -94,10 +94,11 @@ class OC_Setup { } if(count($error) == 0) { - OC_Appconfig::setValue('core', 'installedat', microtime(true)); - OC_Appconfig::setValue('core', 'lastupdatedat', microtime(true)); - OC_AppConfig::setValue('core', 'remote_core.css', '/core/minimizer.php'); - OC_AppConfig::setValue('core', 'remote_core.js', '/core/minimizer.php'); + $appConfig = \OC::$server->getAppConfig(); + $appConfig->setValue('core', 'installedat', microtime(true)); + $appConfig->setValue('core', 'lastupdatedat', microtime(true)); + $appConfig->setValue('core', 'remote_core.css', '/core/minimizer.php'); + $appConfig->setValue('core', 'remote_core.js', '/core/minimizer.php'); OC_Group::createGroup('admin'); OC_Group::addToGroup($username, 'admin'); diff --git a/lib/private/util.php b/lib/private/util.php index 0585749d615..246c82a26c7 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -91,9 +91,10 @@ class OC_Util { } public static function getUserQuota($user){ - $userQuota = OC_Preferences::getValue($user, 'files', 'quota', 'default'); + $config = \OC::$server->getConfig(); + $userQuota = $config->getUserValue($user, 'files', 'quota', 'default'); if($userQuota === 'default') { - $userQuota = OC_AppConfig::getValue('files', 'default_quota', 'none'); + $userQuota = $config->getAppValue('files', 'default_quota', 'none'); } if($userQuota === 'none') { return \OC\Files\SPACE_UNLIMITED; diff --git a/remote.php b/remote.php index 2d0088cd903..7884695b3a5 100644 --- a/remote.php +++ b/remote.php @@ -14,7 +14,7 @@ try { } $service=substr($path_info, 1, $pos-1); - $file = OC_AppConfig::getValue('core', 'remote_' . $service); + $file = \OC::$server->getAppConfig()->getValue('core', 'remote_' . $service); if(is_null($file)) { OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND); From 2887fb1f4816546c11a5c9994a293bf78f98081e Mon Sep 17 00:00:00 2001 From: Matthew Caron Date: Fri, 14 Feb 2014 16:09:19 -0500 Subject: [PATCH 19/33] Fit shared videos to viewer, just like images. Issue #1648 --- apps/files_sharing/css/public.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 21f0c82b829..2d569fd77da 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -71,11 +71,18 @@ p.info a { max-width:100%; } +#imgframe video { + max-height:100%; + max-width:100%; +} + /* some margin for the file type icon */ #imgframe .publicpreview { margin-top: 10%; } + + thead { padding-left: 0 !important; /* fixes multiselect bar offset on shared page */ } From 2ab062193a355e87946f310c992d5449eaf558cc Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 10 Feb 2014 16:43:04 +0100 Subject: [PATCH 20/33] catch errors during initial encryption --- apps/files_encryption/hooks/hooks.php | 22 +++++++----- apps/files_encryption/lib/util.php | 51 +++++++++++++++++---------- 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 83abf3ba9de..1eb5f4c41e4 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -109,21 +109,27 @@ class Hooks { } - // Encrypt existing user files: - if ( - $util->encryptAll('/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password']) - ) { + // Encrypt existing user files + try { + $result = $util->encryptAll('/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password']); + } catch (\Exception $ex) { + \OCP\Util::writeLog('Encryption library', 'Initial encryption failed! Error: ' . $ex->getMessage(), \OCP\Util::FATAL); + $util->resetMigrationStatus(); + \OCP\User::logout(); + $result = false; + } + + if ($result) { \OC_Log::write( 'Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" completed' , \OC_Log::INFO ); - } - - // Register successful migration in DB - $util->finishMigration(); + // Register successful migration in DB + $util->finishMigration(); + } } return true; diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index ae3e2a2e15a..ced4b823cf0 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -1186,26 +1186,48 @@ class Util { } /** - * @brief start migration mode to initially encrypt users data + * @brief set migration status + * @param int $status * @return boolean */ - public function beginMigration() { + private function setMigrationStatus($status) { - $return = false; - - $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?'; - $args = array(self::MIGRATION_IN_PROGRESS, $this->userId, self::MIGRATION_OPEN); + $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ?'; + $args = array($status, $this->userId); $query = \OCP\DB::prepare($sql); $manipulatedRows = $query->execute($args); if ($manipulatedRows === 1) { - $return = true; + $result = true; + \OCP\Util::writeLog('Encryption library', "Migration status set to " . self::MIGRATION_OPEN, \OCP\Util::INFO); + } else { + $result = false; + \OCP\Util::writeLog('Encryption library', "Could not set migration status to " . self::MIGRATION_OPEN, \OCP\Util::WARN); + } + + return $result; + } + + /** + * @brief start migration mode to initially encrypt users data + * @return boolean + */ + public function beginMigration() { + + $result = $this->setMigrationStatus(self::MIGRATION_IN_PROGRESS); + + if ($result) { \OCP\Util::writeLog('Encryption library', "Start migration to encryption mode for " . $this->userId, \OCP\Util::INFO); } else { \OCP\Util::writeLog('Encryption library', "Could not activate migration mode for " . $this->userId . ". Probably another process already started the initial encryption", \OCP\Util::WARN); } - return $return; + return $result; + } + + public function resetMigrationStatus() { + return $this->setMigrationStatus(self::MIGRATION_OPEN); + } /** @@ -1213,22 +1235,15 @@ class Util { * @return boolean */ public function finishMigration() { + $result = $this->setMigrationStatus(self::MIGRATION_COMPLETED); - $return = false; - - $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?'; - $args = array(self::MIGRATION_COMPLETED, $this->userId, self::MIGRATION_IN_PROGRESS); - $query = \OCP\DB::prepare($sql); - $manipulatedRows = $query->execute($args); - - if ($manipulatedRows === 1) { - $return = true; + if ($result) { \OCP\Util::writeLog('Encryption library', "Finish migration successfully for " . $this->userId, \OCP\Util::INFO); } else { \OCP\Util::writeLog('Encryption library', "Could not deactivate migration mode for " . $this->userId, \OCP\Util::WARN); } - return $return; + return $result; } /** From f2f5769df7d4c2b33a847e86a71d94d5c689decd Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 10 Feb 2014 17:23:54 +0100 Subject: [PATCH 21/33] catch errors during decryption --- apps/files_encryption/lib/util.php | 40 +++++++++----- apps/files_encryption/tests/util.php | 81 +++++++++++++++++++++++++++- settings/ajax/decryptall.php | 9 +++- 3 files changed, 113 insertions(+), 17 deletions(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index ced4b823cf0..f3f69997f2c 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -316,7 +316,8 @@ class Util { $found = array( 'plain' => array(), 'encrypted' => array(), - 'legacy' => array() + 'legacy' => array(), + 'broken' => array(), ); } @@ -327,10 +328,7 @@ class Util { if(is_resource($handle)) { while (false !== ($file = readdir($handle))) { - if ( - $file !== "." - && $file !== ".." - ) { + if ($file !== "." && $file !== "..") { $filePath = $directory . '/' . $this->view->getRelativePath('/' . $file); $relPath = \OCA\Encryption\Helper::stripUserFilesPath($filePath); @@ -357,15 +355,23 @@ class Util { // NOTE: This is inefficient; // scanning every file like this // will eat server resources :( - if ( - Keymanager::getFileKey($this->view, $this, $relPath) - && $isEncryptedPath - ) { - - $found['encrypted'][] = array( - 'name' => $file, - 'path' => $filePath - ); + if ($isEncryptedPath) { + + $fileKey = Keymanager::getFileKey($this->view, $this, $relPath); + $shareKey = Keymanager::getShareKey($this->view, $this->userId, $this, $relPath); + // if file is encrypted but now file key is available, throw exception + if ($fileKey === false || $shareKey === false) { + \OCP\Util::writeLog('encryption library', 'No keys available to decrypt the file: ' . $filePath, \OCP\Util::ERROR); + $found['broken'][] = array( + 'name' => $file, + 'path' => $filePath, + ); + } else { + $found['encrypted'][] = array( + 'name' => $file, + 'path' => $filePath, + ); + } // If the file uses old // encryption system @@ -771,6 +777,12 @@ class Util { $successful = false; } + // if there are broken encrypted files than the complete decryption + // was not successful + if (!empty($found['broken'])) { + $successful = false; + } + if ($successful) { $this->view->deleteAll($this->keyfilesPath); $this->view->deleteAll($this->shareKeysPath); diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php index 228f7df1b90..321bdc76f8b 100755 --- a/apps/files_encryption/tests/util.php +++ b/apps/files_encryption/tests/util.php @@ -64,6 +64,8 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { function setUp() { + // login user + \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); \OC_User::setUserId(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); $this->userId = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1; $this->pass = \Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1; @@ -358,9 +360,12 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { $fileInfoEncrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); $this->assertTrue($fileInfoEncrypted instanceof \OC\Files\FileInfo); + $this->assertEquals($fileInfoEncrypted['encrypted'], 1); - // encrypt all unencrypted files - $util->decryptAll('/' . $this->userId . '/' . 'files'); + // decrypt all encrypted files + $result = $util->decryptAll('/' . $this->userId . '/' . 'files'); + + $this->assertTrue($result); $fileInfoUnencrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); @@ -369,11 +374,83 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { // check if mtime and etags unchanged $this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']); $this->assertEquals($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']); + // file should no longer be encrypted + $this->assertEquals(0, $fileInfoUnencrypted['encrypted']); $this->view->unlink($this->userId . '/files/' . $filename); } + function testDescryptAllWithBrokenFiles() { + + $file1 = "/decryptAll1" . uniqid() . ".txt"; + $file2 = "/decryptAll2" . uniqid() . ".txt"; + + $util = new Encryption\Util($this->view, $this->userId); + + $this->view->file_put_contents($this->userId . '/files/' . $file1, $this->dataShort); + $this->view->file_put_contents($this->userId . '/files/' . $file2, $this->dataShort); + + $fileInfoEncrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); + $fileInfoEncrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); + + $this->assertTrue($fileInfoEncrypted1 instanceof \OC\Files\FileInfo); + $this->assertTrue($fileInfoEncrypted2 instanceof \OC\Files\FileInfo); + $this->assertEquals($fileInfoEncrypted1['encrypted'], 1); + $this->assertEquals($fileInfoEncrypted2['encrypted'], 1); + + // rename keyfile for file1 so that the decryption for file1 fails + // Expected behaviour: decryptAll() returns false, file2 gets decrypted anyway + $this->view->rename($this->userId . '/files_encryption/keyfiles/' . $file1 . '.key', + $this->userId . '/files_encryption/keyfiles/' . $file1 . '.key.moved'); + + // decrypt all encrypted files + $result = $util->decryptAll('/' . $this->userId . '/' . 'files'); + + $this->assertFalse($result); + + $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); + $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); + + $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo); + $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo); + + // file1 should be still encrypted; file2 should be decrypted + $this->assertEquals(1, $fileInfoUnencrypted1['encrypted']); + $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']); + + // keyfiles and share keys should still exist + $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/keyfiles/')); + $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/share-keys/')); + + // rename the keyfile for file1 back + $this->view->rename($this->userId . '/files_encryption/keyfiles/' . $file1 . '.key.moved', + $this->userId . '/files_encryption/keyfiles/' . $file1 . '.key'); + + // try again to decrypt all encrypted files + $result = $util->decryptAll('/' . $this->userId . '/' . 'files'); + + $this->assertTrue($result); + + $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); + $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); + + $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo); + $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo); + + // now both files should be decrypted + $this->assertEquals(0, $fileInfoUnencrypted1['encrypted']); + $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']); + + // keyfiles and share keys should be deleted + $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/keyfiles/')); + $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/share-keys/')); + + $this->view->unlink($this->userId . '/files/' . $file1); + $this->view->unlink($this->userId . '/files/' . $file2); + + } + /** * @large */ diff --git a/settings/ajax/decryptall.php b/settings/ajax/decryptall.php index ebc17aacfaa..d7c104ab151 100644 --- a/settings/ajax/decryptall.php +++ b/settings/ajax/decryptall.php @@ -16,7 +16,14 @@ $util = new \OCA\Encryption\Util($view, \OCP\User::getUser()); $result = $util->initEncryption($params); if ($result !== false) { - $successful = $util->decryptAll(); + + try { + $successful = $util->decryptAll(); + } catch (\Exception $ex) { + \OCP\Util::writeLog('encryption library', "Decryption finished unexpected: " . $ex->getMessage(), \OCP\Util::ERROR); + $successful = false; + } + if ($successful === true) { \OCP\JSON::success(array('data' => array('message' => 'Files decrypted successfully'))); } else { From 6778dc5a4a92ba4e808c072a9eae48ff91b6ec74 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 11 Feb 2014 12:44:06 +0100 Subject: [PATCH 22/33] don't block login forever if we are stuck in the middle of the initial encryption --- apps/files_encryption/ajax/getMigrationStatus.php | 8 +++----- apps/files_encryption/appinfo/app.php | 1 + apps/files_encryption/hooks/hooks.php | 7 +++---- apps/files_encryption/js/detect-migration.js | 6 +++++- apps/files_encryption/js/encryption.js | 12 ++++++++++++ 5 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 apps/files_encryption/js/encryption.js diff --git a/apps/files_encryption/ajax/getMigrationStatus.php b/apps/files_encryption/ajax/getMigrationStatus.php index 17469a1af0c..7c9e0dcc51c 100644 --- a/apps/files_encryption/ajax/getMigrationStatus.php +++ b/apps/files_encryption/ajax/getMigrationStatus.php @@ -13,16 +13,14 @@ use OCA\Encryption\Util; $loginname = isset($_POST['user']) ? $_POST['user'] : ''; $password = isset($_POST['password']) ? $_POST['password'] : ''; -$migrationCompleted = true; +$migrationStatus = Util::MIGRATION_COMPLETED; if ($loginname !== '' && $password !== '') { $username = \OCP\User::checkPassword($loginname, $password); if ($username) { $util = new Util(new \OC_FilesystemView('/'), $username); - if ($util->getMigrationStatus() !== Util::MIGRATION_COMPLETED) { - $migrationCompleted = false; - } + $migrationStatus = $util->getMigrationStatus(); } } -\OCP\JSON::success(array('data' => array('migrationCompleted' => $migrationCompleted))); +\OCP\JSON::success(array('data' => array('migrationStatus' => $migrationStatus))); diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index fd9aa429b01..21de421c195 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -10,6 +10,7 @@ OC::$CLASSPATH['OCA\Encryption\Session'] = 'files_encryption/lib/session.php'; OC::$CLASSPATH['OCA\Encryption\Capabilities'] = 'files_encryption/lib/capabilities.php'; OC::$CLASSPATH['OCA\Encryption\Helper'] = 'files_encryption/lib/helper.php'; +\OCP\Util::addscript('files_encryption', 'encryption'); \OCP\Util::addscript('files_encryption', 'detect-migration'); if (!OC_Config::getValue('maintenance', false)) { diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 1eb5f4c41e4..50f322ddef4 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -85,10 +85,9 @@ class Hooks { $ready = $util->beginMigration(); } elseif ($migrationStatus === Util::MIGRATION_IN_PROGRESS) { // refuse login as long as the initial encryption is running - while ($migrationStatus === Util::MIGRATION_IN_PROGRESS) { - sleep(60); - $migrationStatus = $util->getMigrationStatus(); - } + sleep(5); + \OCP\User::logout(); + return false; } // If migration not yet done diff --git a/apps/files_encryption/js/detect-migration.js b/apps/files_encryption/js/detect-migration.js index 301e77f24f7..f5627edf4e4 100644 --- a/apps/files_encryption/js/detect-migration.js +++ b/apps/files_encryption/js/detect-migration.js @@ -17,10 +17,14 @@ $(document).ready(function(){ data: {user: user, password: password}, async: false, success: function(response) { - if (response.data.migrationCompleted === false) { + if (response.data.migrationStatus === OC.Encryption.MIGRATION_OPEN) { var message = t('files_encryption', 'Initial encryption started... This can take some time. Please wait.'); $('#messageText').text(message); $('#message').removeClass('hidden').addClass('update'); + } else if (response.data.migrationStatus === OC.Encryption.MIGRATION_IN_PROGRESS) { + var message = t('files_encryption', 'Initial encryption running... Please try again later.'); + $('#messageText').text(message); + $('#message').removeClass('hidden').addClass('update'); } } }); diff --git a/apps/files_encryption/js/encryption.js b/apps/files_encryption/js/encryption.js new file mode 100644 index 00000000000..65ffabe55e6 --- /dev/null +++ b/apps/files_encryption/js/encryption.js @@ -0,0 +1,12 @@ +/** + * Copyright (c) 2014 + * Bjoern Schiessle + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +OC.Encryption={ + MIGRATION_OPEN:0, + MIGRATION_COMPLETED:1, + MIGRATION_IN_PROGRESS:-1, +}; From 049e03c2b92e10ef94d1f7bc900e74f078a56a9b Mon Sep 17 00:00:00 2001 From: tomneedham Date: Mon, 17 Feb 2014 10:58:27 +0000 Subject: [PATCH 23/33] Finish basic testing of user export --- tests/lib/migrate.php | 69 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/tests/lib/migrate.php b/tests/lib/migrate.php index 5c6c9ebe7be..4b20173ba5f 100644 --- a/tests/lib/migrate.php +++ b/tests/lib/migrate.php @@ -9,14 +9,68 @@ class Test_Migrate extends PHPUnit_Framework_TestCase { public $users; + public $tmpfiles = array(); - public function testUserSelfExport(){ + /** + * @breif Generates a test user and sets up their file system + * @return string the test users id + */ + public function generateUser() { + $username = uniqid(); + \OC_User::createUser($username, 'password'); + \OC_Util::tearDownFS(); + \OC_User::setUserId(''); + \OC\Files\Filesystem::tearDown(); + \OC_Util::setupFS($username); + $this->users[] = $username; + return $username; + } + + /** + * @breif validates an export for a user + * @breif checks for existence of export_info.json and file folder + * @param string $exportedUser the user that was exported + * @param string $path the path to the .zip export + */ + public function validateUserExport($exportedBy, $exportedUser, $path) { + $this->assertTrue(file_exists($path)); + // Extract + $extract = get_temp_dir() . '/oc_import_' . uniqid(); + //mkdir($extract); + $this->tmpfiles[] = $extract; + $zip = new ZipArchive; + $zip->open($path); + $zip->extractTo($extract); + $zip->close(); + $this->assertTrue(file_exists($extract.'/export_info.json')); + $exportInfo = file_get_contents($extract.'/export_info.json'); + $exportInfo = json_decode($exportInfo); + $this->assertNotNull($exportInfo); + $this->assertEquals($exportedUser, $exportInfo->exporteduser); + $this->assertEquals($exportedBy, $exportInfo->exportedby); + $this->assertTrue(file_exists($extract.'/'.$exportedUser.'/files')); + } + + public function testUserSelfExport() { // Create a user - $user = uniqid(); - $u = new OC_User(); - $u->createUser($user, 'password'); - $this->users[] = $user; - $exportLocation = \OC_Migrate::export($user); + $user = $this->generateUser(); + \OC_User::setUserId($user); + $export = \OC_Migrate::export($user); + // Check it succeeded and exists + $this->assertTrue(json_decode($export)->success); + // Validate the export + $this->validateUserExport($user, $user, json_decode($export)->data); + } + + public function testUserOtherExport() { + $user = $this->generateUser(); + $user2 = $this->generateUser(); + \OC_User::setUserId($user2); + $export = \OC_Migrate::export($user); + // Check it succeeded and exists + $this->assertTrue(json_decode($export)->success); + // Validate the export + $this->validateUserExport($user2, $user, json_decode($export)->data); } public function tearDown() { @@ -24,6 +78,9 @@ class Test_Migrate extends PHPUnit_Framework_TestCase { foreach($this->users as $user) { $u->deleteUser($user); } + foreach($this->tmpfiles as $file) { + \OC_Helper::rmdirr($file); + } } From fe9c98208101b517057906bf0a0faf787dd87276 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 17 Feb 2014 14:34:15 +0100 Subject: [PATCH 24/33] Removed quota question --- issue_template.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/issue_template.md b/issue_template.md index bea1f5c4c2d..ec14a8b3463 100644 --- a/issue_template.md +++ b/issue_template.md @@ -33,8 +33,6 @@ Insert your config.php content here **Are you using external storage, if yes which one:** local/smb/sftp/... -**Are you using quota:** yes/no - **Are you using encryption:** yes/no ### Client configuration From 8a2cd0355da540759e7a1edcfe67fb4715032ad0 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 17 Feb 2014 16:45:22 +0100 Subject: [PATCH 25/33] Use the proper content-type We should use the proper content-type `application/xml` instead of the default `text/html` here. Backport requested. --- ocs/providers.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ocs/providers.php b/ocs/providers.php index bf94b85dcfb..2c62f767ad3 100644 --- a/ocs/providers.php +++ b/ocs/providers.php @@ -23,6 +23,8 @@ require_once '../lib/base.php'; +header('Content-type: application/xml'); + $url=OCP\Util::getServerProtocol().'://'.substr(OCP\Util::getServerHost().OCP\Util::getRequestUri(), 0, -17).'ocs/v1.php/'; echo(' From 54f9db403ff20f9941fb32d88686fa733645636e Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 17 Feb 2014 17:19:48 +0100 Subject: [PATCH 26/33] LDAP: improve wizard strings, fixes #5567 --- apps/user_ldap/templates/part.wizard-groupfilter.php | 2 +- apps/user_ldap/templates/part.wizard-loginfilter.php | 2 +- apps/user_ldap/templates/part.wizard-userfilter.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/user_ldap/templates/part.wizard-groupfilter.php b/apps/user_ldap/templates/part.wizard-groupfilter.php index 0cc4dfa572a..e460997b1bf 100644 --- a/apps/user_ldap/templates/part.wizard-groupfilter.php +++ b/apps/user_ldap/templates/part.wizard-groupfilter.php @@ -1,7 +1,7 @@

- t('Limit the access to %s to groups meeting this criteria:', $theme->getName()));?> + t('Groups meeting these criteria are available in %s:', $theme->getName()));?>

- t('What attribute shall be used as login name:'));?> + t('Users login with this attribute:'));?>

- t('Limit the access to %s to users meeting this criteria:', $theme->getName()));?> + t('Limit %s access to users meeting these criteria:', $theme->getName()));?>