diff options
author | Bart Visscher <bartv@thisnet.nl> | 2013-06-27 17:51:37 +0200 |
---|---|---|
committer | Bart Visscher <bartv@thisnet.nl> | 2013-06-27 17:54:17 +0200 |
commit | c6bbccc776ee9ea1112d3cfab54c9f2c95540130 (patch) | |
tree | 799c938b8d314a4f49fdeba43f5b42e212f77fcd /lib | |
parent | 969e43c87b7afb6184846fe27849167c9c6f5eab (diff) | |
parent | 6fcee1ee117a167aa0c526ca39effbf086d10991 (diff) | |
download | nextcloud-server-c6bbccc776ee9ea1112d3cfab54c9f2c95540130.tar.gz nextcloud-server-c6bbccc776ee9ea1112d3cfab54c9f2c95540130.zip |
Merge branch 'master' into convert-oc_config
Conflicts:
lib/config.php
lib/setup.php
Diffstat (limited to 'lib')
44 files changed, 609 insertions, 312 deletions
diff --git a/lib/app.php b/lib/app.php index c6f6e92e60e..f974dd9f594 100644 --- a/lib/app.php +++ b/lib/app.php @@ -174,7 +174,8 @@ class OC_App{ $apps=array('files'); $sql = 'SELECT `appid` FROM `*PREFIX*appconfig`' .' WHERE `configkey` = \'enabled\' AND `configvalue`=\'yes\''; - if (OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { //FIXME oracle hack + if (OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { + //FIXME oracle hack: need to explicitly cast CLOB to CHAR for comparison $sql = 'SELECT `appid` FROM `*PREFIX*appconfig`' .' WHERE `configkey` = \'enabled\' AND to_char(`configvalue`)=\'yes\''; } @@ -348,7 +349,8 @@ class OC_App{ $settings = array(); // by default, settings only contain the help menu - if(OC_Config::getValue('knowledgebaseenabled', true)==true) { + if(OC_Util::getEditionString() === '' && + OC_Config::getValue('knowledgebaseenabled', true)==true) { $settings = array( array( "id" => "help", diff --git a/lib/autoloader.php b/lib/autoloader.php index 9615838a9a2..21170639092 100644 --- a/lib/autoloader.php +++ b/lib/autoloader.php @@ -96,8 +96,8 @@ class Autoloader { } else { foreach ($this->prefixPaths as $prefix => $dir) { if (0 === strpos($class, $prefix)) { - $path = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php'; - $path = str_replace('_', DIRECTORY_SEPARATOR, $path); + $path = str_replace('\\', '/', $class) . '.php'; + $path = str_replace('_', '/', $path); $paths[] = $dir . '/' . $path; } } diff --git a/lib/base.php b/lib/base.php index a6e4a47dbf5..fd4870974fe 100644 --- a/lib/base.php +++ b/lib/base.php @@ -235,10 +235,7 @@ class OC { $currentVersion = implode('.', OC_Util::getVersion()); if (version_compare($currentVersion, $installedVersion, '>')) { if ($showTemplate && !OC_Config::getValue('maintenance', false)) { - OC_Config::setValue('maintenance', true); - OC_Log::write('core', - 'starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, - OC_Log::WARN); + OC_Config::setValue('theme', ''); $minimizerCSS = new OC_Minimizer_CSS(); $minimizerCSS->clearCache(); $minimizerJS = new OC_Minimizer_JS(); @@ -291,14 +288,14 @@ class OC { $cookie_path = OC::$WEBROOT ?: '/'; ini_set('session.cookie_path', $cookie_path); + //set the session object to a dummy session so code relying on the session existing still works + self::$session = new \OC\Session\Memory(''); + try{ // set the session name to the instance id - which is unique self::$session = new \OC\Session\Internal(OC_Util::getInstanceId()); // if session cant be started break with http 500 error }catch (Exception $e){ - //set the session object to a dummy session so code relying on the session existing still works - self::$session = new \OC\Session\Memory(''); - OC_Log::write('core', 'Session could not be initialized', OC_Log::ERROR); diff --git a/lib/config.php b/lib/config.php index a3663949d16..e204de0baee 100644 --- a/lib/config.php +++ b/lib/config.php @@ -166,5 +166,6 @@ class Config { } // Prevent others from reading the config @chmod($this->configFilename, 0640); + OC_Util::clearOpcodeCache(); } } diff --git a/lib/connector/sabre/locks.php b/lib/connector/sabre/locks.php index e58e584fb41..7aca2e43712 100644 --- a/lib/connector/sabre/locks.php +++ b/lib/connector/sabre/locks.php @@ -45,7 +45,12 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { // but otherwise reading locks from SQLite Databases will return // nothing $query = 'SELECT * FROM `*PREFIX*locks`' - .' WHERE `userid` = ? AND (`created` + `timeout`) > '.time().' AND (( `uri` = ?)'; + .' WHERE `userid` = ? AND (`created` + `timeout`) > '.time().' AND (( `uri` = ?)'; + if (OC_Config::getValue( "dbtype") === 'oci') { + //FIXME oracle hack: need to explicitly cast CLOB to CHAR for comparison + $query = 'SELECT * FROM `*PREFIX*locks`' + .' WHERE `userid` = ? AND (`created` + `timeout`) > '.time().' AND (( to_char(`uri`) = ?)'; + } $params = array(OC_User::getUser(), $uri); // We need to check locks for every part in the uri. @@ -60,23 +65,31 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { if ($currentPath) $currentPath.='/'; $currentPath.=$part; - - $query.=' OR (`depth` != 0 AND `uri` = ?)'; + //FIXME oracle hack: need to explicitly cast CLOB to CHAR for comparison + if (OC_Config::getValue( "dbtype") === 'oci') { + $query.=' OR (`depth` != 0 AND to_char(`uri`) = ?)'; + } else { + $query.=' OR (`depth` != 0 AND `uri` = ?)'; + } $params[] = $currentPath; } if ($returnChildLocks) { - $query.=' OR (`uri` LIKE ?)'; + //FIXME oracle hack: need to explicitly cast CLOB to CHAR for comparison + if (OC_Config::getValue( "dbtype") === 'oci') { + $query.=' OR (to_char(`uri`) LIKE ?)'; + } else { + $query.=' OR (`uri` LIKE ?)'; + } $params[] = $uri . '/%'; } $query.=')'; - $stmt = OC_DB::prepare( $query ); - $result = $stmt->execute( $params ); - + $result = OC_DB::executeAudited( $query, $params ); + $lockList = array(); while( $row = $result->fetchRow()) { @@ -113,14 +126,17 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { $locks = $this->getLocks($uri, false); $exists = false; foreach($locks as $lock) { - if ($lock->token == $lockInfo->token) $exists = true; + if ($lock->token == $lockInfo->token) { + $exists = true; + break; + } } if ($exists) { - $query = OC_DB::prepare( 'UPDATE `*PREFIX*locks`' - .' SET `owner` = ?, `timeout` = ?, `scope` = ?, `depth` = ?, `uri` = ?, `created` = ?' - .' WHERE `userid` = ? AND `token` = ?' ); - $result = $query->execute( array( + $sql = 'UPDATE `*PREFIX*locks`' + .' SET `owner` = ?, `timeout` = ?, `scope` = ?, `depth` = ?, `uri` = ?, `created` = ?' + .' WHERE `userid` = ? AND `token` = ?'; + $result = OC_DB::executeAudited( $sql, array( $lockInfo->owner, $lockInfo->timeout, $lockInfo->scope, @@ -131,10 +147,10 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { $lockInfo->token) ); } else { - $query = OC_DB::prepare( 'INSERT INTO `*PREFIX*locks`' - .' (`userid`,`owner`,`timeout`,`scope`,`depth`,`uri`,`created`,`token`)' - .' VALUES (?,?,?,?,?,?,?,?)' ); - $result = $query->execute( array( + $sql = 'INSERT INTO `*PREFIX*locks`' + .' (`userid`,`owner`,`timeout`,`scope`,`depth`,`uri`,`created`,`token`)' + .' VALUES (?,?,?,?,?,?,?,?)'; + $result = OC_DB::executeAudited( $sql, array( OC_User::getUser(), $lockInfo->owner, $lockInfo->timeout, @@ -159,8 +175,12 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { */ public function unlock($uri, Sabre_DAV_Locks_LockInfo $lockInfo) { - $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*locks` WHERE `userid` = ? AND `uri` = ? AND `token` = ?' ); - $result = $query->execute( array(OC_User::getUser(), $uri, $lockInfo->token)); + $sql = 'DELETE FROM `*PREFIX*locks` WHERE `userid` = ? AND `uri` = ? AND `token` = ?'; + if (OC_Config::getValue( "dbtype") === 'oci') { + //FIXME oracle hack: need to explicitly cast CLOB to CHAR for comparison + $sql = 'DELETE FROM `*PREFIX*locks` WHERE `userid` = ? AND to_char(`uri`) = ? AND `token` = ?'; + } + $result = OC_DB::executeAudited( $sql, array(OC_User::getUser(), $uri, $lockInfo->token)); return $result->numRows() === 1; diff --git a/lib/connector/sabre/maintenanceplugin.php b/lib/connector/sabre/maintenanceplugin.php index 329fa4443ad..2eda269afc2 100644 --- a/lib/connector/sabre/maintenanceplugin.php +++ b/lib/connector/sabre/maintenanceplugin.php @@ -50,6 +50,9 @@ class OC_Connector_Sabre_MaintenancePlugin extends Sabre_DAV_ServerPlugin if (OC_Config::getValue('maintenance', false)) { throw new Sabre_DAV_Exception_ServiceUnavailable(); } + if (OC::checkUpgrade(false)) { + throw new Sabre_DAV_Exception_ServiceUnavailable('Upgrade needed'); + } return true; } diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index 1ffa048d6b2..0bffa58af78 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -189,8 +189,8 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr */ public function getProperties($properties) { if (is_null($this->property_cache)) { - $query = OC_DB::prepare( 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?' ); - $result = $query->execute( array( OC_User::getUser(), $this->path )); + $sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?'; + $result = OC_DB::executeAudited( $sql, array( OC_User::getUser(), $this->path ) ); $this->property_cache = array(); while( $row = $result->fetchRow()) { diff --git a/lib/db.php b/lib/db.php index 61836551833..a6b81aaba69 100644 --- a/lib/db.php +++ b/lib/db.php @@ -23,7 +23,8 @@ class DatabaseException extends Exception{ private $query; - public function __construct($message, $query){ + //FIXME getQuery seems to be unused, maybe use parent constructor with $message, $code and $previous + public function __construct($message, $query = null){ parent::__construct($message); $this->query = $query; } @@ -392,9 +393,59 @@ class OC_DB { } /** + * @brief execute a prepared statement, on error write log and throw exception + * @param mixed $stmt PDOStatementWrapper | MDB2_Statement_Common , + * an array with 'sql' and optionally 'limit' and 'offset' keys + * .. or a simple sql query string + * @param array $parameters + * @return result + * @throws DatabaseException + */ + static public function executeAudited( $stmt, array $parameters = null) { + if (is_string($stmt)) { + // convert to an array with 'sql' + if (stripos($stmt,'LIMIT') !== false) { //OFFSET requires LIMIT, se we only neet to check for LIMIT + // TODO try to convert LIMIT OFFSET notation to parameters, see fixLimitClauseForMSSQL + $message = 'LIMIT and OFFSET are forbidden for portability reasons,' + . ' pass an array with \'limit\' and \'offset\' instead'; + throw new DatabaseException($message); + } + $stmt = array('sql' => $stmt, 'limit' => null, 'offset' => null); + } + if (is_array($stmt)){ + // convert to prepared statement + if ( ! array_key_exists('sql', $stmt) ) { + $message = 'statement array must at least contain key \'sql\''; + throw new DatabaseException($message); + } + if ( ! array_key_exists('limit', $stmt) ) { + $stmt['limit'] = null; + } + if ( ! array_key_exists('limit', $stmt) ) { + $stmt['offset'] = null; + } + $stmt = self::prepare($stmt['sql'], $stmt['limit'], $stmt['offset']); + } + self::raiseExceptionOnError($stmt, 'Could not prepare statement'); + if ($stmt instanceof PDOStatementWrapper || $stmt instanceof MDB2_Statement_Common) { + $result = $stmt->execute($parameters); + self::raiseExceptionOnError($result, 'Could not execute statement'); + } else { + if (is_object($stmt)) { + $message = 'Expected a prepared statement or array got ' . get_class($stmt); + } else { + $message = 'Expected a prepared statement or array got ' . gettype($stmt); + } + throw new DatabaseException($message); + } + return $result; + } + + /** * @brief gets last value of autoincrement * @param string $table The optional table name (will replace *PREFIX*) and add sequence suffix * @return int id + * @throws DatabaseException * * MDB2 lastInsertID() * @@ -404,25 +455,27 @@ class OC_DB { public static function insertid($table=null) { self::connect(); $type = OC_Config::getValue( "dbtype", "sqlite" ); - if( $type == 'pgsql' ) { - $query = self::prepare('SELECT lastval() AS id'); - $row = $query->execute()->fetchRow(); + if( $type === 'pgsql' ) { + $result = self::executeAudited('SELECT lastval() AS id'); + $row = $result->fetchRow(); + self::raiseExceptionOnError($row, 'fetching row for insertid failed'); return $row['id']; - } - if( $type == 'mssql' ) { + } else if( $type === 'mssql' || $type === 'oci') { if($table !== null) { $prefix = OC_Config::getValue( "dbtableprefix", "oc_" ); $table = str_replace( '*PREFIX*', $prefix, $table ); } - return self::$connection->lastInsertId($table); - }else{ + $result = self::$connection->lastInsertId($table); + } else { if($table !== null) { $prefix = OC_Config::getValue( "dbtableprefix", "oc_" ); $suffix = OC_Config::getValue( "dbsequencesuffix", "_id_seq" ); $table = str_replace( '*PREFIX*', $prefix, $table ).$suffix; } - return self::$connection->lastInsertId($table); + $result = self::$connection->lastInsertId($table); } + self::raiseExceptionOnError($result, 'insertid failed'); + return $result; } /** @@ -512,11 +565,9 @@ class OC_DB { //clean up memory unlink( $file2 ); + + self::raiseExceptionOnError($definition,'Failed to parse the database definition'); - // Die in case something went wrong - if( $definition instanceof MDB2_Schema_Error ) { - OC_Template::printErrorPage( $definition->getMessage().': '.$definition->getUserInfo() ); - } if(OC_Config::getValue('dbtype', 'sqlite')==='oci') { unset($definition['charset']); //or MDB2 tries SHUTDOWN IMMEDIATE $oldname = $definition['name']; @@ -528,11 +579,7 @@ class OC_DB { $ret=self::$schema->createDatabase( $definition ); - // Die in case something went wrong - if( $ret instanceof MDB2_Error ) { - OC_Template::printErrorPage( self::$MDB2->getDebugOutput().' '.$ret->getMessage() . ': ' - . $ret->getUserInfo() ); - } + self::raiseExceptionOnError($ret,'Failed to create the database structure'); return true; } @@ -547,18 +594,17 @@ class OC_DB { $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" ); self::connectScheme(); + + if(OC_Config::getValue('dbtype', 'sqlite')==='oci') { + //set dbname, it is unset because oci uses 'service' to connect + self::$schema->db->database_name=self::$schema->db->dsn['username']; + } // read file $content = file_get_contents( $file ); $previousSchema = self::$schema->getDefinitionFromDatabase(); - if (PEAR::isError($previousSchema)) { - $error = $previousSchema->getMessage(); - $detail = $previousSchema->getDebugInfo(); - $message = 'Failed to get existing database structure for updating ('.$error.', '.$detail.')'; - OC_Log::write('core', $message, OC_Log::FATAL); - throw new Exception($message); - } + self::raiseExceptionOnError($previousSchema,'Failed to get existing database structure for updating'); // Make changes and save them to an in-memory file $file2 = 'static://db_scheme'; @@ -576,19 +622,19 @@ class OC_DB { $content = str_replace( '<default>0000-00-00 00:00:00</default>', '<default>CURRENT_TIMESTAMP</default>', $content ); } + if(OC_Config::getValue('dbtype', 'sqlite')==='oci') { + unset($previousSchema['charset']); //or MDB2 tries SHUTDOWN IMMEDIATE + $oldname = $previousSchema['name']; + $previousSchema['name']=OC_Config::getValue( "dbuser", $oldname ); + //TODO check identifiers are at most 30 chars long + } file_put_contents( $file2, $content ); $op = self::$schema->updateDatabase($file2, $previousSchema, array(), false); //clean up memory unlink( $file2 ); - if (PEAR::isError($op)) { - $error = $op->getMessage(); - $detail = $op->getDebugInfo(); - $message = 'Failed to update database structure ('.$error.', '.$detail.')'; - OC_Log::write('core', $message, OC_Log::FATAL); - throw new Exception($message); - } + self::raiseExceptionOnError($op,'Failed to update database structure'); return true; } @@ -641,15 +687,9 @@ class OC_DB { } $query = substr($query, 0, strlen($query) - 5); try { - $stmt = self::prepare($query); - $result = $stmt->execute($inserts); - - } catch(PDOException $e) { - $entry = 'DB Error: "'.$e->getMessage() . '"<br />'; - $entry .= 'Offending command was: ' . $query . '<br />'; - OC_Log::write('core', $entry, OC_Log::FATAL); - error_log('DB error: '.$entry); - OC_Template::printErrorPage( $entry ); + $result = self::executeAudited($query, $inserts); + } catch(DatabaseException $e) { + OC_Template::printExceptionErrorPage( $e ); } if((int)$result->numRows() === 0) { @@ -674,16 +714,12 @@ class OC_DB { } try { - $result = self::prepare($query); + $result = self::executeAudited($query, $inserts); } catch(PDOException $e) { - $entry = 'DB Error: "'.$e->getMessage() . '"<br />'; - $entry .= 'Offending command was: ' . $query.'<br />'; - OC_Log::write('core', $entry, OC_Log::FATAL); - error_log('DB error: ' . $entry); - OC_Template::printErrorPage( $entry ); + OC_Template::printExceptionErrorPage( $e ); } - return $result->execute($inserts); + return $result; } /** @@ -891,7 +927,32 @@ class OC_DB { return false; } } + /** + * check if a result is an error and throws an exception, works with MDB2 and PDOException + * @param mixed $result + * @param string message + * @return void + * @throws DatabaseException + */ + public static function raiseExceptionOnError($result, $message = null) { + if(self::isError($result)) { + if ($message === null) { + $message = self::getErrorMessage($result); + } else { + $message .= ', Root cause:' . self::getErrorMessage($result); + } + throw new DatabaseException($message, self::getErrorCode($result)); + } + } + public static function getErrorCode($error) { + if ( self::$backend==self::BACKEND_MDB2 and PEAR::isError($error) ) { + $code = $error->getCode(); + } elseif ( self::$backend==self::BACKEND_PDO and self::$PDO ) { + $code = self::$PDO->errorCode(); + } + return $code; + } /** * returns the error code and message as a string for logging * works with MDB2 and PDOException @@ -901,9 +962,7 @@ class OC_DB { public static function getErrorMessage($error) { if ( self::$backend==self::BACKEND_MDB2 and PEAR::isError($error) ) { $msg = $error->getCode() . ': ' . $error->getMessage(); - if (defined('DEBUG') && DEBUG) { - $msg .= '(' . $error->getDebugInfo() . ')'; - } + $msg .= ' (' . $error->getDebugInfo() . ')'; } elseif (self::$backend==self::BACKEND_PDO and self::$PDO) { $msg = self::$PDO->errorCode() . ': '; $errorInfo = self::$PDO->errorInfo(); diff --git a/lib/defaults.php b/lib/defaults.php new file mode 100644 index 00000000000..7dc6fbd0ada --- /dev/null +++ b/lib/defaults.php @@ -0,0 +1,74 @@ +<?php + +/** + * Default strings and values which differ between the enterprise and the + * community edition. Use the get methods to always get the right strings. + */ + +class OC_Defaults { + + private static $communityEntity = "ownCloud"; + private static $communityName = "ownCloud"; + private static $communityBaseUrl = "http://owncloud.org"; + private static $communitySyncClientUrl = " http://owncloud.org/sync-clients/"; + private static $communityDocBaseUrl = "http://doc.owncloud.org"; + private static $communitySlogan = "web services under your control"; + + private static $enterpriseEntity = "ownCloud Inc."; + private static $enterpriseName = "ownCloud Enterprise Edition"; + private static $enterpriseBaseUrl = "https://owncloud.com"; + private static $enterpriseDocBaseUrl = "http://doc.owncloud.com"; + private static $enterpiseSyncClientUrl = "https://owncloud.com/products/desktop-clients"; + private static $enterpriseSlogan = "Your Cloud, Your Data, Your Way!"; + + + public static function getBaseUrl() { + if (OC_Util::getEditionString() === '') { + return self::$communityBaseUrl; + } else { + return self::$enterpriseBaseUrl; + } + } + + public static function getSyncClientUrl() { + if (OC_Util::getEditionString() === '') { + return self::$communitySyncClientUrl; + } else { + return self::$enterpiseSyncClientUrl; + } + } + + public static function getDocBaseUrl() { + if (OC_Util::getEditionString() === '') { + return self::$communityDocBaseUrl; + } else { + return self::$enterpriseDocBaseUrl; + } + } + + public static function getName() { + if (OC_Util::getEditionString() === '') { + return self::$communityName; + } else { + return self::$enterpriseName; + } + } + + public static function getEntity() { + if (OC_Util::getEditionString() === '') { + return self::$communityEntity; + } else { + return self::$enterpriseEntity; + } + } + + public static function getSlogan() { + $l = OC_L10N::get('core'); + if (OC_Util::getEditionString() === '') { + return $l->t(self::$communitySlogan); + } else { + return self::$enterpriseSlogan; + } + } + +}
\ No newline at end of file diff --git a/lib/files/cache/backgroundwatcher.php b/lib/files/cache/backgroundwatcher.php index 8933101577d..923804f48d0 100644 --- a/lib/files/cache/backgroundwatcher.php +++ b/lib/files/cache/backgroundwatcher.php @@ -18,8 +18,8 @@ class BackgroundWatcher { if (!is_null(self::$folderMimetype)) { return self::$folderMimetype; } - $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'); - $result = $query->execute(array('httpd/unix-directory')); + $sql = 'SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'; + $result = \OC_DB::executeAudited($sql, array('httpd/unix-directory')); $row = $result->fetchRow(); return $row['id']; } @@ -59,11 +59,11 @@ class BackgroundWatcher { */ static private function getNextFileId($previous, $folder) { if ($folder) { - $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND mimetype = ' . self::getFolderMimetype() . ' ORDER BY `fileid` ASC', 1); + $stmt = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND `mimetype` = ? ORDER BY `fileid` ASC', 1); } else { - $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND mimetype != ' . self::getFolderMimetype() . ' ORDER BY `fileid` ASC', 1); + $stmt = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND `mimetype` != ? ORDER BY `fileid` ASC', 1); } - $result = $query->execute(array($previous)); + $result = \OC_DB::executeAudited($stmt, array($previous,self::getFolderMimetype())); if ($row = $result->fetchRow()) { return $row['fileid']; } else { diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index cae2e63e4dc..3818fdbd840 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -65,13 +65,11 @@ class Cache { */ public function getMimetypeId($mime) { if (!isset($this->mimetypeIds[$mime])) { - $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'); - $result = $query->execute(array($mime)); + $result = \OC_DB::executeAudited('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?', array($mime)); if ($row = $result->fetchRow()) { $this->mimetypeIds[$mime] = $row['id']; } else { - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)'); - $query->execute(array($mime)); + $result = \OC_DB::executeAudited('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)', array($mime)); $this->mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes'); } $this->mimetypes[$this->mimetypeIds[$mime]] = $mime; @@ -81,8 +79,8 @@ class Cache { public function getMimetype($id) { if (!isset($this->mimetypes[$id])) { - $query = \OC_DB::prepare('SELECT `mimetype` FROM `*PREFIX*mimetypes` WHERE `id` = ?'); - $result = $query->execute(array($id)); + $sql = 'SELECT `mimetype` FROM `*PREFIX*mimetypes` WHERE `id` = ?'; + $result = \OC_DB::executeAudited($sql, array($id)); if ($row = $result->fetchRow()) { $this->mimetypes[$id] = $row['mimetype']; } else { @@ -96,7 +94,7 @@ class Cache { * get the stored metadata of a file or folder * * @param string/int $file - * @return array + * @return array | false */ public function get($file) { if (is_string($file) or $file == '') { @@ -109,12 +107,18 @@ class Cache { $where = 'WHERE `fileid` = ?'; $params = array($file); } - $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` ' . $where); - $result = $query->execute($params); + $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, + `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` + FROM `*PREFIX*filecache` ' . $where; + $result = \OC_DB::executeAudited($sql, $params); $data = $result->fetchRow(); + //FIXME hide this HACK in the next database layer, or just use doctrine and get rid of MDB2 and PDO + //PDO returns false, MDB2 returns null, oracle always uses MDB2, so convert null to false + if ($data === null) { + $data = false; + } + //merge partial data if (!$data and is_string($file)) { if (isset($this->partial[$file])) { @@ -147,14 +151,10 @@ class Cache { public function getFolderContents($folder) { $fileId = $this->getId($folder); if ($fileId > -1) { - $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC'); - - $result = $query->execute(array($fileId)); - if (\OC_DB::isError($result)) { - \OCP\Util::writeLog('cache', 'getFolderContents failed: ' . $result->getMessage(), \OCP\Util::ERROR); - } + $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, + `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` + FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC'; + $result = \OC_DB::executeAudited($sql,array($fileId)); $files = $result->fetchAll(); foreach ($files as &$file) { $file['mimetype'] = $this->getMimetype($file['mimetype']); @@ -208,12 +208,9 @@ class Cache { $params[] = $this->getNumericStorageId(); $valuesPlaceholder = array_fill(0, count($queryParts), '?'); - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ')' - . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); - $result = $query->execute($params); - if (\OC_DB::isError($result)) { - \OCP\Util::writeLog('cache', 'Insert to cache failed: ' . $result->getMessage(), \OCP\Util::ERROR); - } + $sql = 'INSERT INTO `*PREFIX*filecache` (' . implode(', ', $queryParts) . ')' + . ' VALUES (' . implode(', ', $valuesPlaceholder) . ')'; + \OC_DB::executeAudited($sql, $params); return (int)\OC_DB::insertid('*PREFIX*filecache'); } @@ -240,9 +237,8 @@ class Cache { list($queryParts, $params) = $this->buildParts($data); $params[] = $id; - $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=?' - . ' WHERE fileid = ?'); - $query->execute($params); + $sql = 'UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? WHERE `fileid` = ?'; + \OC_DB::executeAudited($sql, $params); } /** @@ -289,9 +285,8 @@ class Cache { $pathHash = md5($file); - $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($this->getNumericStorageId(), $pathHash)); - + $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'; + $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId(), $pathHash)); if ($row = $result->fetchRow()) { return $row['fileid']; } else { @@ -340,8 +335,9 @@ class Cache { $this->remove($child['path']); } } - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?'); - $query->execute(array($entry['fileid'])); + + $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?'; + \OC_DB::executeAudited($sql, array($entry['fileid'])); $permissionsCache = new Permissions($this->storageId); $permissionsCache->remove($entry['fileid']); @@ -364,32 +360,31 @@ class Cache { if ($sourceData['mimetype'] === 'httpd/unix-directory') { //find all child entries - $query = \OC_DB::prepare('SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path` LIKE ?'); - $result = $query->execute(array($this->getNumericStorageId(), $source . '/%')); + $sql = 'SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path` LIKE ?'; + $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId(), $source . '/%')); $childEntries = $result->fetchAll(); $sourceLength = strlen($source); $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ? WHERE `fileid` = ?'); foreach ($childEntries as $child) { $targetPath = $target . substr($child['path'], $sourceLength); - $query->execute(array($targetPath, md5($targetPath), $child['fileid'])); + \OC_DB::executeAudited($query, array($targetPath, md5($targetPath), $child['fileid'])); } } - $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ?, `name` = ?, `parent` =?' - . ' WHERE `fileid` = ?'); - $query->execute(array($target, md5($target), basename($target), $newParentId, $sourceId)); + $sql = 'UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ?, `name` = ?, `parent` =? WHERE `fileid` = ?'; + \OC_DB::executeAudited($sql, array($target, md5($target), basename($target), $newParentId, $sourceId)); } /** * remove all entries for files that are stored on the storage from the cache */ public function clear() { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage = ?'); - $query->execute(array($this->getNumericStorageId())); + $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?'; + \OC_DB::executeAudited($sql, array($this->getNumericStorageId())); - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*storages` WHERE id = ?'); - $query->execute(array($this->storageId)); + $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?'; + \OC_DB::executeAudited($sql, array($this->storageId)); } /** @@ -402,11 +397,8 @@ class Cache { $file = $this->normalize($file); $pathHash = md5($file); - $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($this->getNumericStorageId(), $pathHash)); - if( \OC_DB::isError($result)) { - \OCP\Util::writeLog('cache', 'get status failed: ' . $result->getMessage(), \OCP\Util::ERROR); - } + $sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'; + $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId(), $pathHash)); if ($row = $result->fetchRow()) { if ((int)$row['size'] === -1) { return self::SHALLOW; @@ -433,11 +425,9 @@ class Cache { // normalize pattern $pattern = $this->normalize($pattern); - $query = \OC_DB::prepare(' - SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' - ); - $result = $query->execute(array($pattern, $this->getNumericStorageId())); + $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` + FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?'; + $result = \OC_DB::executeAudited($sql, array($pattern, $this->getNumericStorageId())); $files = array(); while ($row = $result->fetchRow()) { $row['mimetype'] = $this->getMimetype($row['mimetype']); @@ -459,12 +449,10 @@ class Cache { } else { $where = '`mimepart` = ?'; } - $query = \OC_DB::prepare(' - SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' - ); + $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` + FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?'; $mimetype = $this->getMimetypeId($mimetype); - $result = $query->execute(array($mimetype, $this->getNumericStorageId())); + $result = \OC_DB::executeAudited($sql, array($mimetype, $this->getNumericStorageId())); $files = array(); while ($row = $result->fetchRow()) { $row['mimetype'] = $this->getMimetype($row['mimetype']); @@ -501,8 +489,8 @@ class Cache { if ($id === -1) { return 0; } - $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); - $result = $query->execute(array($id, $this->getNumericStorageId())); + $sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'; + $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); $totalSize = 0; $hasChilds = 0; while ($row = $result->fetchRow()) { @@ -528,8 +516,8 @@ class Cache { * @return int[] */ public function getAll() { - $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?'); - $result = $query->execute(array($this->getNumericStorageId())); + $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?'; + $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId())); $ids = array(); while ($row = $result->fetchRow()) { $ids[] = $row['fileid']; @@ -549,10 +537,7 @@ class Cache { public function getIncomplete() { $query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache`' . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC',1); - $result = $query->execute(array($this->getNumericStorageId())); - if (\OC_DB::isError($result)) { - \OCP\Util::writeLog('cache', 'getIncomplete failed: ' . $result->getMessage(), \OCP\Util::ERROR); - } + $result = \OC_DB::executeAudited($query, array($this->getNumericStorageId())); if ($row = $result->fetchRow()) { return $row['path']; } else { @@ -567,8 +552,8 @@ class Cache { * @return array, first element holding the storage id, second the path */ static public function getById($id) { - $query = \OC_DB::prepare('SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); - $result = $query->execute(array($id)); + $sql = 'SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?'; + $result = \OC_DB::executeAudited($sql, array($id)); if ($row = $result->fetchRow()) { $numericId = $row['storage']; $path = $row['path']; diff --git a/lib/files/cache/legacy.php b/lib/files/cache/legacy.php index b8e2548639b..8eed1f67a5d 100644 --- a/lib/files/cache/legacy.php +++ b/lib/files/cache/legacy.php @@ -26,8 +26,8 @@ class Legacy { * @return int */ function getCount() { - $query = \OC_DB::prepare('SELECT COUNT(`id`) AS `count` FROM `*PREFIX*fscache` WHERE `user` = ?'); - $result = $query->execute(array($this->user)); + $sql = 'SELECT COUNT(`id`) AS `count` FROM `*PREFIX*fscache` WHERE `user` = ?'; + $result = \OC_DB::executeAudited($sql, array($this->user)); if ($row = $result->fetchRow()) { return $row['count']; } else { @@ -45,7 +45,7 @@ class Legacy { return $this->cacheHasItems; } try { - $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `user` = ? LIMIT 1'); + $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `user` = ?',1); } catch (\Exception $e) { $this->cacheHasItems = false; return false; @@ -74,11 +74,11 @@ class Legacy { */ function get($path) { if (is_numeric($path)) { - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `id` = ?'); + $sql = 'SELECT * FROM `*PREFIX*fscache` WHERE `id` = ?'; } else { - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `path` = ?'); + $sql = 'SELECT * FROM `*PREFIX*fscache` WHERE `path` = ?'; } - $result = $query->execute(array($path)); + $result = \OC_DB::executeAudited($sql, array($path)); $data = $result->fetchRow(); $data['etag'] = $this->getEtag($data['path'], $data['user']); return $data; @@ -111,7 +111,7 @@ class Legacy { if(is_null($query)){ $query = \OC_DB::prepare('SELECT `propertyvalue` FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = \'{DAV:}getetag\''); } - $result = $query->execute(array($user, '/' . $relativePath)); + $result = \OC_DB::executeAudited($query,array($user, '/' . $relativePath)); if ($row = $result->fetchRow()) { return trim($row['propertyvalue'], '"'); } else { @@ -126,8 +126,7 @@ class Legacy { * @return array */ function getChildren($id) { - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `parent` = ?'); - $result = $query->execute(array($id)); + $result = \OC_DB::executeAudited('SELECT * FROM `*PREFIX*fscache` WHERE `parent` = ?', array($id)); $data = $result->fetchAll(); foreach ($data as $i => $item) { $data[$i]['etag'] = $this->getEtag($item['path'], $item['user']); diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php index 29c30b0f36c..2e2bdb20b78 100644 --- a/lib/files/cache/permissions.php +++ b/lib/files/cache/permissions.php @@ -33,8 +33,8 @@ class Permissions { * @return int (-1 if file no permissions set) */ public function get($fileId, $user) { - $query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'); - $result = $query->execute(array($user, $fileId)); + $sql = 'SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'; + $result = \OC_DB::executeAudited($sql, array($user, $fileId)); if ($row = $result->fetchRow()) { return $row['permissions']; } else { @@ -51,13 +51,11 @@ class Permissions { */ public function set($fileId, $user, $permissions) { if (self::get($fileId, $user) !== -1) { - $query = \OC_DB::prepare('UPDATE `*PREFIX*permissions` SET `permissions` = ?' - . ' WHERE `user` = ? AND `fileid` = ?'); + $sql = 'UPDATE `*PREFIX*permissions` SET `permissions` = ? WHERE `user` = ? AND `fileid` = ?'; } else { - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*permissions`(`permissions`, `user`, `fileid`)' - . ' VALUES(?, ?,? )'); + $sql = 'INSERT INTO `*PREFIX*permissions`(`permissions`, `user`, `fileid`) VALUES(?, ?,? )'; } - $query->execute(array($permissions, $user, $fileId)); + \OC_DB::executeAudited($sql, array($permissions, $user, $fileId)); } /** @@ -75,9 +73,9 @@ class Permissions { $params[] = $user; $inPart = implode(', ', array_fill(0, count($fileIds), '?')); - $query = \OC_DB::prepare('SELECT `fileid`, `permissions` FROM `*PREFIX*permissions`' - . ' WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); - $result = $query->execute($params); + $sql = 'SELECT `fileid`, `permissions` FROM `*PREFIX*permissions`' + . ' WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'; + $result = \OC_DB::executeAudited($sql, $params); $filePermissions = array(); while ($row = $result->fetchRow()) { $filePermissions[$row['fileid']] = $row['permissions']; @@ -93,11 +91,12 @@ class Permissions { * @return int[] */ public function getDirectoryPermissions($parentId, $user) { - $query = \OC_DB::prepare('SELECT `*PREFIX*permissions`.`fileid`, `permissions` - FROM `*PREFIX*permissions` INNER JOIN `*PREFIX*filecache` ON `*PREFIX*permissions`.`fileid` = `*PREFIX*filecache`.`fileid` - WHERE `*PREFIX*filecache`.`parent` = ? AND `*PREFIX*permissions`.`user` = ?'); + $sql = 'SELECT `*PREFIX*permissions`.`fileid`, `permissions` + FROM `*PREFIX*permissions` + INNER JOIN `*PREFIX*filecache` ON `*PREFIX*permissions`.`fileid` = `*PREFIX*filecache`.`fileid` + WHERE `*PREFIX*filecache`.`parent` = ? AND `*PREFIX*permissions`.`user` = ?'; - $result = $query->execute(array($parentId, $user)); + $result = \OC_DB::executeAudited($sql, array($parentId, $user)); $filePermissions = array(); while ($row = $result->fetchRow()) { $filePermissions[$row['fileid']] = $row['permissions']; @@ -113,18 +112,17 @@ class Permissions { */ public function remove($fileId, $user = null) { if (is_null($user)) { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ?'); - $query->execute(array($fileId)); + \OC_DB::executeAudited('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ?', array($fileId)); } else { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); - $query->execute(array($fileId, $user)); + $sql = 'DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'; + \OC_DB::executeAudited($sql, array($fileId, $user)); } } public function removeMultiple($fileIds, $user) { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); foreach ($fileIds as $fileId) { - $query->execute(array($fileId, $user)); + \OC_DB::executeAudited($query, array($fileId, $user)); } } @@ -134,8 +132,8 @@ class Permissions { * @param int $fileId */ public function getUsers($fileId) { - $query = \OC_DB::prepare('SELECT `user` FROM `*PREFIX*permissions` WHERE `fileid` = ?'); - $result = $query->execute(array($fileId)); + $sql = 'SELECT `user` FROM `*PREFIX*permissions` WHERE `fileid` = ?'; + $result = \OC_DB::executeAudited($sql, array($fileId)); $users = array(); while ($row = $result->fetchRow()) { $users[] = $row['user']; diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 8f9a7921956..9b94a24f481 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -8,6 +8,8 @@ namespace OC\Files\Cache; +use OC\Files\Filesystem; + class Scanner { /** * @var \OC\Files\Storage\Storage $storage @@ -27,6 +29,9 @@ class Scanner { const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; + const REUSE_ETAG = 1; + const REUSE_SIZE = 2; + public function __construct(\OC\Files\Storage\Storage $storage) { $this->storage = $storage; $this->storageId = $this->storage->getId(); @@ -59,12 +64,12 @@ class Scanner { * scan a single file and store it in the cache * * @param string $file - * @param bool $checkExisting check existing folder sizes in the cache instead of always using -1 for folder size + * @param int $reuseExisting * @return array with metadata of the scanned file */ - public function scanFile($file, $checkExisting = false) { - if ( ! self::isPartialFile($file) - and ! \OC\Files\Filesystem::isFileBlacklisted($file) + public function scanFile($file, $reuseExisting = 0) { + if (!self::isPartialFile($file) + and !Filesystem::isFileBlacklisted($file) ) { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); @@ -79,20 +84,22 @@ class Scanner { } } $newData = $data; - if ($cacheData = $this->cache->get($file)) { - if ($checkExisting && $data['size'] === -1) { - $data['size'] = $cacheData['size']; - } - if ($data['mtime'] === $cacheData['mtime'] && - $data['size'] === $cacheData['size']) { - $data['etag'] = $cacheData['etag']; + if ($reuseExisting and $cacheData = $this->cache->get($file)) { + // only reuse data if the file hasn't explicitly changed + if ($data['mtime'] === $cacheData['mtime']) { + if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) { + $data['size'] = $cacheData['size']; + } + if ($reuseExisting & self::REUSE_ETAG) { + $data['etag'] = $cacheData['etag']; + } } // Only update metadata that has changed $newData = array_diff($data, $cacheData); } - if (!empty($newData)) { - $this->cache->put($file, $newData); - } + } + if (!empty($newData)) { + $this->cache->put($file, $newData); } return $data; } @@ -100,55 +107,79 @@ class Scanner { } /** - * scan all the files in a folder and store them in the cache + * scan a folder and all it's children * * @param string $path * @param bool $recursive - * @param bool $onlyChilds + * @param int $reuse * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ - public function scan($path, $recursive = self::SCAN_RECURSIVE, $onlyChilds = false) { - \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_folder', array('path' => $path, 'storage' => $this->storageId)); - $childQueue = array(); - if (!$onlyChilds) { - $this->scanFile($path); + public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) { + if ($reuse === -1) { + $reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : 0; } + $this->scanFile($path, $reuse); + return $this->scanChildren($path, $recursive, $reuse); + } + /** + * scan all the files and folders in a folder + * + * @param string $path + * @param bool $recursive + * @param int $reuse + * @return int the size of the scanned folder or -1 if the size is unknown at this stage + */ + public function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) { + if ($reuse === -1) { + $reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : 0; + } + \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_folder', array('path' => $path, 'storage' => $this->storageId)); $size = 0; + $childQueue = array(); + $existingChildren = array(); + if ($this->cache->inCache($path)) { + $children = $this->cache->getFolderContents($path); + foreach ($children as $child) { + $existingChildren[] = $child['name']; + } + } + $newChildren = array(); if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) { \OC_DB::beginTransaction(); while ($file = readdir($dh)) { $child = ($path) ? $path . '/' . $file : $file; - if (!\OC\Files\Filesystem::isIgnoredDir($file)) { - $data = $this->scanFile($child, $recursive === self::SCAN_SHALLOW); + if (!Filesystem::isIgnoredDir($file)) { + $newChildren[] = $file; + $data = $this->scanFile($child, $reuse); if ($data) { if ($data['size'] === -1) { if ($recursive === self::SCAN_RECURSIVE) { $childQueue[] = $child; - $data['size'] = 0; } else { $size = -1; } - } - - if ($size !== -1) { + } else if ($size !== -1) { $size += $data['size']; } } } } + $removedChildren = \array_diff($existingChildren, $newChildren); + foreach ($removedChildren as $childName) { + $child = ($path) ? $path . '/' . $childName : $childName; + $this->cache->remove($child); + } \OC_DB::commit(); foreach ($childQueue as $child) { - $childSize = $this->scan($child, self::SCAN_RECURSIVE, true); + $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE); if ($childSize === -1) { $size = -1; } else { $size += $childSize; } } - if ($size !== -1) { - $this->cache->put($path, array('size' => $size)); - } + $this->cache->put($path, array('size' => $size)); } return $size; } diff --git a/lib/files/cache/storage.php b/lib/files/cache/storage.php index 72de376798c..8a9e47ca36d 100644 --- a/lib/files/cache/storage.php +++ b/lib/files/cache/storage.php @@ -32,13 +32,13 @@ class Storage { $this->storageId = md5($this->storageId); } - $query = \OC_DB::prepare('SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?'); - $result = $query->execute(array($this->storageId)); + $sql = 'SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?'; + $result = \OC_DB::executeAudited($sql, array($this->storageId)); if ($row = $result->fetchRow()) { $this->numericId = $row['numeric_id']; } else { - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*storages`(`id`) VALUES(?)'); - $query->execute(array($this->storageId)); + $sql = 'INSERT INTO `*PREFIX*storages` (`id`) VALUES(?)'; + \OC_DB::executeAudited($sql, array($this->storageId)); $this->numericId = \OC_DB::insertid('*PREFIX*storages'); } } @@ -48,8 +48,9 @@ class Storage { } public static function getStorageId($numericId) { - $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*storages` WHERE `numeric_id` = ?'); - $result = $query->execute(array($numericId)); + + $sql = 'SELECT `id` FROM `*PREFIX*storages` WHERE `numeric_id` = ?'; + $result = \OC_DB::executeAudited($sql, array($numericId)); if ($row = $result->fetchRow()) { return $row['id']; } else { diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 417a47f3830..87c33a313a4 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -7,6 +7,7 @@ */ namespace OC\Files\Cache; +use OCP\Util; /** * listen to filesystem hooks and change the cache accordingly @@ -102,7 +103,7 @@ class Updater { static public function correctFolder($path, $time) { if ($path !== '' && $path !== '/') { $parent = dirname($path); - if ($parent === '.') { + if ($parent === '.' || $parent === '\\') { $parent = ''; } /** @@ -116,6 +117,8 @@ class Updater { if ($id !== -1) { $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); self::correctFolder($parent, $time); + } else { + Util::writeLog('core', 'Path not in cache: '.$internalPath, Util::ERROR); } } } diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index ca044ba81de..cfb9a117311 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -78,7 +78,7 @@ class Upgrade { VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); } if (!$this->inCache($data['storage'], $data['path_hash'], $data['id'])) { - $insertQuery->execute(array($data['id'], $data['storage'], + \OC_DB::executeAudited($insertQuery, array($data['id'], $data['storage'], $data['path'], $data['path_hash'], $data['parent'], $data['name'], $data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'], $data['etag'])); } @@ -97,7 +97,7 @@ class Upgrade { if(is_null($query)) { $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE (`storage` = ? AND `path_hash` = ?) OR `fileid` = ?'); } - $result = $query->execute(array($storage, $pathHash, $id)); + $result = \OC_DB::executeAudited($query, array($storage, $pathHash, $id)); return (bool)$result->fetchRow(); } diff --git a/lib/files/mapper.php b/lib/files/mapper.php index 15f5f0628b5..47abd4e52fe 100644 --- a/lib/files/mapper.php +++ b/lib/files/mapper.php @@ -53,11 +53,9 @@ class Mapper } if ($isLogicPath) { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'); - $query->execute(array($path)); + \OC_DB::executeAudited('DELETE FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?', array($path)); } else { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*file_map` WHERE `physic_path` LIKE ?'); - $query->execute(array($path)); + \OC_DB::executeAudited('DELETE FROM `*PREFIX*file_map` WHERE `physic_path` LIKE ?', array($path)); } } @@ -73,8 +71,8 @@ class Mapper $physicPath1 = $this->logicToPhysical($path1, true); $physicPath2 = $this->logicToPhysical($path2, true); - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'); - $result = $query->execute(array($path1.'%')); + $sql = 'SELECT * FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'; + $result = \OC_DB::executeAudited($sql, array($path1.'%')); $updateQuery = \OC_DB::prepare('UPDATE `*PREFIX*file_map`' .' SET `logic_path` = ?' .' , `logic_path_hash` = ?' @@ -88,7 +86,8 @@ class Mapper $newPhysic = $physicPath2.$this->stripRootFolder($currentPhysic, $physicPath1); if ($path1 !== $currentLogic) { try { - $updateQuery->execute(array($newLogic, md5($newLogic), $newPhysic, md5($newPhysic), $currentLogic)); + \OC_DB::executeAudited($updateQuery, array($newLogic, md5($newLogic), $newPhysic, md5($newPhysic), + $currentLogic)); } catch (\Exception $e) { error_log('Mapper::Copy failed '.$currentLogic.' -> '.$newLogic.'\n'.$e); throw $e; @@ -123,8 +122,8 @@ class Mapper private function resolveLogicPath($logicPath) { $logicPath = $this->stripLast($logicPath); - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `logic_path_hash` = ?'); - $result = $query->execute(array(md5($logicPath))); + $sql = 'SELECT * FROM `*PREFIX*file_map` WHERE `logic_path_hash` = ?'; + $result = \OC_DB::executeAudited($sql, array(md5($logicPath))); $result = $result->fetchRow(); if ($result === false) { return null; @@ -135,8 +134,8 @@ class Mapper private function resolvePhysicalPath($physicalPath) { $physicalPath = $this->stripLast($physicalPath); - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `physic_path_hash` = ?'); - $result = $query->execute(array(md5($physicalPath))); + $sql = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `physic_path_hash` = ?'); + $result = \OC_DB::executeAudited($sql, array(md5($physicalPath))); $result = $result->fetchRow(); return $result['logic_path']; @@ -163,8 +162,9 @@ class Mapper } private function insert($logicPath, $physicalPath) { - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*file_map`(`logic_path`, `physic_path`, `logic_path_hash`, `physic_path_hash`) VALUES(?, ?, ?, ?)'); - $query->execute(array($logicPath, $physicalPath, md5($logicPath), md5($physicalPath))); + $sql = 'INSERT INTO `*PREFIX*file_map` (`logic_path`, `physic_path`, `logic_path_hash`, `physic_path_hash`) + VALUES (?, ?, ?, ?)'; + \OC_DB::executeAudited($sql, array($logicPath, $physicalPath, md5($logicPath), md5($physicalPath))); } public function slugifyPath($path, $index=null) { @@ -172,14 +172,9 @@ class Mapper $pathElements = explode('/', $path); $sluggedElements = array(); - - // rip off the extension ext from last element + $last= end($pathElements); - $parts = pathinfo($last); - $filename = $parts['filename']; - array_pop($pathElements); - array_push($pathElements, $filename); - + foreach ($pathElements as $pathElement) { // remove empty elements if (empty($pathElement)) { @@ -192,13 +187,15 @@ class Mapper // apply index to file name if ($index !== null) { $last= array_pop($sluggedElements); - array_push($sluggedElements, $last.'-'.$index); - } + + // if filename contains periods - add index number before last period + if (preg_match('~\.[^\.]+$~i',$last,$extension)){ + array_push($sluggedElements, substr($last,0,-(strlen($extension[0]))).'-'.$index.$extension[0]); + } else { + // if filename doesn't contain periods add index ofter the last char + array_push($sluggedElements, $last.'-'.$index); + } - // add back the extension - if (isset($parts['extension'])) { - $last= array_pop($sluggedElements); - array_push($sluggedElements, $last.'.'.$parts['extension']); } $sluggedPath = $this->unchangedPhysicalRoot.implode('/', $sluggedElements); @@ -213,8 +210,8 @@ class Mapper */ private function slugify($text) { - // replace non letter or digits by - - $text = preg_replace('~[^\\pL\d]+~u', '-', $text); + // replace non letter or digits or dots by - + $text = preg_replace('~[^\\pL\d\.]+~u', '-', $text); // trim $text = trim($text, '-'); @@ -228,7 +225,10 @@ class Mapper $text = strtolower($text); // remove unwanted characters - $text = preg_replace('~[^-\w]+~', '', $text); + $text = preg_replace('~[^-\w\.]+~', '', $text); + + // trim ending dots (for security reasons and win compatibility) + $text = preg_replace('~\.+$~', '', $text); if (empty($text)) { return uniqid(); diff --git a/lib/files/view.php b/lib/files/view.php index ecb0f30400a..25071709fbe 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -300,7 +300,7 @@ class View { list ($count, $result) = \OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); - if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path)) { + if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path) && $result !== false) { if (!$exists) { \OC_Hook::emit( Filesystem::CLASSNAME, @@ -386,11 +386,19 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); list($count, $result) = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); - $storage1->unlink($internalPath1); + + // close open handle - especially $source is necessary because unlink below will + // throw an exception on windows because the file is locked + fclose($source); + fclose($target); + + if ($result !== false) { + list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + $storage1->unlink($internalPath1); + } } } - if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path1)) { + if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path1) && $result !== false) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_post_rename, @@ -484,7 +492,7 @@ class View { list($count, $result) = \OC_Helper::streamCopy($source, $target); } } - if ($this->fakeRoot == Filesystem::getRoot()) { + if ($this->fakeRoot == Filesystem::getRoot() && $result !== false) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_post_copy, @@ -648,7 +656,7 @@ class View { $result = $storage->$operation($internalPath); } $result = \OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); - if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot()) { + if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot() && $result !== false) { if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open $this->runHooks($hooks, $path, true); } diff --git a/lib/helper.php b/lib/helper.php index 225e9fd2a9a..a315c640d1a 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -364,6 +364,26 @@ class OC_Helper { } /** + * Try to guess the mimetype based on filename + * + * @param string $path + * @return string + */ + static public function getFileNameMimeType($path){ + if(strpos($path, '.')) { + //try to guess the type by the file extension + if(!self::$mimetypes || self::$mimetypes != include 'mimetypes.list.php') { + self::$mimetypes=include 'mimetypes.list.php'; + } + $extension=strtolower(strrchr(basename($path), ".")); + $extension=substr($extension, 1);//remove leading . + return (isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream'; + }else{ + return 'application/octet-stream'; + } + } + + /** * get the mimetype form a local file * @param string $path * @return string @@ -377,17 +397,7 @@ class OC_Helper { return "httpd/unix-directory"; } - if(strpos($path, '.')) { - //try to guess the type by the file extension - if(!self::$mimetypes || self::$mimetypes != include 'mimetypes.list.php') { - self::$mimetypes=include 'mimetypes.list.php'; - } - $extension=strtolower(strrchr(basename($path), ".")); - $extension=substr($extension, 1);//remove leading . - $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream'; - }else{ - $mimeType='application/octet-stream'; - } + $mimeType = self::getFileNameMimeType($path); if($mimeType=='application/octet-stream' and function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)) { @@ -609,7 +619,7 @@ class OC_Helper { } /** - * remove all files in PHP /oc-noclean temp dir + * remove all files in PHP /oc-noclean temp dir */ public static function cleanTmpNoClean() { $tmpDirNoCleanFile=get_temp_dir().'/oc-noclean/'; diff --git a/lib/hintexception.php b/lib/hintexception.php index c8bff750033..3934ae2a4c2 100644 --- a/lib/hintexception.php +++ b/lib/hintexception.php @@ -12,7 +12,7 @@ class HintException extends \Exception { private $hint; - public function __construct($message, $hint, $code = 0, Exception $previous = null) { + public function __construct($message, $hint = '', $code = 0, Exception $previous = null) { $this->hint = $hint; parent::__construct($message, $code, $previous); } diff --git a/lib/l10n/bg_BG.php b/lib/l10n/bg_BG.php index 2de4c0a6e68..8412ac9548f 100644 --- a/lib/l10n/bg_BG.php +++ b/lib/l10n/bg_BG.php @@ -21,16 +21,21 @@ "%s enter the database username." => "%s въведете потребителско име за базата с данни.", "%s enter the database name." => "%s въведете име на базата с данни.", "%s you may not use dots in the database name" => "%s, не можете да ползвате точки в името на базата от данни", +"%s set the database host." => "%s задай хост на базата данни.", "PostgreSQL username and/or password not valid" => "Невалидно PostgreSQL потребителско име и/или парола", "You need to enter either an existing account or the administrator." => "Необходимо е да влезете в всъществуващ акаунт или като администратора", +"Oracle connection could not be established" => "Oracle връзка не можа да се осъществи", "MySQL username and/or password not valid" => "Невалидно MySQL потребителско име и/или парола", "DB Error: \"%s\"" => "Грешка в базата от данни: \"%s\"", +"Offending command was: \"%s\"" => "Проблемната команда беше: \"%s\"", "MySQL user '%s'@'localhost' exists already." => "MySQL потребителят '%s'@'localhost' вече съществува", "Drop this user from MySQL" => "Изтриване на потребителя от MySQL", "MySQL user '%s'@'%%' already exists" => "MySQL потребителят '%s'@'%%' вече съществува.", "Drop this user from MySQL." => "Изтриване на потребителя от MySQL.", "Oracle username and/or password not valid" => "Невалидно Oracle потребителско име и/или парола", +"Offending command was: \"%s\", name: %s, password: %s" => "Проблемната команда беше: \"%s\", име: %s, парола: %s", "MS SQL username and/or password not valid: %s" => "Невалидно MS SQL потребителско име и/или парола: %s", +"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Вашият web сървър все още не е удачно настроен да позволява синхронизация на файлове, защото WebDAV интерфейсът изглежда не работи.", "Please double check the <a href='%s'>installation guides</a>." => "Моля направете повторна справка с <a href='%s'>ръководството за инсталиране</a>.", "seconds ago" => "преди секунди", "1 minute ago" => "преди 1 минута", diff --git a/lib/l10n/cs_CZ.php b/lib/l10n/cs_CZ.php index 36469507d40..b74b9a7184c 100644 --- a/lib/l10n/cs_CZ.php +++ b/lib/l10n/cs_CZ.php @@ -24,6 +24,7 @@ "%s set the database host." => "Zadejte název počítače s databází %s.", "PostgreSQL username and/or password not valid" => "Uživatelské jméno, či heslo PostgreSQL není platné", "You need to enter either an existing account or the administrator." => "Musíte zadat existující účet, či správce.", +"Oracle connection could not be established" => "Spojení s Oracle nemohlo být navázáno", "MySQL username and/or password not valid" => "Uživatelské jméno, či heslo MySQL není platné", "DB Error: \"%s\"" => "Chyba DB: \"%s\"", "Offending command was: \"%s\"" => "Podezřelý příkaz byl: \"%s\"", diff --git a/lib/l10n/da.php b/lib/l10n/da.php index aead17f510e..3202ae3a335 100644 --- a/lib/l10n/da.php +++ b/lib/l10n/da.php @@ -24,6 +24,7 @@ "%s set the database host." => "%s sæt database værten.", "PostgreSQL username and/or password not valid" => "PostgreSQL brugernavn og/eller kodeord er ikke gyldigt.", "You need to enter either an existing account or the administrator." => "Du bliver nødt til at indtaste en eksisterende bruger eller en administrator.", +"Oracle connection could not be established" => "Oracle forbindelsen kunne ikke etableres", "MySQL username and/or password not valid" => "MySQL brugernavn og/eller kodeord er ikke gyldigt.", "DB Error: \"%s\"" => "Databasefejl: \"%s\"", "Offending command was: \"%s\"" => "Fejlende kommando var: \"%s\"", diff --git a/lib/l10n/de.php b/lib/l10n/de.php index 74715bc66eb..4869689ba78 100644 --- a/lib/l10n/de.php +++ b/lib/l10n/de.php @@ -24,6 +24,7 @@ "%s set the database host." => "%s setze den Datenbank-Host", "PostgreSQL username and/or password not valid" => "PostgreSQL Benutzername und/oder Passwort ungültig", "You need to enter either an existing account or the administrator." => "Du musst entweder ein existierendes Benutzerkonto oder das Administratoren-Konto angeben.", +"Oracle connection could not be established" => "Es konnte keine Verbindung zur Oracle-Datenbank hergestellt werden", "MySQL username and/or password not valid" => "MySQL Benutzername und/oder Passwort ungültig", "DB Error: \"%s\"" => "DB Fehler: \"%s\"", "Offending command was: \"%s\"" => "Fehlerhafter Befehl war: \"%s\"", diff --git a/lib/l10n/el.php b/lib/l10n/el.php index 8637b8da269..cd025aec78d 100644 --- a/lib/l10n/el.php +++ b/lib/l10n/el.php @@ -24,6 +24,7 @@ "%s set the database host." => "%s ρυθμίση του κεντρικόυ υπολογιστή βάσης δεδομένων. ", "PostgreSQL username and/or password not valid" => "Μη έγκυρος χρήστης και/ή συνθηματικό της PostgreSQL", "You need to enter either an existing account or the administrator." => "Χρειάζεται να εισάγετε είτε έναν υπάρχον λογαριασμό ή του διαχειριστή.", +"Oracle connection could not be established" => "Αδυναμία σύνδεσης Oracle", "MySQL username and/or password not valid" => "Μη έγκυρος χρήστης και/ή συνθηματικό της MySQL", "DB Error: \"%s\"" => "Σφάλμα Βάσης Δεδομένων: \"%s\"", "Offending command was: \"%s\"" => "Η εντολη παραβατικοτητας ηταν: \"%s\"", diff --git a/lib/l10n/eo.php b/lib/l10n/eo.php index 2782be65da9..327fe75b9d2 100644 --- a/lib/l10n/eo.php +++ b/lib/l10n/eo.php @@ -15,6 +15,24 @@ "Files" => "Dosieroj", "Text" => "Teksto", "Images" => "Bildoj", +"Set an admin username." => "Starigi administran uzantonomon.", +"Set an admin password." => "Starigi administran pasvorton.", +"%s enter the database username." => "%s enigu la uzantonomon de la datumbazo.", +"%s enter the database name." => "%s enigu la nomon de la datumbazo.", +"%s you may not use dots in the database name" => "%s vi ne povas uzi punktojn en la nomo de la datumbazo", +"%s set the database host." => "%s enigu la gastigon de la datumbazo.", +"PostgreSQL username and/or password not valid" => "La uzantonomo de PostgreSQL aŭ la pasvorto ne validas", +"Oracle connection could not be established" => "Konekto al Oracle ne povas stariĝi", +"MySQL username and/or password not valid" => "La uzantonomo de MySQL aŭ la pasvorto ne validas", +"DB Error: \"%s\"" => "Datumbaza eraro: “%s”", +"MySQL user '%s'@'localhost' exists already." => "La uzanto de MySQL “%s”@“localhost” jam ekzistas.", +"Drop this user from MySQL" => "Forigi ĉi tiun uzanton el MySQL", +"MySQL user '%s'@'%%' already exists" => "La uzanto de MySQL “%s”@“%%” jam ekzistas", +"Drop this user from MySQL." => "Forigi ĉi tiun uzanton el MySQL.", +"Oracle username and/or password not valid" => "La uzantonomo de Oracle aŭ la pasvorto ne validas", +"MS SQL username and/or password not valid: %s" => "La uzantonomo de MS SQL aŭ la pasvorto ne validas: %s", +"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Via TTT-servilo ankoraŭ ne ĝuste agordiĝis por permesi sinkronigi dosierojn ĉar la WebDAV-interfaco ŝajnas rompita.", +"Please double check the <a href='%s'>installation guides</a>." => "Bonvolu duoble kontroli la <a href='%s'>gvidilon por instalo</a>.", "seconds ago" => "sekundoj antaŭe", "1 minute ago" => "antaŭ 1 minuto", "%d minutes ago" => "antaŭ %d minutoj", diff --git a/lib/l10n/es_AR.php b/lib/l10n/es_AR.php index 1df1b16de65..b4b2a33cd01 100644 --- a/lib/l10n/es_AR.php +++ b/lib/l10n/es_AR.php @@ -24,6 +24,7 @@ "%s set the database host." => "%s Especifique la dirección de la Base de Datos", "PostgreSQL username and/or password not valid" => "Nombre de usuario o contraseña de PostgradeSQL no válido.", "You need to enter either an existing account or the administrator." => "Debe ingresar una cuenta existente o el administrador", +"Oracle connection could not be established" => "No fue posible establecer la conexión a Oracle", "MySQL username and/or password not valid" => "Usuario y/o contraseña MySQL no válido", "DB Error: \"%s\"" => "Error DB: \"%s\"", "Offending command was: \"%s\"" => "El comando no comprendido es: \"%s\"", diff --git a/lib/l10n/he.php b/lib/l10n/he.php index dcd0545adba..0069d77eee4 100644 --- a/lib/l10n/he.php +++ b/lib/l10n/he.php @@ -15,6 +15,8 @@ "Files" => "קבצים", "Text" => "טקסט", "Images" => "תמונות", +"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "שרת האינטרנט שלך אינו מוגדר לצורכי סנכרון קבצים עדיין כיוון שמנשק ה־WebDAV כנראה אינו תקין.", +"Please double check the <a href='%s'>installation guides</a>." => "נא לעיין שוב ב<a href='%s'>מדריכי ההתקנה</a>.", "seconds ago" => "שניות", "1 minute ago" => "לפני דקה אחת", "%d minutes ago" => "לפני %d דקות", diff --git a/lib/l10n/ko.php b/lib/l10n/ko.php index bf2a68369f1..bfb99544a3b 100644 --- a/lib/l10n/ko.php +++ b/lib/l10n/ko.php @@ -16,6 +16,8 @@ "Files" => "파일", "Text" => "텍스트", "Images" => "그림", +"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "WebDAV 인터페이스가 제대로 작동하지 않습니다. 웹 서버에서 파일 동기화를 사용할 수 있도록 설정이 제대로 되지 않은 것 같습니다.", +"Please double check the <a href='%s'>installation guides</a>." => "<a href='%s'>설치 가이드</a>를 다시 한 번 확인하십시오.", "seconds ago" => "초 전", "1 minute ago" => "1분 전", "%d minutes ago" => "%d분 전", diff --git a/lib/l10n/lt_LT.php b/lib/l10n/lt_LT.php index cebaa6937d8..b8268ed4376 100644 --- a/lib/l10n/lt_LT.php +++ b/lib/l10n/lt_LT.php @@ -14,13 +14,17 @@ "Token expired. Please reload page." => "Sesija baigėsi. Prašome perkrauti puslapį.", "Files" => "Failai", "Text" => "Žinučių", +"Images" => "Paveikslėliai", "seconds ago" => "prieš sekundę", "1 minute ago" => "Prieš 1 minutę", "%d minutes ago" => "prieš %d minučių", +"1 hour ago" => "prieš 1 valandą", +"%d hours ago" => "prieš %d valandų", "today" => "šiandien", "yesterday" => "vakar", "%d days ago" => "prieš %d dienų", "last month" => "praeitą mėnesį", +"%d months ago" => "prieš %d mėnesių", "last year" => "praeitais metais", "years ago" => "prieš metus" ); diff --git a/lib/l10n/ru.php b/lib/l10n/ru.php index e077b688c09..e3e3aee5a92 100644 --- a/lib/l10n/ru.php +++ b/lib/l10n/ru.php @@ -24,6 +24,7 @@ "%s set the database host." => "%s задайте хост базы данных.", "PostgreSQL username and/or password not valid" => "Неверное имя пользователя и/или пароль PostgreSQL", "You need to enter either an existing account or the administrator." => "Вы должны войти или в существующий аккаунт или под администратором.", +"Oracle connection could not be established" => "соединение с Oracle не может быть установлено", "MySQL username and/or password not valid" => "Неверное имя пользователя и/или пароль MySQL", "DB Error: \"%s\"" => "Ошибка БД: \"%s\"", "Offending command was: \"%s\"" => "Вызываемая команда была: \"%s\"", diff --git a/lib/l10n/sv.php b/lib/l10n/sv.php index 3dcb26d5d8d..f2b7c892058 100644 --- a/lib/l10n/sv.php +++ b/lib/l10n/sv.php @@ -16,6 +16,25 @@ "Files" => "Filer", "Text" => "Text", "Images" => "Bilder", +"Set an admin username." => "Ange ett användarnamn för administratören.", +"Set an admin password." => "Ange ett administratörslösenord.", +"%s enter the database username." => "%s ange databasanvändare.", +"%s enter the database name." => "%s ange databasnamn", +"%s you may not use dots in the database name" => "%s du får inte använda punkter i databasnamnet", +"%s set the database host." => "%s ange databasserver/host.", +"PostgreSQL username and/or password not valid" => "PostgreSQL-användarnamnet och/eller lösenordet är felaktigt", +"You need to enter either an existing account or the administrator." => "Du måste antingen ange ett befintligt konto eller administratör.", +"Oracle connection could not be established" => "Oracle-anslutning kunde inte etableras", +"MySQL username and/or password not valid" => "MySQL-användarnamnet och/eller lösenordet är felaktigt", +"DB Error: \"%s\"" => "DB error: \"%s\"", +"Offending command was: \"%s\"" => "Det felaktiga kommandot var: \"%s\"", +"MySQL user '%s'@'localhost' exists already." => "MySQL-användaren '%s'@'localhost' existerar redan.", +"Drop this user from MySQL" => "Radera denna användare från MySQL", +"MySQL user '%s'@'%%' already exists" => "MySQl-användare '%s'@'%%' existerar redan", +"Drop this user from MySQL." => "Radera denna användare från MySQL.", +"Oracle username and/or password not valid" => "Oracle-användarnamnet och/eller lösenordet är felaktigt", +"Offending command was: \"%s\", name: %s, password: %s" => "Det felande kommandot var: \"%s\", name: %s, password: %s", +"MS SQL username and/or password not valid: %s" => "MS SQL-användaren och/eller lösenordet var inte giltigt: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Din webbserver är inte korrekt konfigurerad för att tillåta filsynkronisering eftersom WebDAV inte verkar fungera.", "Please double check the <a href='%s'>installation guides</a>." => "Var god kontrollera <a href='%s'>installationsguiden</a>.", "seconds ago" => "sekunder sedan", diff --git a/lib/l10n/tr.php b/lib/l10n/tr.php index 7996447b95d..2662d61649d 100644 --- a/lib/l10n/tr.php +++ b/lib/l10n/tr.php @@ -24,6 +24,7 @@ "%s set the database host." => "%s veritabanı sunucu adını tanımla", "PostgreSQL username and/or password not valid" => "PostgreSQL adi kullanici ve/veya parola yasal degildir. ", "You need to enter either an existing account or the administrator." => "Bir konto veya kullanici birlemek ihtiyacin. ", +"Oracle connection could not be established" => "Oracle bağlantısı kurulamadı", "MySQL username and/or password not valid" => "MySQL kullanıcı adı ve/veya parolası geçerli değil", "DB Error: \"%s\"" => "DB Hata: ''%s''", "Offending command was: \"%s\"" => "Komut rahasiz ''%s''. ", diff --git a/lib/l10n/zh_CN.php b/lib/l10n/zh_CN.php index 61e405d8058..edb0f81ee9d 100644 --- a/lib/l10n/zh_CN.php +++ b/lib/l10n/zh_CN.php @@ -24,6 +24,7 @@ "%s set the database host." => "%s 设置数据库所在主机。", "PostgreSQL username and/or password not valid" => "PostgreSQL 数据库用户名和/或密码无效", "You need to enter either an existing account or the administrator." => "你需要输入一个数据库中已有的账户或管理员账户。", +"Oracle connection could not be established" => "不能建立甲骨文连接", "MySQL username and/or password not valid" => "MySQL 数据库用户名和/或密码无效", "DB Error: \"%s\"" => "数据库错误:\"%s\"", "Offending command was: \"%s\"" => "冲突命令为:\"%s\"", diff --git a/lib/public/share.php b/lib/public/share.php index 81f5515bb4b..122ab3fa030 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -152,11 +152,11 @@ class Share { // Fetch all shares of this file path from DB $query = \OC_DB::prepare( - 'SELECT share_with + 'SELECT `share_with` FROM `*PREFIX*share` WHERE - item_source = ? AND share_type = ?' + `item_source` = ? AND `share_type` = ?' ); $result = $query->execute(array($source, self::SHARE_TYPE_USER)); @@ -171,11 +171,11 @@ class Share { // We also need to take group shares into account $query = \OC_DB::prepare( - 'SELECT share_with + 'SELECT `share_with` FROM `*PREFIX*share` WHERE - item_source = ? AND share_type = ?' + `item_source` = ? AND `share_type` = ?' ); $result = $query->execute(array($source, self::SHARE_TYPE_GROUP)); @@ -192,11 +192,11 @@ class Share { //check for public link shares if (!$publicShare) { $query = \OC_DB::prepare( - 'SELECT share_with + 'SELECT `share_with` FROM `*PREFIX*share` WHERE - item_source = ? AND share_type = ?' + `item_source` = ? AND `share_type` = ?' ); $result = $query->execute(array($source, self::SHARE_TYPE_LINK)); @@ -1586,10 +1586,10 @@ class Share { public static function post_removeFromGroup($arguments) { // TODO Don't call if user deleted? - $query = \OC_DB::prepare('SELECT `id`, `share_type` FROM `*PREFIX*share`' - .' WHERE (`share_type` = ? AND `share_with` = ?) OR (`share_type` = ? AND `share_with` = ?)'); - $result = $query->execute(array(self::SHARE_TYPE_GROUP, $arguments['gid'], self::$shareTypeGroupUserUnique, - $arguments['uid'])); + $sql = 'SELECT `id`, `share_type` FROM `*PREFIX*share`' + .' WHERE (`share_type` = ? AND `share_with` = ?) OR (`share_type` = ? AND `share_with` = ?)'; + $result = \OC_DB::executeAudited($sql, array(self::SHARE_TYPE_GROUP, $arguments['gid'], + self::$shareTypeGroupUserUnique, $arguments['uid'])); while ($item = $result->fetchRow()) { if ($item['share_type'] == self::SHARE_TYPE_GROUP) { // Delete all reshares by this user of the group share @@ -1601,8 +1601,8 @@ class Share { } public static function post_deleteGroup($arguments) { - $query = \OC_DB::prepare('SELECT id FROM `*PREFIX*share` WHERE `share_type` = ? AND `share_with` = ?'); - $result = $query->execute(array(self::SHARE_TYPE_GROUP, $arguments['gid'])); + $sql = 'SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ? AND `share_with` = ?'; + $result = \OC_DB::executeAudited($sql, array(self::SHARE_TYPE_GROUP, $arguments['gid'])); while ($item = $result->fetchRow()) { self::delete($item['id']); } diff --git a/lib/response.php b/lib/response.php index 49d79fda709..674176d078b 100644 --- a/lib/response.php +++ b/lib/response.php @@ -11,6 +11,7 @@ class OC_Response { const STATUS_NOT_MODIFIED = 304; const STATUS_TEMPORARY_REDIRECT = 307; const STATUS_NOT_FOUND = 404; + const STATUS_INTERNAL_SERVER_ERROR = 500; /** * @brief Enable response caching by sending correct HTTP headers @@ -70,6 +71,9 @@ class OC_Response { case self::STATUS_NOT_FOUND; $status = $status . ' Not Found'; break; + case self::STATUS_INTERNAL_SERVER_ERROR; + $status = $status . ' Internal Server Error'; + break; } header($protocol.' '.$status); } diff --git a/lib/setup.php b/lib/setup.php index fd22141f1b9..4a15d14a34d 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -92,12 +92,6 @@ class OC_Setup { 'hint' => $e->getHint() ); return($error); - } catch (Exception $e) { - $error[] = array( - 'error' => $e->getMessage(), - 'hint' => '' - ); - return($error); } } elseif($dbtype == 'pgsql') { @@ -113,7 +107,7 @@ class OC_Setup { try { self::setupPostgreSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $username); - } catch (Exception $e) { + } catch (DatabaseSetupException $e) { $error[] = array( 'error' => $l->t('PostgreSQL username and/or password not valid'), 'hint' => $l->t('You need to enter either an existing account or the administrator.') @@ -125,18 +119,21 @@ class OC_Setup { $dbuser = $options['dbuser']; $dbpass = $options['dbpass']; $dbname = $options['dbname']; - $dbtablespace = $options['dbtablespace']; + if (array_key_exists('dbtablespace', $options)) { + $dbtablespace = $options['dbtablespace']; + } else { + $dbtablespace = 'USERS'; + } $dbhost = isset($options['dbhost'])?$options['dbhost']:''; $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_'; OC_Config::setValue('dbname', $dbname); - OC_Config::setValue('dbtablespace', $dbtablespace); OC_Config::setValue('dbhost', $dbhost); OC_Config::setValue('dbtableprefix', $dbtableprefix); try { self::setupOCIDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, $username); - } catch (Exception $e) { + } catch (DatabaseSetupException $e) { $error[] = array( 'error' => $l->t('Oracle connection could not be established'), 'hint' => $e->getMessage().' Check environment: ORACLE_HOME='.getenv('ORACLE_HOME') @@ -163,7 +160,7 @@ class OC_Setup { try { self::setupMSSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix); - } catch (Exception $e) { + } catch (DatabaseSetupException $e) { $error[] = array( 'error' => 'MS SQL username and/or password not valid', 'hint' => 'You need to enter either an existing account or the administrator.' @@ -312,7 +309,13 @@ class OC_Setup { $connection_string = "host='$e_host' dbname=postgres user='$e_user' password='$e_password'"; $connection = @pg_connect($connection_string); if(!$connection) { - throw new Exception($l->t('PostgreSQL username and/or password not valid')); + // Try if we can connect to the DB with the specified name + $e_dbname = addslashes($dbname); + $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'"; + $connection = @pg_connect($connection_string); + + if(!$connection) + throw new DatabaseSetupException($l->t('PostgreSQL username and/or password not valid')); } $e_user = pg_escape_string($dbuser); //check for roles creation rights in postgresql @@ -357,7 +360,7 @@ class OC_Setup { $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'"; $connection = @pg_connect($connection_string); if(!$connection) { - throw new Exception($l->t('PostgreSQL username and/or password not valid')); + throw new DatabaseSetupException($l->t('PostgreSQL username and/or password not valid')); } $query = "select count(*) FROM pg_class WHERE relname='{$dbtableprefix}users' limit 1"; $result = pg_query($connection, $query); @@ -432,7 +435,7 @@ class OC_Setup { } private static function setupOCIDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, - $username) { + $username) { $l = self::getTrans(); $e_host = addslashes($dbhost); $e_dbname = addslashes($dbname); @@ -447,9 +450,9 @@ class OC_Setup { if(!$connection) { $e = oci_error(); if (is_array ($e) && isset ($e['message'])) { - throw new Exception($e['message']); + throw new DatabaseSetupException($e['message']); } - throw new Exception($l->t('Oracle username and/or password not valid')); + throw new DatabaseSetupException($l->t('Oracle username and/or password not valid')); } //check for roles creation rights in oracle @@ -516,7 +519,7 @@ class OC_Setup { } $connection = @oci_connect($dbuser, $dbpass, $easy_connect_string); if(!$connection) { - throw new Exception($l->t('Oracle username and/or password not valid')); + throw new DatabaseSetupException($l->t('Oracle username and/or password not valid')); } $query = "SELECT count(*) FROM user_tables WHERE table_name = :un"; $stmt = oci_parse($connection, $query); @@ -627,7 +630,7 @@ class OC_Setup { } else { $entry = ''; } - throw new Exception($l->t('MS SQL username and/or password not valid: %s', array($entry))); + throw new DatabaseSetupException($l->t('MS SQL username and/or password not valid: %s', array($entry))); } OC_Config::setValue('dbuser', $dbuser); diff --git a/lib/template.php b/lib/template.php index 9467dedb62a..ae9ea187445 100644 --- a/lib/template.php +++ b/lib/template.php @@ -535,4 +535,25 @@ class OC_Template{ $content->printPage(); die(); } + + /** + * print error page using Exception details + * @param Exception $exception + */ + + public static function printExceptionErrorPage(Exception $exception) { + $error_msg = $exception->getMessage(); + if ($exception->getCode()) { + $error_msg = '['.$exception->getCode().'] '.$error_msg; + } + $hint = $exception->getTraceAsString(); + while (method_exists($exception,'previous') && $exception = $exception->previous()) { + $error_msg .= '<br/>Caused by: '; + if ($exception->getCode()) { + $error_msg .= '['.$exception->getCode().'] '; + } + $error_msg .= $exception->getMessage(); + }; + self::printErrorPage($error_msg, $hint); + } } diff --git a/lib/user.php b/lib/user.php index 503ac3f7493..830f13bb8df 100644 --- a/lib/user.php +++ b/lib/user.php @@ -190,7 +190,7 @@ class OC_User { // use Reflection to create a new instance, using the $args $backend = $reflectionObj->newInstanceArgs($arguments); self::useBackend($backend); - $_setupedBackends[] = $i; + self::$_setupedBackends[] = $i; } else { OC_Log::write('core', 'User backend ' . $class . ' already initialized.', OC_Log::DEBUG); } @@ -213,7 +213,7 @@ class OC_User { * Allowed characters in the username are: "a-z", "A-Z", "0-9" and "_.@-" */ public static function createUser($uid, $password) { - self::getManager()->createUser($uid, $password); + return self::getManager()->createUser($uid, $password); } /** diff --git a/lib/user/database.php b/lib/user/database.php index d70b620f2ab..9f00a022d9f 100644 --- a/lib/user/database.php +++ b/lib/user/database.php @@ -85,7 +85,7 @@ class OC_User_Database extends OC_User_Backend { */ public function deleteUser( $uid ) { // Delete user-group-relation - $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*users` WHERE uid = ?' ); + $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*users` WHERE `uid` = ?' ); $query->execute( array( $uid )); return true; } diff --git a/lib/user/user.php b/lib/user/user.php index f9466b71499..55d7848a979 100644 --- a/lib/user/user.php +++ b/lib/user/user.php @@ -131,10 +131,10 @@ class User { * @return bool */ public function setPassword($password, $recoveryPassword) { + if ($this->emitter) { + $this->emitter->emit('\OC\User', 'preSetPassword', array($this, $password, $recoveryPassword)); + } if ($this->backend->implementsActions(\OC_USER_BACKEND_SET_PASSWORD)) { - if ($this->emitter) { - $this->emitter->emit('\OC\User', 'preSetPassword', array($this, $password, $recoveryPassword)); - } $result = $this->backend->setPassword($this->uid, $password); if ($this->emitter) { $this->emitter->emit('\OC\User', 'postSetPassword', array($this, $password, $recoveryPassword)); diff --git a/lib/util.php b/lib/util.php index 95af22ed0ee..4bc02daf36e 100755 --- a/lib/util.php +++ b/lib/util.php @@ -819,9 +819,9 @@ class OC_Util { * @return string the theme */ public static function getTheme() { - $theme = OC_Config::getValue("theme"); + $theme = OC_Config::getValue("theme", ''); - if(is_null($theme)) { + if($theme === '') { if(is_dir(OC::$SERVERROOT . '/themes/default')) { $theme = 'default'; @@ -833,6 +833,26 @@ class OC_Util { } /** + * Clear the opcode cache if one exists + * This is necessary for writing to the config file + * in case the opcode cache doesn't revalidate files + */ + public static function clearOpcodeCache() { + // APC + if (function_exists('apc_clear_cache')) { + apc_clear_cache(); + } + // Zend Opcache + if (function_exists('accelerator_reset')) { + accelerator_reset(); + } + // XCache + if (function_exists('xcache_clear_cache')) { + xcache_clear_cache(XC_TYPE_VAR, 0); + } + } + + /** * Normalize a unicode string * @param string $value a not normalized string * @return bool|string diff --git a/lib/vcategories.php b/lib/vcategories.php index 91c72d5dfae..7bac6e7d4e3 100644 --- a/lib/vcategories.php +++ b/lib/vcategories.php @@ -554,7 +554,7 @@ class OC_VCategories { } try { $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` ' - . 'WHERE `uid` = ? AND'); + . '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); |