diff options
author | Michael Gapczynski <mtgap@owncloud.com> | 2013-03-08 15:28:45 -0500 |
---|---|---|
committer | Michael Gapczynski <mtgap@owncloud.com> | 2013-03-08 15:28:45 -0500 |
commit | d7beac6d6f3ad588cee6c5ba8a2145b42fa184a2 (patch) | |
tree | 613f576938ee8ef88a5a93304a824f60fbb85a7a /lib | |
parent | 2ed850e05b46d820528813c2f2415dad60c1c570 (diff) | |
parent | 546fb72b25fb8ebdc70aa75ccc7a095d7d83b174 (diff) | |
download | nextcloud-server-d7beac6d6f3ad588cee6c5ba8a2145b42fa184a2.tar.gz nextcloud-server-d7beac6d6f3ad588cee6c5ba8a2145b42fa184a2.zip |
Merge branch 'master' into filecache_mtime
Conflicts:
lib/files/view.php
lib/util.php
tests/lib/files/cache/cache.php
Diffstat (limited to 'lib')
68 files changed, 1554 insertions, 463 deletions
diff --git a/lib/app.php b/lib/app.php index e653c30b2d9..55b4543ec9f 100644 --- a/lib/app.php +++ b/lib/app.php @@ -223,7 +223,7 @@ class OC_App{ // check if the app is compatible with this version of ownCloud $info=OC_App::getAppInfo($app); $version=OC_Util::getVersion(); - if(!isset($info['require']) or ($version[0]>$info['require'])) { + if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) { OC_Log::write('core', 'App "'.$info['name'].'" can\'t be installed because it is' .' not compatible with this version of ownCloud', @@ -851,7 +851,7 @@ class OC_App{ foreach($apps as $app) { // check if the app is compatible with this version of ownCloud $info = OC_App::getAppInfo($app); - if(!isset($info['require']) or (($version[0].'.'.$version[1])>$info['require'])) { + if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) { OC_Log::write('core', 'App "'.$info['name'].'" ('.$app.') can\'t be used because it is' .' not compatible with this version of ownCloud', @@ -862,6 +862,38 @@ class OC_App{ } } + + /** + * Compares the app version with the owncloud version to see if the app + * requires a newer version than the currently active one + * @param array $owncloudVersions array with 3 entries: major minor bugfix + * @param string $appRequired the required version from the xml + * major.minor.bugfix + * @return boolean true if compatible, otherwise false + */ + public static function isAppVersionCompatible($owncloudVersions, $appRequired){ + $appVersions = explode('.', $appRequired); + + for($i=0; $i<count($appVersions); $i++){ + $appVersion = (int) $appVersions[$i]; + + if(isset($owncloudVersions[$i])){ + $owncloudVersion = $owncloudVersions[$i]; + } else { + $owncloudVersion = 0; + } + + if($owncloudVersion < $appVersion){ + return false; + } elseif ($owncloudVersion > $appVersion) { + return true; + } + } + + return true; + } + + /** * get the installed version of all apps */ diff --git a/lib/arrayparser.php b/lib/arrayparser.php new file mode 100644 index 00000000000..3bb394a5163 --- /dev/null +++ b/lib/arrayparser.php @@ -0,0 +1,189 @@ +<?php + +/** + * @author Robin Appelman + * @copyright 2013 Robin Appelman icewind@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC; + +class SyntaxException extends \Exception { +} + +class ArrayParser { + const TYPE_NUM = 1; + const TYPE_BOOL = 2; + const TYPE_STRING = 3; + const TYPE_ARRAY = 4; + + function parsePHP($string) { + $string = $this->stripPHPTags($string); + $string = $this->stripAssignAndReturn($string); + return $this->parse($string); + } + + function stripPHPTags($string) { + $string = trim($string); + if (substr($string, 0, 5) === '<?php') { + $string = substr($string, 5); + } + if (substr($string, -2) === '?>') { + $string = substr($string, 0, -2); + } + return $string; + } + + function stripAssignAndReturn($string) { + $string = trim($string); + if (substr($string, 0, 6) === 'return') { + $string = substr($string, 6); + } + if (substr($string, 0, 1) === '$') { + list(, $string) = explode('=', $string, 2); + } + return $string; + } + + function parse($string) { + $string = trim($string); + $string = trim($string, ';'); + switch ($this->getType($string)) { + case self::TYPE_NUM: + return $this->parseNum($string); + case self::TYPE_BOOL: + return $this->parseBool($string); + case self::TYPE_STRING: + return $this->parseString($string); + case self::TYPE_ARRAY: + return $this->parseArray($string); + } + return null; + } + + function getType($string) { + $string = strtolower($string); + $first = substr($string, 0, 1); + $last = substr($string, -1, 1); + $arrayFirst = substr($string, 0, 5); + if (($first === '"' or $first === "'") and ($last === '"' or $last === "'")) { + return self::TYPE_STRING; + } elseif ($string === 'false' or $string === 'true') { + return self::TYPE_BOOL; + } elseif ($arrayFirst === 'array' and $last === ')') { + return self::TYPE_ARRAY; + } else { + return self::TYPE_NUM; + } + } + + function parseString($string) { + return substr($string, 1, -1); + } + + function parseNum($string) { + return intval($string); + } + + function parseBool($string) { + $string = strtolower($string); + return $string === 'true'; + } + + function parseArray($string) { + $body = substr($string, 5); + $body = trim($body); + $body = substr($body, 1, -1); + $items = $this->splitArray($body); + $result = array(); + $lastKey = -1; + foreach ($items as $item) { + $item = trim($item); + if ($item) { + if (strpos($item, '=>')) { + list($key, $value) = explode('=>', $item, 2); + $key = $this->parse($key); + $value = $this->parse($value); + } else { + $key = ++$lastKey; + $value = $item; + } + + if (is_numeric($key)) { + $lastKey = $key; + } + $result[$key] = $value; + } + } + return $result; + } + + function splitArray($body) { + $inSingleQuote = false;//keep track if we are inside quotes + $inDoubleQuote = false; + $bracketDepth = 0;//keep track if we are inside brackets + $parts = array(); + $start = 0; + $escaped = false;//keep track if we are after an escape character + $skips = array();//keep track of the escape characters we need to remove from the result + if (substr($body, -1, 1) !== ',') { + $body .= ','; + } + for ($i = 0; $i < strlen($body); $i++) { + $char = substr($body, $i, 1); + if ($char === '\\') { + if ($escaped) { + array_unshift($skips, $i - 1); + } + $escaped = !$escaped; + } else { + if ($char === '"' and !$inSingleQuote) { + if ($escaped) { + array_unshift($skips, $i - 1); + } else { + $inDoubleQuote = !$inDoubleQuote; + } + } elseif ($char === "'" and !$inDoubleQuote) { + if ($escaped) { + array_unshift($skips, $i - 1); + } else { + $inSingleQuote = !$inSingleQuote; + } + } elseif (!$inDoubleQuote and !$inSingleQuote) { + if ($char === '(') { + $bracketDepth++; + } elseif ($char === ')') { + if ($bracketDepth <= 0) { + throw new SyntaxException; + } else { + $bracketDepth--; + } + } elseif ($bracketDepth === 0 and $char === ',') { + $part = substr($body, $start, $i - $start); + foreach ($skips as $skip) { + $part = substr($part, 0, $skip - $start) . substr($part, $skip - $start + 1); + } + $parts[] = $part; + $start = $i + 1; + $skips = array(); + } + } + $escaped = false; + } + } + return $parts; + } +} diff --git a/lib/base.php b/lib/base.php index b5439c00abf..59b861ffce1 100644 --- a/lib/base.php +++ b/lib/base.php @@ -162,9 +162,9 @@ class OC { OC::$THIRDPARTYWEBROOT = rtrim(dirname(OC::$WEBROOT), '/'); OC::$THIRDPARTYROOT = rtrim(dirname(OC::$SERVERROOT), '/'); } else { - echo("3rdparty directory not found! Please put the ownCloud 3rdparty' + echo('3rdparty directory not found! Please put the ownCloud 3rdparty' .' folder in the ownCloud folder or the folder above.' - .' You can also configure the location in the config.php file."); + .' You can also configure the location in the config.php file.'); exit; } // search the apps folder @@ -188,8 +188,8 @@ class OC { } if (empty(OC::$APPSROOTS)) { - echo("apps directory not found! Please put the ownCloud apps folder in the ownCloud folder' - .' or the folder above. You can also configure the location in the config.php file."); + echo('apps directory not found! Please put the ownCloud apps folder in the ownCloud folder' + .' or the folder above. You can also configure the location in the config.php file.'); exit; } $paths = array(); @@ -214,8 +214,8 @@ class OC { $tmpl = new OC_Template('', 'error', 'guest'); $tmpl->assign('errors', array(1 => array( 'error' => "Can't write into config directory 'config'", - 'hint' => "You can usually fix this by giving the webserver user write access' - .' to the config directory in owncloud" + 'hint' => 'You can usually fix this by giving the webserver user write access' + .' to the config directory in owncloud' ))); $tmpl->printPage(); exit(); @@ -277,6 +277,10 @@ class OC { OC_Log::write('core', 'starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, OC_Log::DEBUG); + $minimizerCSS = new OC_Minimizer_CSS(); + $minimizerCSS->clearCache(); + $minimizerJS = new OC_Minimizer_JS(); + $minimizerJS->clearCache(); OC_Util::addscript('update'); $tmpl = new OC_Template('', 'update', 'guest'); $tmpl->assign('version', OC_Util::getVersionString()); @@ -320,19 +324,33 @@ class OC { // set the session name to the instance id - which is unique session_name(OC_Util::getInstanceId()); - // (re)-initialize session - session_start(); + // if session cant be started break with http 500 error + if (session_start() === false){ + OC_Log::write('core', 'Session could not be initialized', + OC_Log::ERROR); + + header('HTTP/1.1 500 Internal Server Error'); + OC_Util::addStyle("styles"); + $error = 'Session could not be initialized. Please contact your '; + $error .= 'system administrator'; + + $tmpl = new OC_Template('', 'error', 'guest'); + $tmpl->assign('errors', array(1 => array('error' => $error))); + $tmpl->printPage(); + + exit(); + } // regenerate session id periodically to avoid session fixation if (!isset($_SESSION['SID_CREATED'])) { $_SESSION['SID_CREATED'] = time(); - } else if (time() - $_SESSION['SID_CREATED'] > 900) { + } else if (time() - $_SESSION['SID_CREATED'] > 60*60*12) { session_regenerate_id(true); $_SESSION['SID_CREATED'] = time(); } // session timeout - if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 3600)) { + if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 60*60*24)) { if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time() - 42000, '/'); } @@ -525,7 +543,7 @@ class OC { 'setting locale to en_US.UTF-8/en_US.UTF8 failed. Support is probably not installed on your system', OC_Log::ERROR); } - if (OC_Config::getValue('installed', false)) { + if (OC_Config::getValue('installed', false) && !self::checkUpgrade(false)) { if (OC_Appconfig::getValue('core', 'backgroundjobs_mode', 'ajax') == 'ajax') { OC_Util::addScript('backgroundjobs'); } @@ -582,8 +600,10 @@ class OC { if (!self::$CLI) { try { - OC_App::loadApps(); - OC::getRouter()->match(OC_Request::getPathInfo()); + if (!OC_Config::getValue('maintenance', false)) { + OC_App::loadApps(); + } + OC::getRouter()->match(OC_Request::getRawPathInfo()); return; } catch (Symfony\Component\Routing\Exception\ResourceNotFoundException $e) { //header('HTTP/1.0 404 Not Found'); diff --git a/lib/config.php b/lib/config.php index a5c11b466f7..0bd497b8e50 100644 --- a/lib/config.php +++ b/lib/config.php @@ -166,8 +166,8 @@ class OC_Config{ $tmpl = new OC_Template( '', 'error', 'guest' ); $tmpl->assign('errors', array(1=>array( 'error'=>"Can't write into config directory 'config'", - 'hint'=>"You can usually fix this by giving the webserver user write access' - .' to the config directory in owncloud"))); + 'hint'=>'You can usually fix this by giving the webserver user write access' + .' to the config directory in owncloud'))); $tmpl->printPage(); exit; } diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index a9aa891d409..6ccb54b79ab 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -62,12 +62,12 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa } } else { $newPath = $this->path . '/' . $name; - + // mark file as partial while uploading (ignored by the scanner) $partpath = $newPath . '.part'; - + \OC\Files\Filesystem::file_put_contents($partpath, $data); - + //detect aborted upload if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT' ) { if (isset($_SERVER['CONTENT_LENGTH'])) { @@ -80,10 +80,10 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa } } } - + // rename to correct path \OC\Files\Filesystem::rename($partpath, $newPath); - + // allow sync clients to send the mtime along in a header $mtime = OC_Request::hasModificationTime(); if ($mtime !== false) { @@ -91,7 +91,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa header('X-OC-MTime: accepted'); } } - + return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); } @@ -107,7 +107,9 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa public function createDirectory($name) { $newPath = $this->path . '/' . $name; - \OC\Files\Filesystem::mkdir($newPath); + if(!\OC\Files\Filesystem::mkdir($newPath)) { + throw new Sabre_DAV_Exception_Forbidden('Could not create directory '.$newPath); + } } diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index c4c27e92251..91646312e90 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -47,9 +47,9 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D // mark file as partial while uploading (ignored by the scanner) $partpath = $this->path . '.part'; - + \OC\Files\Filesystem::file_put_contents($partpath, $data); - + //detect aborted upload if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT' ) { if (isset($_SERVER['CONTENT_LENGTH'])) { @@ -62,10 +62,10 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D } } } - + // rename to correct path \OC\Files\Filesystem::rename($partpath, $this->path); - + //allow sync clients to send the mtime along in a header $mtime = OC_Request::hasModificationTime(); if ($mtime !== false) { diff --git a/lib/connector/sabre/quotaplugin.php b/lib/connector/sabre/quotaplugin.php index ce9a968eb3c..c80a33d04b1 100644 --- a/lib/connector/sabre/quotaplugin.php +++ b/lib/connector/sabre/quotaplugin.php @@ -50,7 +50,8 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin { $uri='/'.$uri; } list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri); - if ($length > \OC\Files\Filesystem::free_space($parentUri)) { + $freeSpace = \OC\Files\Filesystem::free_space($parentUri); + if ($freeSpace !== \OC\Files\FREE_SPACE_UNKNOWN && $length > $freeSpace) { throw new Sabre_DAV_Exception_InsufficientStorage(); } } diff --git a/lib/db.php b/lib/db.php index edbc2fe13ed..347deac8519 100644 --- a/lib/db.php +++ b/lib/db.php @@ -42,6 +42,7 @@ class OC_DB { const BACKEND_MDB2=1; static private $preparedQueries = array(); + static private $cachingEnabled = true; /** * @var MDB2_Driver_Common @@ -178,6 +179,13 @@ class OC_DB { $dsn = 'oci:dbname=//' . $host . '/' . $name; } break; + case 'mssql': + if ($port) { + $dsn='sqlsrv:Server='.$host.','.$port.';Database='.$name; + } else { + $dsn='sqlsrv:Server='.$host.';Database='.$name; + } + break; default: return false; } @@ -278,6 +286,15 @@ class OC_DB { $dsn['database'] = $user; } break; + case 'mssql': + $dsn = array( + 'phptype' => 'sqlsrv', + 'username' => $user, + 'password' => $pass, + 'hostspec' => $host, + 'database' => $name + ); + break; default: return false; } @@ -340,7 +357,7 @@ class OC_DB { } } } else { - if (isset(self::$preparedQueries[$query])) { + if (isset(self::$preparedQueries[$query]) and self::$cachingEnabled) { return self::$preparedQueries[$query]; } } @@ -366,8 +383,11 @@ class OC_DB { } $result=new PDOStatementWrapper($result); } - if (is_null($limit) || $limit == -1) { - self::$preparedQueries[$rawQuery] = $result; + if ((is_null($limit) || $limit == -1) and self::$cachingEnabled ) { + $type = OC_Config::getValue( "dbtype", "sqlite" ); + if( $type != 'sqlite' && $type != 'sqlite3' ) { + self::$preparedQueries[$rawQuery] = $result; + } } return $result; } @@ -389,6 +409,13 @@ class OC_DB { $query = self::prepare('SELECT lastval() AS id'); $row = $query->execute()->fetchRow(); return $row['id']; + } + if( $type == 'mssql' ) { + if($table !== null) { + $prefix = OC_Config::getValue( "dbtableprefix", "oc_" ); + $table = str_replace( '*PREFIX*', $prefix, $table ); + } + return self::$connection->lastInsertId($table); }else{ if($table !== null) { $prefix = OC_Config::getValue( "dbtableprefix", "oc_" ); @@ -631,7 +658,7 @@ class OC_DB { } else { return true; } - } elseif( $type == 'pgsql' || $type == 'oci' || $type == 'mysql') { + } elseif( $type == 'pgsql' || $type == 'oci' || $type == 'mysql' || $type == 'mssql') { $query = 'INSERT INTO `' .$table . '` (' . implode(',', array_keys($input)) . ') SELECT \'' . implode('\',\'', array_values($input)) . '\' FROM ' . $table . ' WHERE '; @@ -691,7 +718,15 @@ class OC_DB { }elseif( $type == 'oci' ) { $query = str_replace( '`', '"', $query ); $query = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $query ); - } + }elseif( $type == 'mssql' ) { + $query = preg_replace( "/\`(.*?)`/", "[$1]", $query ); + $query = str_replace( 'NOW()', 'CURRENT_TIMESTAMP', $query ); + $query = str_replace( 'now()', 'CURRENT_TIMESTAMP', $query ); + $query = str_replace( 'LENGTH(', 'LEN(', $query ); + $query = str_replace( 'SUBSTR(', 'SUBSTRING(', $query ); + + $query = self::fixLimitClauseForMSSQL($query); + } // replace table name prefix $query = str_replace( '*PREFIX*', $prefix, $query ); @@ -699,6 +734,60 @@ class OC_DB { return $query; } + private static function fixLimitClauseForMSSQL($query) { + $limitLocation = stripos ($query, "LIMIT"); + + if ( $limitLocation === false ) { + return $query; + } + + // total == 0 means all results - not zero results + // + // First number is either total or offset, locate it by first space + // + $offset = substr ($query, $limitLocation + 5); + $offset = substr ($offset, 0, stripos ($offset, ' ')); + $offset = trim ($offset); + + // check for another parameter + if (stripos ($offset, ',') === false) { + // no more parameters + $offset = 0; + $total = intval ($offset); + } else { + // found another parameter + $offset = intval ($offset); + + $total = substr ($query, $limitLocation + 5); + $total = substr ($total, stripos ($total, ',')); + + $total = substr ($total, 0, stripos ($total, ' ')); + $total = intval ($total); + } + + $query = trim (substr ($query, 0, $limitLocation)); + + if ($offset == 0 && $total !== 0) { + if (strpos($query, "SELECT") === false) { + $query = "TOP {$total} " . $query; + } else { + $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP '.$total, $query); + } + } else if ($offset > 0) { + $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP(10000000) ', $query); + $query = 'SELECT * + FROM (SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3 + FROM (SELECT 1 AS line2, sub1.* FROM (' . $query . ') AS sub1) as sub2) AS sub3'; + + if ($total > 0) { + $query .= ' WHERE line3 BETWEEN ' . ($offset + 1) . ' AND ' . ($offset + $total); + } else { + $query .= ' WHERE line3 > ' . $offset; + } + } + return $query; + } + /** * @brief drop a table * @param string $tableName the table to drop @@ -830,6 +919,16 @@ class OC_DB { } return $msg; } + + /** + * @param bool $enabled + */ + static public function enableCaching($enabled) { + if (!$enabled) { + self::$preparedQueries = array(); + } + self::$cachingEnabled = $enabled; + } } /** @@ -850,19 +949,119 @@ class PDOStatementWrapper{ * make execute return the result instead of a bool */ public function execute($input=array()) { - $this->lastArguments=$input; - if(count($input)>0) { + $this->lastArguments = $input; + if (count($input) > 0) { + + if (!isset($type)) { + $type = OC_Config::getValue( "dbtype", "sqlite" ); + } + + if ($type == 'mssql') { + $input = $this->tryFixSubstringLastArgumentDataForMSSQL($input); + } + $result=$this->statement->execute($input); - }else{ + } else { $result=$this->statement->execute(); } - if($result) { + + if ($result) { return $this; - }else{ + } else { return false; } } + private function tryFixSubstringLastArgumentDataForMSSQL($input) { + $query = $this->statement->queryString; + $pos = stripos ($query, 'SUBSTRING'); + + if ( $pos === false) { + return; + } + + try { + $newQuery = ''; + + $cArg = 0; + + $inSubstring = false; + + // Create new query + for ($i = 0; $i < strlen ($query); $i++) { + if ($inSubstring == false) { + // Defines when we should start inserting values + if (substr ($query, $i, 9) == 'SUBSTRING') { + $inSubstring = true; + } + } else { + // Defines when we should stop inserting values + if (substr ($query, $i, 1) == ')') { + $inSubstring = false; + } + } + + if (substr ($query, $i, 1) == '?') { + // We found a question mark + if ($inSubstring) { + $newQuery .= $input[$cArg]; + + // + // Remove from input array + // + array_splice ($input, $cArg, 1); + } else { + $newQuery .= substr ($query, $i, 1); + $cArg++; + } + } else { + $newQuery .= substr ($query, $i, 1); + } + } + + // The global data we need + $name = OC_Config::getValue( "dbname", "owncloud" ); + $host = OC_Config::getValue( "dbhost", "" ); + $user = OC_Config::getValue( "dbuser", "" ); + $pass = OC_Config::getValue( "dbpassword", "" ); + if (strpos($host,':')) { + list($host, $port) = explode(':', $host, 2); + } else { + $port = false; + } + $opts = array(); + + if ($port) { + $dsn = 'sqlsrv:Server='.$host.','.$port.';Database='.$name; + } else { + $dsn = 'sqlsrv:Server='.$host.';Database='.$name; + } + + $PDO = new PDO($dsn, $user, $pass, $opts); + $PDO->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + $this->statement = $PDO->prepare($newQuery); + + $this->lastArguments = $input; + + return $input; + } catch (PDOException $e){ + $entry = 'PDO DB Error: "'.$e->getMessage().'"<br />'; + $entry .= 'Offending command was: '.$this->statement->queryString .'<br />'; + $entry .= 'Input parameters: ' .print_r($input, true).'<br />'; + $entry .= 'Stack trace: ' .$e->getTraceAsString().'<br />'; + OC_Log::write('core', $entry, OC_Log::FATAL); + OC_User::setUserId(null); + + // send http status 503 + header('HTTP/1.1 503 Service Temporarily Unavailable'); + header('Status: 503 Service Temporarily Unavailable'); + OC_Template::printErrorPage('Failed to connect to database'); + die ($entry); + } + } + /** * provide numRows */ diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index 07d1d250e4d..3dac3264fbe 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -62,21 +62,21 @@ class OC_FileProxy_Quota extends OC_FileProxy{ * @var string $internalPath */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); - $owner=$storage->getOwner($internalPath); + $owner = $storage->getOwner($internalPath); if (!$owner) { return -1; } - $totalSpace=$this->getQuota($owner); - if($totalSpace==-1) { + $totalSpace = $this->getQuota($owner); + if($totalSpace == -1) { return -1; } $view = new \OC\Files\View("/".$owner."/files"); - $rootInfo=$view->getFileInfo('/'); - $usedSpace=isset($rootInfo['size'])?$rootInfo['size']:0; - return $totalSpace-$usedSpace; + $rootInfo = $view->getFileInfo('/'); + $usedSpace = isset($rootInfo['size'])?$rootInfo['size']:0; + return $totalSpace - $usedSpace; } public function postFree_space($path, $space) { @@ -84,6 +84,9 @@ class OC_FileProxy_Quota extends OC_FileProxy{ if($free==-1) { return $space; } + if ($space < 0){ + return $free; + } return min($free, $space); } diff --git a/lib/files.php b/lib/files.php index b594b78c4b7..71bb21851b6 100644 --- a/lib/files.php +++ b/lib/files.php @@ -49,8 +49,9 @@ class OC_Files { isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { $xsendfile = true; } - if(strpos($files, ';')) { - $files=explode(';', $files); + + if (count($files) == 1) { + $files = $files[0]; } if (is_array($files)) { @@ -77,7 +78,13 @@ class OC_Files { } } $zip->close(); - $name = basename($dir) . '.zip'; + $basename = basename($dir); + if ($basename) { + $name = $basename . '.zip'; + } else { + $name = 'owncloud.zip'; + } + set_time_limit($executionTime); } elseif (\OC\Files\Filesystem::is_dir($dir . '/' . $files)) { self::validateZipDownload($dir, $files); @@ -212,12 +219,18 @@ class OC_Files { $zipLimit = OC_Config::getValue('maxZipInputSize', OC_Helper::computerFileSize('800 MB')); if ($zipLimit > 0) { $totalsize = 0; - if (is_array($files)) { - foreach ($files as $file) { - $totalsize += \OC\Files\Filesystem::filesize($dir . '/' . $file); + if(!is_array($files)) { + $files = array($files); + } + foreach ($files as $file) { + $path = $dir . '/' . $file; + if(\OC\Files\Filesystem::is_dir($path)) { + foreach (\OC\Files\Filesystem::getDirectoryContent($path) as $i) { + $totalsize += $i['size']; + } + } else { + $totalsize += \OC\Files\Filesystem::filesize($path); } - } else { - $totalsize += \OC\Files\Filesystem::filesize($dir . '/' . $files); } if ($totalsize > $zipLimit) { $l = OC_L10N::get('lib'); diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 65f33c5f797..2413c05b8cd 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -48,6 +48,9 @@ class Cache { } else { $this->storageId = $storage; } + if (strlen($this->storageId) > 64) { + $this->storageId = md5($this->storageId); + } $query = \OC_DB::prepare('SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?'); $result = $query->execute(array($this->storageId)); @@ -205,7 +208,7 @@ class Cache { $valuesPlaceholder = array_fill(0, count($queryParts), '?'); $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ')' - .' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); + . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); return (int)\OC_DB::insertid('*PREFIX*filecache'); @@ -223,7 +226,7 @@ class Cache { $params[] = $id; $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=?' - .' WHERE fileid = ?'); + . ' WHERE fileid = ?'); $query->execute($params); } @@ -321,6 +324,9 @@ class Cache { } $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?'); $query->execute(array($entry['fileid'])); + + $permissionsCache = new Permissions($this->storageId); + $permissionsCache->remove($entry['fileid']); } /** @@ -346,7 +352,7 @@ class Cache { } $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ?, `parent` =?' - .' WHERE `fileid` = ?'); + . ' WHERE `fileid` = ?'); $query->execute(array($target, md5($target), $newParentId, $sourceId)); } @@ -507,9 +513,9 @@ class Cache { */ public function getIncomplete() { $query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache`' - .' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC LIMIT 1'); - $query->execute(array($this->numericId)); - if ($row = $query->fetchRow()) { + . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC LIMIT 1'); + $result = $query->execute(array($this->numericId)); + if ($row = $result->fetchRow()) { return $row['path']; } else { return false; diff --git a/lib/files/cache/legacy.php b/lib/files/cache/legacy.php index 6d1ffa7b40b..2b8689fcbda 100644 --- a/lib/files/cache/legacy.php +++ b/lib/files/cache/legacy.php @@ -51,12 +51,12 @@ class Legacy { $this->cacheHasItems = false; return false; } - + if ($result === false || property_exists($result, 'error_message_prefix')) { $this->cacheHasItems = false; return false; - } - + } + $this->cacheHasItems = (bool)$result->fetchRow(); return $this->cacheHasItems; } diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php index e1735831b94..a5c9c144054 100644 --- a/lib/files/cache/permissions.php +++ b/lib/files/cache/permissions.php @@ -17,10 +17,10 @@ class Permissions { /** * @param \OC\Files\Storage\Storage|string $storage */ - public function __construct($storage){ - if($storage instanceof \OC\Files\Storage\Storage) { + public function __construct($storage) { + if ($storage instanceof \OC\Files\Storage\Storage) { $this->storageId = $storage->getId(); - }else{ + } else { $this->storageId = $storage; } } @@ -52,10 +52,10 @@ 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` = ?'); + . ' WHERE `user` = ? AND `fileid` = ?'); } else { $query = \OC_DB::prepare('INSERT INTO `*PREFIX*permissions`(`permissions`, `user`, `fileid`)' - .' VALUES(?, ?,? )'); + . ' VALUES(?, ?,? )'); } $query->execute(array($permissions, $user, $fileId)); } @@ -76,7 +76,7 @@ class Permissions { $inPart = implode(', ', array_fill(0, count($fileIds), '?')); $query = \OC_DB::prepare('SELECT `fileid`, `permissions` FROM `*PREFIX*permissions`' - .' WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); + . ' WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); $result = $query->execute($params); $filePermissions = array(); while ($row = $result->fetchRow()) { @@ -91,14 +91,19 @@ class Permissions { * @param int $fileId * @param string $user */ - public function remove($fileId, $user) { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); - $query->execute(array($fileId, $user)); + public function remove($fileId, $user = null) { + if (is_null($user)) { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ?'); + $query->execute(array($fileId)); + } else { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); + $query->execute(array($fileId, $user)); + } } public function removeMultiple($fileIds, $user) { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); - foreach($fileIds as $fileId){ + foreach ($fileIds as $fileId) { $query->execute(array($fileId, $user)); } } diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 1fe4c584686..811d82d7437 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -64,7 +64,7 @@ class Upgrade { * @param array $data the data for the new cache */ function insert($data) { - if (!$this->inCache($data['storage'], $data['path_hash'])) { + if (!$this->inCache($data['storage'], $data['path_hash'], $data['id'])) { $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` ( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); @@ -78,11 +78,12 @@ class Upgrade { /** * @param string $storage * @param string $pathHash + * @param string $id * @return bool */ - function inCache($storage, $pathHash) { - $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($storage, $pathHash)); + function inCache($storage, $pathHash, $id) { + $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE (`storage` = ? AND `path_hash` = ?) OR `fileid` = ?'); + $result = $query->execute(array($storage, $pathHash, $id)); return (bool)$result->fetchRow(); } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index f4530868077..0bbd7550d74 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -29,6 +29,8 @@ namespace OC\Files; +const FREE_SPACE_UNKNOWN = -2; + class Filesystem { public static $loaded = false; /** @@ -215,9 +217,18 @@ class Filesystem { if ($user == '') { $user = \OC_User::getUser(); } + $parser = new \OC\ArrayParser(); + + $root = \OC_User::getHome($user); + self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); + // Load system mount points - if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { - $mountConfig = include 'config/mount.php'; + if (is_file(\OC::$SERVERROOT . '/config/mount.php') or is_file(\OC::$SERVERROOT . '/config/mount.json')) { + if (is_file(\OC::$SERVERROOT . '/config/mount.json')) { + $mountConfig = json_decode(file_get_contents(\OC::$SERVERROOT . '/config/mount.json'), true); + } elseif (is_file(\OC::$SERVERROOT . '/config/mount.php')) { + $mountConfig = $parser->parsePHP(file_get_contents(\OC::$SERVERROOT . '/config/mount.php')); + } if (isset($mountConfig['global'])) { foreach ($mountConfig['global'] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); @@ -251,10 +262,12 @@ class Filesystem { } } // Load personal mount points - $root = \OC_User::getHome($user); - self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); - if (is_file($root . '/mount.php')) { - $mountConfig = include $root . '/mount.php'; + if (is_file($root . '/mount.php') or is_file($root . '/mount.json')) { + if (is_file($root . '/mount.json')) { + $mountConfig = json_decode(file_get_contents($root . '/mount.json'), true); + } elseif (is_file($root . '/mount.php')) { + $mountConfig = $parser->parsePHP(file_get_contents($root . '/mount.php')); + } if (isset($mountConfig['user'][$user])) { foreach ($mountConfig['user'][$user] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); @@ -377,21 +390,29 @@ class Filesystem { * @param array $data from hook */ static public function isBlacklisted($data) { - $blacklist = \OC_Config::getValue('blacklisted_files', array('.htaccess')); if (isset($data['path'])) { $path = $data['path']; } else if (isset($data['newpath'])) { $path = $data['newpath']; } if (isset($path)) { - $filename = strtolower(basename($path)); - if (in_array($filename, $blacklist)) { + if (self::isFileBlacklisted($path)) { $data['run'] = false; } } } /** + * @param string $filename + * @return bool + */ + static public function isFileBlacklisted($filename) { + $blacklist = \OC_Config::getValue('blacklisted_files', array('.htaccess')); + $filename = strtolower(basename($filename)); + return (in_array($filename, $blacklist)); + } + + /** * following functions are equivalent to their php builtin equivalents for arguments/return values. */ static public function mkdir($path) { @@ -613,11 +634,11 @@ class Filesystem { } /** - * Get the owner for a file or folder - * - * @param string $path - * @return string - */ + * Get the owner for a file or folder + * + * @param string $path + * @return string + */ public static function getOwner($path) { return self::$defaultInstance->getOwner($path); } diff --git a/lib/files/mapper.php b/lib/files/mapper.php index cd163dcbfcd..520fadbd8c6 100644 --- a/lib/files/mapper.php +++ b/lib/files/mapper.php @@ -7,6 +7,12 @@ namespace OC\Files; */ class Mapper { + private $unchangedPhysicalRoot; + + public function __construct($rootDir) { + $this->unchangedPhysicalRoot = $rootDir; + } + /** * @param string $logicPath * @param bool $create indicates if the generated physical name shall be stored in the database or not @@ -23,7 +29,7 @@ class Mapper /** * @param string $physicalPath - * @return string|null + * @return string */ public function physicalToLogic($physicalPath) { $logicPath = $this->resolvePhysicalPath($physicalPath); @@ -39,6 +45,7 @@ class Mapper * @param string $path * @param bool $isLogicPath indicates if $path is logical or physical * @param $recursive + * @return void */ public function removePath($path, $isLogicPath, $recursive) { if ($recursive) { @@ -159,14 +166,11 @@ class Mapper } private function slugifyPath($path, $index=null) { + $path = $this->stripRootFolder($path, $this->unchangedPhysicalRoot); + $pathElements = explode('/', $path); $sluggedElements = array(); - // skip slugging the drive letter on windows - TODO: test if local path - if (\OC_Util::runningOnWindows()) { - $sluggedElements[]= $pathElements[0]; - array_shift($pathElements); - } foreach ($pathElements as $pathElement) { // remove empty elements if (empty($pathElement)) { @@ -186,12 +190,8 @@ class Mapper array_push($sluggedElements, $last.'-'.$index); } - // on non-windows systems add the leading / if necessary - if (!\OC_Util::runningOnWindows() and $path[0] === '/') { - return DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $sluggedElements); - } - - return implode(DIRECTORY_SEPARATOR, $sluggedElements); + $sluggedPath = $this->unchangedPhysicalRoot.implode(DIRECTORY_SEPARATOR, $sluggedElements); + return $this->stripLast($sluggedPath); } /** diff --git a/lib/files/mount.php b/lib/files/mount.php index 74ee483b1be..1c9382d78e7 100644 --- a/lib/files/mount.php +++ b/lib/files/mount.php @@ -93,6 +93,9 @@ class Mount { $this->storage = $this->createStorage(); } $this->storageId = $this->storage->getId(); + if (strlen($this->storageId) > 64) { + $this->storageId = md5($this->storageId); + } } return $this->storageId; } @@ -173,10 +176,15 @@ class Mount { } /** + * Find mounts by storage id + * * @param string $id - * @return \OC\Files\Storage\Storage[] + * @return Mount[] */ - public static function findById($id) { + public static function findByStorageId($id) { + if (strlen($id) > 64) { + $id = md5($id); + } $result = array(); foreach (self::$mounts as $mount) { if ($mount->getStorageId() === $id) { @@ -185,4 +193,24 @@ class Mount { } return $result; } + + /** + * Find mounts by numeric storage id + * + * @param string $id + * @return Mount + */ + public static function findByNumericId($id) { + $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*storages` WHERE `numeric_id` = ?'); + $result = $query->execute(array($id))->fetchOne(); + if ($result) { + $id = $result; + foreach (self::$mounts as $mount) { + if ($mount->getStorageId() === $id) { + return $mount; + } + } + } + return false; + } } diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 4cdabf1c8a6..8aa227ec0b7 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -22,83 +22,104 @@ namespace OC\Files\Storage; abstract class Common implements \OC\Files\Storage\Storage { - public function __construct($parameters) {} + public function __construct($parameters) { + } + public function is_dir($path) { - return $this->filetype($path)=='dir'; + return $this->filetype($path) == 'dir'; } + public function is_file($path) { - return $this->filetype($path)=='file'; + return $this->filetype($path) == 'file'; } + public function filesize($path) { - if($this->is_dir($path)) { - return 0;//by definition - }else{ + if ($this->is_dir($path)) { + return 0; //by definition + } else { $stat = $this->stat($path); - return $stat['size']; + if (isset($stat['size'])) { + return $stat['size']; + } else { + return 0; + } } } + public function isCreatable($path) { if ($this->is_dir($path) && $this->isUpdatable($path)) { return true; } return false; } + public function isDeletable($path) { return $this->isUpdatable($path); } + public function isSharable($path) { return $this->isReadable($path); } - public function getPermissions($path){ + + public function getPermissions($path) { $permissions = 0; - if($this->isCreatable($path)) { + if ($this->isCreatable($path)) { $permissions |= \OCP\PERMISSION_CREATE; } - if($this->isReadable($path)) { + if ($this->isReadable($path)) { $permissions |= \OCP\PERMISSION_READ; } - if($this->isUpdatable($path)) { + if ($this->isUpdatable($path)) { $permissions |= \OCP\PERMISSION_UPDATE; } - if($this->isDeletable($path)) { + if ($this->isDeletable($path)) { $permissions |= \OCP\PERMISSION_DELETE; } - if($this->isSharable($path)) { + if ($this->isSharable($path)) { $permissions |= \OCP\PERMISSION_SHARE; } return $permissions; } + public function filemtime($path) { $stat = $this->stat($path); - return $stat['mtime']; + if (isset($stat['mtime'])) { + return $stat['mtime']; + } else { + return 0; + } } + public function file_get_contents($path) { $handle = $this->fopen($path, "r"); - if(!$handle) { + if (!$handle) { return false; } - $size=$this->filesize($path); - if($size==0) { + $size = $this->filesize($path); + if ($size == 0) { return ''; } return fread($handle, $size); } + public function file_put_contents($path, $data) { $handle = $this->fopen($path, "w"); return fwrite($handle, $data); } + public function rename($path1, $path2) { - if($this->copy($path1, $path2)) { + if ($this->copy($path1, $path2)) { return $this->unlink($path1); - }else{ + } else { return false; } } + public function copy($path1, $path2) { - $source=$this->fopen($path1, 'r'); - $target=$this->fopen($path2, 'w'); - $count=\OC_Helper::streamCopy($source, $target); - return $count>0; + $source = $this->fopen($path1, 'r'); + $target = $this->fopen($path2, 'w'); + list($count, $result) = \OC_Helper::streamCopy($source, $target); + return $result; } /** @@ -110,29 +131,30 @@ abstract class Common implements \OC\Files\Storage\Storage { * @note By default the directory specified by $directory will be * deleted together with its contents. To avoid this set $empty to true */ - public function deleteAll( $directory, $empty = false ) { + public function deleteAll($directory, $empty = false) { $directory = trim($directory, '/'); - if ( !$this->file_exists( \OCP\USER::getUser() . '/' . $directory ) - || !$this->is_dir( \OCP\USER::getUser() . '/' . $directory ) ) { + if (!$this->file_exists(\OCP\USER::getUser() . '/' . $directory) + || !$this->is_dir(\OCP\USER::getUser() . '/' . $directory) + ) { return false; - } elseif( !$this->isReadable( \OCP\USER::getUser() . '/' . $directory ) ) { + } elseif (!$this->isReadable(\OCP\USER::getUser() . '/' . $directory)) { return false; } else { - $directoryHandle = $this->opendir( \OCP\USER::getUser() . '/' . $directory ); - while ( $contents = readdir( $directoryHandle ) ) { - if ( $contents != '.' && $contents != '..') { + $directoryHandle = $this->opendir(\OCP\USER::getUser() . '/' . $directory); + while ($contents = readdir($directoryHandle)) { + if ($contents != '.' && $contents != '..') { $path = $directory . "/" . $contents; - if ( $this->is_dir( $path ) ) { - $this->deleteAll( $path ); + if ($this->is_dir($path)) { + $this->deleteAll($path); } else { - $this->unlink( \OCP\USER::getUser() .'/' . $path ); // TODO: make unlink use same system path as is_dir + $this->unlink(\OCP\USER::getUser() . '/' . $path); // TODO: make unlink use same system path as is_dir } } } //$this->closedir( $directoryHandle ); // TODO: implement closedir in OC_FSV - if ( $empty == false ) { - if ( !$this->rmdir( $directory ) ) { + if ($empty == false) { + if (!$this->rmdir($directory)) { return false; } } @@ -140,88 +162,95 @@ abstract class Common implements \OC\Files\Storage\Storage { } } + public function getMimeType($path) { - if(!$this->file_exists($path)) { + if (!$this->file_exists($path)) { return false; } - if($this->is_dir($path)) { + if ($this->is_dir($path)) { return 'httpd/unix-directory'; } - $source=$this->fopen($path, 'r'); - if(!$source) { + $source = $this->fopen($path, 'r'); + if (!$source) { return false; } - $head=fread($source, 8192);//8kb should suffice to determine a mimetype - if($pos=strrpos($path, '.')) { - $extension=substr($path, $pos); - }else{ - $extension=''; + $head = fread($source, 8192); //8kb should suffice to determine a mimetype + if ($pos = strrpos($path, '.')) { + $extension = substr($path, $pos); + } else { + $extension = ''; } - $tmpFile=\OC_Helper::tmpFile($extension); + $tmpFile = \OC_Helper::tmpFile($extension); file_put_contents($tmpFile, $head); - $mime=\OC_Helper::getMimeType($tmpFile); + $mime = \OC_Helper::getMimeType($tmpFile); unlink($tmpFile); return $mime; } + public function hash($type, $path, $raw = false) { - $tmpFile=$this->getLocalFile($path); - $hash=hash($type, $tmpFile, $raw); + $tmpFile = $this->getLocalFile($path); + $hash = hash($type, $tmpFile, $raw); unlink($tmpFile); return $hash; } + public function search($query) { return $this->searchInDir($query); } + public function getLocalFile($path) { return $this->toTmpFile($path); } - private function toTmpFile($path) {//no longer in the storage api, still useful here - $source=$this->fopen($path, 'r'); - if(!$source) { + + private function toTmpFile($path) { //no longer in the storage api, still useful here + $source = $this->fopen($path, 'r'); + if (!$source) { return false; } - if($pos=strrpos($path, '.')) { - $extension=substr($path, $pos); - }else{ - $extension=''; + if ($pos = strrpos($path, '.')) { + $extension = substr($path, $pos); + } else { + $extension = ''; } - $tmpFile=\OC_Helper::tmpFile($extension); - $target=fopen($tmpFile, 'w'); + $tmpFile = \OC_Helper::tmpFile($extension); + $target = fopen($tmpFile, 'w'); \OC_Helper::streamCopy($source, $target); return $tmpFile; } + public function getLocalFolder($path) { - $baseDir=\OC_Helper::tmpFolder(); + $baseDir = \OC_Helper::tmpFolder(); $this->addLocalFolder($path, $baseDir); return $baseDir; } + private function addLocalFolder($path, $target) { - if($dh=$this->opendir($path)) { - while($file=readdir($dh)) { - if($file!=='.' and $file!=='..') { - if($this->is_dir($path.'/'.$file)) { - mkdir($target.'/'.$file); - $this->addLocalFolder($path.'/'.$file, $target.'/'.$file); - }else{ - $tmp=$this->toTmpFile($path.'/'.$file); - rename($tmp, $target.'/'.$file); + if ($dh = $this->opendir($path)) { + while ($file = readdir($dh)) { + if ($file !== '.' and $file !== '..') { + if ($this->is_dir($path . '/' . $file)) { + mkdir($target . '/' . $file); + $this->addLocalFolder($path . '/' . $file, $target . '/' . $file); + } else { + $tmp = $this->toTmpFile($path . '/' . $file); + rename($tmp, $target . '/' . $file); } } } } } - protected function searchInDir($query, $dir='') { - $files=array(); - $dh=$this->opendir($dir); - if($dh) { - while($item=readdir($dh)) { + protected function searchInDir($query, $dir = '') { + $files = array(); + $dh = $this->opendir($dir); + if ($dh) { + while ($item = readdir($dh)) { if ($item == '.' || $item == '..') continue; - if(strstr(strtolower($item), strtolower($query))!==false) { - $files[]=$dir.'/'.$item; + if (strstr(strtolower($item), strtolower($query)) !== false) { + $files[] = $dir . '/' . $item; } - if($this->is_dir($dir.'/'.$item)) { - $files=array_merge($files, $this->searchInDir($query, $dir.'/'.$item)); + if ($this->is_dir($dir . '/' . $item)) { + $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item)); } } } @@ -230,32 +259,34 @@ abstract class Common implements \OC\Files\Storage\Storage { /** * check if a file or folder has been updated since $time + * * @param string $path * @param int $time * @return bool */ public function hasUpdated($path, $time) { - return $this->filemtime($path)>$time; + return $this->filemtime($path) > $time; } - public function getCache($path=''){ + public function getCache($path = '') { return new \OC\Files\Cache\Cache($this); } - public function getScanner($path=''){ + public function getScanner($path = '') { return new \OC\Files\Cache\Scanner($this); } - public function getPermissionsCache($path=''){ + public function getPermissionsCache($path = '') { return new \OC\Files\Cache\Permissions($this); } - public function getWatcher($path=''){ + public function getWatcher($path = '') { return new \OC\Files\Cache\Watcher($this); } /** * get the owner of a path + * * @param string $path The path to get the owner * @return string uid or false */ @@ -269,19 +300,20 @@ abstract class Common implements \OC\Files\Storage\Storage { * @param string $path * @return string */ - public function getETag($path){ + public function getETag($path) { $ETagFunction = \OC_Connector_Sabre_Node::$ETagFunction; - if($ETagFunction) { + if ($ETagFunction) { $hash = call_user_func($ETagFunction, $path); return $hash; - }else{ + } else { return uniqid(); } } - + /** * clean a path, i.e. remove all redundant '.' and '..' * making sure that it can't point to higher than '/' + * * @param $path The path to clean * @return string cleaned path */ @@ -289,7 +321,7 @@ abstract class Common implements \OC\Files\Storage\Storage { if (strlen($path) == 0 or $path[0] != '/') { $path = '/' . $path; } - + $output = array(); foreach (explode('/', $path) as $chunk) { if ($chunk == '..') { @@ -301,4 +333,21 @@ abstract class Common implements \OC\Files\Storage\Storage { } return implode('/', $output); } + + public function test() { + if ($this->stat('')) { + return true; + } + return false; + } + + /** + * get the free space in the storage + * + * @param $path + * return int + */ + public function free_space($path) { + return \OC\Files\FREE_SPACE_UNKNOWN; + } } diff --git a/lib/files/storage/mappedlocal.php b/lib/files/storage/mappedlocal.php index e707f71d71c..434c10bcbf7 100644 --- a/lib/files/storage/mappedlocal.php +++ b/lib/files/storage/mappedlocal.php @@ -20,7 +20,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ $this->datadir.='/'; } - $this->mapper= new \OC\Files\Mapper(); + $this->mapper= new \OC\Files\Mapper($this->datadir); } public function __destruct() { if (defined('PHPUNIT_RUN')) { @@ -274,7 +274,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ return $this->buildPath($path); } - protected function searchInDir($query, $dir='', $isLogicPath=true) { + protected function searchInDir($query, $dir='') { $files=array(); $physicalDir = $this->buildPath($dir); foreach (scandir($physicalDir) as $item) { @@ -287,7 +287,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ $files[]=$dir.'/'.$item; } if(is_dir($physicalItem)) { - $files=array_merge($files, $this->searchInDir($query, $physicalItem, false)); + $files=array_merge($files, $this->searchInDir($query, $dir.'/'.$item)); } } return $files; diff --git a/lib/files/view.php b/lib/files/view.php index 3348244715e..3cea8b082dc 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -199,7 +199,7 @@ class View { @ob_end_clean(); $handle = $this->fopen($path, 'rb'); if ($handle) { - $chunkSize = 8192; // 8 MB chunks + $chunkSize = 8192; // 8 kB chunks while (!feof($handle)) { echo fread($handle, $chunkSize); flush(); @@ -245,7 +245,11 @@ class View { if (!is_null($mtime) and !is_numeric($mtime)) { $mtime = strtotime($mtime); } - $result = $this->basicOperation('touch', $path, array('write'), $mtime); + $hooks = array('touch'); + if (!$this->file_exists($path)) { + $hooks[] = 'write'; + } + $result = $this->basicOperation('touch', $path, $hooks, $mtime); if (!$result) { //if native touch fails, we emulate it by changing the mtime in the cache $this->putFileInfo($path, array('mtime' => $mtime)); } @@ -289,7 +293,7 @@ class View { } $target = $this->fopen($path, 'w'); if ($target) { - $count = \OC_Helper::streamCopy($data, $target); + list ($count, $result) = \OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); if ($this->fakeRoot == Filesystem::getRoot()) { @@ -307,7 +311,7 @@ class View { ); } \OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); - return $count > 0; + return $result; } else { return false; } @@ -365,10 +369,9 @@ class View { } else { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); - $count = \OC_Helper::streamCopy($source, $target); + list($count, $result) = \OC_Helper::streamCopy($source, $target); list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $storage1->unlink($internalPath1); - $result = $count > 0; } if ($this->fakeRoot == Filesystem::getRoot()) { \OC_Hook::emit( @@ -448,7 +451,7 @@ class View { } else { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); - $result = \OC_Helper::streamCopy($source, $target); + list($count, $result) = \OC_Helper::streamCopy($source, $target); } if ($this->fakeRoot == Filesystem::getRoot()) { \OC_Hook::emit( @@ -601,6 +604,7 @@ class View { if ($path == null) { return false; } + $run = $this->runHooks($hooks, $path); list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); if ($run and $storage) { @@ -965,7 +969,7 @@ class View { */ public function getPath($id) { list($storage, $internalPath) = Cache\Cache::getById($id); - $mounts = Mount::findById($storage); + $mounts = Mount::findByStorageId($storage); foreach ($mounts as $mount) { /** * @var \OC\Files\Mount $mount diff --git a/lib/group.php b/lib/group.php index 6afe1440030..d1a830730b7 100644 --- a/lib/group.php +++ b/lib/group.php @@ -286,38 +286,45 @@ class OC_Group { } return $users; } - - /**
- * @brief get a list of all display names in a group
- * @returns array with display names (value) and user ids(key)
- */
- public static function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
- $displayNames=array();
- foreach(self::$_usedBackends as $backend) {
- $displayNames = array_merge($backend->displayNamesInGroup($gid, $search, $limit, $offset), $displayNames);
- }
- return $displayNames;
+ + /** + * @brief get a list of all display names in a group + * @returns array with display names (value) and user ids(key) + */ + public static function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { + $displayNames=array(); + foreach(self::$_usedBackends as $backend) { + if($backend->implementsActions(OC_GROUP_BACKEND_GET_DISPLAYNAME)) { + $displayNames = array_merge($backend->displayNamesInGroup($gid, $search, $limit, $offset), $displayNames); + } else { + $users = $backend->usersInGroup($gid, $search, $limit, $offset); + $names = array_combine($users, $users); + $displayNames = array_merge($names, $displayNames); + } + } + return $displayNames; } - - /**
- * @brief get a list of all display names in several groups
- * @param array $gids
- * @param string $search
- * @param int $limit
- * @param int $offset
- * @return array with display names (Key) user ids (value)
- */
- public static function displayNamesInGroups($gids, $search = '', $limit = -1, $offset = 0) {
- $displayNames = array();
- foreach ($gids as $gid) {
- // TODO Need to apply limits to groups as total
- $displayNames = array_merge( - array_diff( - self::displayNamesInGroup($gid, $search, $limit, $offset), - $displayNames - ), - $displayNames); - }
- return $displayNames;
+ + /** + * @brief get a list of all display names in several groups + * @param array $gids + * @param string $search + * @param int $limit + * @param int $offset + * @return array with display names (Key) user ids (value) + */ + public static function displayNamesInGroups($gids, $search = '', $limit = -1, $offset = 0) { + $displayNames = array(); + foreach ($gids as $gid) { + // TODO Need to apply limits to groups as total + $diff = array_diff( + self::displayNamesInGroup($gid, $search, $limit, $offset), + $displayNames + ); + if ($diff) { + $displayNames = array_merge($diff, $displayNames); + } + } + return $displayNames; } } diff --git a/lib/group/backend.php b/lib/group/backend.php index 4f6570c3be3..2e17b5d0b7f 100644 --- a/lib/group/backend.php +++ b/lib/group/backend.php @@ -33,6 +33,7 @@ define('OC_GROUP_BACKEND_CREATE_GROUP', 0x00000001); define('OC_GROUP_BACKEND_DELETE_GROUP', 0x00000010); define('OC_GROUP_BACKEND_ADD_TO_GROUP', 0x00000100); define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00001000); +define('OC_GROUP_BACKEND_GET_DISPLAYNAME', 0x00010000); /** * Abstract base class for user management @@ -43,6 +44,7 @@ abstract class OC_Group_Backend implements OC_Group_Interface { OC_GROUP_BACKEND_DELETE_GROUP => 'deleteGroup', OC_GROUP_BACKEND_ADD_TO_GROUP => 'addToGroup', OC_GROUP_BACKEND_REMOVE_FROM_GOUP => 'removeFromGroup', + OC_GROUP_BACKEND_GET_DISPLAYNAME => 'displayNamesInGroup', ); /** @@ -133,23 +135,23 @@ abstract class OC_Group_Backend implements OC_Group_Interface { public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { return array(); } - - /**
- * @brief get a list of all display names in a group
- * @param string $gid
- * @param string $search
- * @param int $limit
- * @param int $offset
- * @return array with display names (value) and user ids (key)
- */
- public function DisplayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
- $displayNames = '';
- $users = $this->usersInGroup($gid, $search, $limit, $offset);
- foreach ( $users as $user ) {
- $DisplayNames[$user] = $user;
- }
-
- return $DisplayNames;
+ + /** + * @brief get a list of all display names in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return array with display names (value) and user ids (key) + */ + public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { + $displayNames = array(); + $users = $this->usersInGroup($gid, $search, $limit, $offset); + foreach ($users as $user) { + $displayNames[$user] = $user; + } + + return $displayNames; } } diff --git a/lib/group/database.php b/lib/group/database.php index 8816dd8169c..d0974685ff6 100644 --- a/lib/group/database.php +++ b/lib/group/database.php @@ -210,30 +210,30 @@ class OC_Group_Database extends OC_Group_Backend { } return $users; } - - /**
- * @brief get a list of all display names in a group
- * @param string $gid
- * @param string $search
- * @param int $limit
- * @param int $offset
- * @return array with display names (value) and user ids (key)
- */
- public function DisplayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
- $displayNames = ''; + + /** + * @brief get a list of all display names in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return array with display names (value) and user ids (key) + */ + public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { + $displayNames = array(); $stmt = OC_DB::prepare('SELECT `*PREFIX*users`.`uid`, `*PREFIX*users`.`displayname`' .' FROM `*PREFIX*users`' .' INNER JOIN `*PREFIX*group_user` ON `*PREFIX*group_user`.`uid` = `*PREFIX*users`.`uid`' - .' WHERE `gid` = ? AND `*PREFIX*group_user.uid` LIKE ?', + .' WHERE `gid` = ? AND `*PREFIX*group_user`.`uid` LIKE ?', $limit, $offset); - $result = $stmt->execute(array($gid, $search.'%'));
- $users = array();
+ $result = $stmt->execute(array($gid, $search.'%')); + $users = array(); while ($row = $result->fetchRow()) { - $displayName = trim($row['displayname'], ' ');
- $displayNames[$row['uid']] = empty($displayName) ? $row['uid'] : $displayName;
- }
- return $displayNames;
+ $displayName = trim($row['displayname'], ' '); + $displayNames[$row['uid']] = empty($displayName) ? $row['uid'] : $displayName; + } + return $displayNames; } } diff --git a/lib/helper.php b/lib/helper.php index 0f810ffc0c2..41985ca57a7 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -513,11 +513,16 @@ class OC_Helper { if(!$source or !$target) { return false; } - $count=0; + $result = true; + $count = 0; while(!feof($source)) { - $count+=fwrite($target, fread($source, 8192)); + if ( ( $c = fwrite($target, fread($source, 8192)) ) === false) { + $result = false; + } else { + $count += $c; + } } - return $count; + return array($count, $result); } /** @@ -762,9 +767,13 @@ class OC_Helper { $maxUploadFilesize = min($upload_max_filesize, $post_max_size); $freeSpace = \OC\Files\Filesystem::free_space($dir); - $freeSpace = max($freeSpace, 0); + if($freeSpace !== \OC\Files\FREE_SPACE_UNKNOWN){ + $freeSpace = max($freeSpace, 0); - return min($maxUploadFilesize, $freeSpace); + return min($maxUploadFilesize, $freeSpace); + } else { + return $maxUploadFilesize; + } } /** diff --git a/lib/hook.php b/lib/hook.php index 554381251d6..8516cf0dcff 100644 --- a/lib/hook.php +++ b/lib/hook.php @@ -20,23 +20,23 @@ class OC_Hook{ * TODO: write example */ static public function connect( $signalclass, $signalname, $slotclass, $slotname ) { - // If we're trying to connect to an emitting class that isn't + // If we're trying to connect to an emitting class that isn't // yet registered, register it if( !array_key_exists( $signalclass, self::$registered )) { self::$registered[$signalclass] = array(); } - // If we're trying to connect to an emitting method that isn't + // If we're trying to connect to an emitting method that isn't // yet registered, register it with the emitting class - if( !array_key_exists( $signalname, self::$registered[$signalclass] )) { + if( !array_key_exists( $signalname, self::$registered[$signalclass] )) { self::$registered[$signalclass][$signalname] = array(); } - + // Connect the hook handler to the requested emitter self::$registered[$signalclass][$signalname][] = array( "class" => $slotclass, "name" => $slotname ); - + // No chance for failure ;-) return true; } @@ -53,19 +53,19 @@ class OC_Hook{ * TODO: write example */ static public function emit( $signalclass, $signalname, $params = array()) { - + // Return false if no hook handlers are listening to this // emitting class if( !array_key_exists( $signalclass, self::$registered )) { return false; } - + // Return false if no hook handlers are listening to this // emitting method if( !array_key_exists( $signalname, self::$registered[$signalclass] )) { return false; } - + // Call all slots foreach( self::$registered[$signalclass][$signalname] as $i ) { try { diff --git a/lib/image.php b/lib/image.php index 7b0cbefd657..c1b187608a6 100644 --- a/lib/image.php +++ b/lib/image.php @@ -35,7 +35,13 @@ class OC_Image { * @returns string The mime type if the it could be determined, otherwise an empty string. */ static public function getMimeTypeForFile($filepath) { - $imagetype = exif_imagetype($filepath); + // exif_imagetype throws "read error!" if file is less than 12 byte + if (filesize($filepath) > 11) { + $imagetype = exif_imagetype($filepath); + } + else { + $imagetype = false; + } return $imagetype ? image_type_to_mime_type($imagetype) : ''; } @@ -385,7 +391,8 @@ class OC_Image { * @returns An image resource or false on error */ public function loadFromFile($imagepath=false) { - if(!is_file($imagepath) || !file_exists($imagepath) || !is_readable($imagepath)) { + // exif_imagetype throws "read error!" if file is less than 12 byte + if(!is_file($imagepath) || !file_exists($imagepath) || filesize($imagepath) < 12 || !is_readable($imagepath)) { // Debug output disabled because this method is tried before loadFromBase64? OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: '.$imagepath, OC_Log::DEBUG); return false; @@ -702,6 +709,13 @@ class OC_Image { return false; } + // preserve transparency + if($this->imagetype == IMAGETYPE_GIF or $this->imagetype == IMAGETYPE_PNG) { + imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127)); + imagealphablending($process, false); + imagesavealpha($process, true); + } + imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); if ($process == false) { OC_Log::write('core', __METHOD__.'(): Error resampling process image '.$width.'x'.$height, OC_Log::ERROR); @@ -751,6 +765,14 @@ class OC_Image { imagedestroy($process); return false; } + + // preserve transparency + if($this->imagetype == IMAGETYPE_GIF or $this->imagetype == IMAGETYPE_PNG) { + imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127)); + imagealphablending($process, false); + imagesavealpha($process, true); + } + imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height); if ($process == false) { OC_Log::write('core', diff --git a/lib/l10n/bg_BG.php b/lib/l10n/bg_BG.php index d80e03608a2..d32e2aadfc5 100644 --- a/lib/l10n/bg_BG.php +++ b/lib/l10n/bg_BG.php @@ -21,6 +21,18 @@ "Specify a data folder." => "Укажете папка за данни", "%s enter the database username." => "%s въведете потребителско име за базата с данни.", "%s enter the database name." => "%s въведете име на базата с данни.", +"%s you may not use dots in the database name" => "%s, не можете да ползвате точки в името на базата от данни", +"PostgreSQL username and/or password not valid" => "Невалидно PostgreSQL потребителско име и/или парола", +"You need to enter either an existing account or the administrator." => "Необходимо е да влезете в всъществуващ акаунт или като администратора", +"Oracle username and/or password not valid" => "Невалидно Oracle потребителско име и/или парола", +"MySQL username and/or password not valid" => "Невалидно MySQL потребителско име и/или парола", +"DB Error: \"%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.", +"MS SQL username and/or password not valid: %s" => "Невалидно MS SQL потребителско име и/или парола: %s", +"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/ca.php b/lib/l10n/ca.php index 3e3938aa6cb..108bb5c09be 100644 --- a/lib/l10n/ca.php +++ b/lib/l10n/ca.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "L'usuari MySQL '%s'@'%%' ja existeix", "Drop this user from MySQL." => "Elimina aquest usuari de MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "L'ordre en conflicte és: \"%s\", nom: %s, contrasenya: %s", +"MS SQL username and/or password not valid: %s" => "Nom d'usuari i/o contrasenya MS SQL no vàlids: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "El servidor web no està configurat correctament per permetre la sincronització de fitxers perquè la interfície WebDAV sembla no funcionar correctament.", "Please double check the <a href='%s'>installation guides</a>." => "Comproveu les <a href='%s'>guies d'instal·lació</a>.", "seconds ago" => "segons enrere", diff --git a/lib/l10n/cs_CZ.php b/lib/l10n/cs_CZ.php index d99f259cb0f..d9ec3d82cf7 100644 --- a/lib/l10n/cs_CZ.php +++ b/lib/l10n/cs_CZ.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "Uživatel '%s'@'%%' již v MySQL existuje", "Drop this user from MySQL." => "Zahodit uživatele z MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "Podezřelý příkaz byl: \"%s\", jméno: %s, heslo: %s", +"MS SQL username and/or password not valid: %s" => "Uživatelské jméno, či heslo MSSQL není platné: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Váš webový server není správně nastaven pro umožnění synchronizace, protože rozhraní WebDAV je rozbité.", "Please double check the <a href='%s'>installation guides</a>." => "Zkonzultujte, prosím, <a href='%s'>průvodce instalací</a>.", "seconds ago" => "před vteřinami", diff --git a/lib/l10n/da.php b/lib/l10n/da.php index e61fba30ff3..38ccbbe8e21 100644 --- a/lib/l10n/da.php +++ b/lib/l10n/da.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "MySQL brugeren '%s'@'%%' eksisterer allerede.", "Drop this user from MySQL." => "Slet denne bruger fra MySQL", "Offending command was: \"%s\", name: %s, password: %s" => "Fejlende kommando var: \"%s\", navn: %s, password: %s", +"MS SQL username and/or password not valid: %s" => "MS SQL brugernavn og/eller adgangskode ikke er gyldigt: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Din webserver er endnu ikke sat op til at tillade fil synkronisering fordi WebDAV grænsefladen virker ødelagt.", "Please double check the <a href='%s'>installation guides</a>." => "Dobbelttjek venligst <a href='%s'>installations vejledningerne</a>.", "seconds ago" => "sekunder siden", diff --git a/lib/l10n/de.php b/lib/l10n/de.php index f65ee5cfa3b..3c2069d4637 100644 --- a/lib/l10n/de.php +++ b/lib/l10n/de.php @@ -9,7 +9,7 @@ "Files need to be downloaded one by one." => "Die Dateien müssen einzeln heruntergeladen werden.", "Back to Files" => "Zurück zu \"Dateien\"", "Selected files too large to generate zip file." => "Die gewählten Dateien sind zu groß, um eine ZIP-Datei zu erstellen.", -"couldn't be determined" => "Konnte nicht festgestellt werden", +"couldn't be determined" => "konnte nicht festgestellt werden", "Application is not enabled" => "Die Anwendung ist nicht aktiviert", "Authentication error" => "Authentifizierungs-Fehler", "Token expired. Please reload page." => "Token abgelaufen. Bitte lade die Seite neu.", @@ -18,13 +18,13 @@ "Images" => "Bilder", "Set an admin username." => "Setze Administrator Benutzername.", "Set an admin password." => "Setze Administrator Passwort", -"Specify a data folder." => "Datei-Verzeichnis angeben", +"Specify a data folder." => "Datei-Verzeichnis angeben.", "%s enter the database username." => "%s gib den Datenbank-Benutzernamen an.", "%s enter the database name." => "%s gib den Datenbank-Namen an.", "%s you may not use dots in the database name" => "%s Der Datenbank-Name darf keine Punkte enthalten", "%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." => "Sie müssen entweder ein existierendes Benutzerkonto oder das Administratoren-Konto angeben.", +"You need to enter either an existing account or the administrator." => "Du musst entweder ein existierendes Benutzerkonto oder das Administratoren-Konto angeben.", "Oracle username and/or password not valid" => "Oracle Benutzername und/oder Passwort ungültig", "MySQL username and/or password not valid" => "MySQL Benutzername und/oder Passwort ungültig", "DB Error: \"%s\"" => "DB Fehler: \"%s\"", @@ -32,10 +32,11 @@ "MySQL user '%s'@'localhost' exists already." => "MySQL Benutzer '%s'@'localhost' existiert bereits.", "Drop this user from MySQL" => "Lösche diesen Benutzer von MySQL", "MySQL user '%s'@'%%' already exists" => "MySQL Benutzer '%s'@'%%' existiert bereits", -"Drop this user from MySQL." => "Lösche diesen Benutzer von MySQL.", +"Drop this user from MySQL." => "Lösche diesen Benutzer aus MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "Fehlerhafter Befehl war: \"%s\", Name: %s, Passwort: %s", +"MS SQL username and/or password not valid: %s" => "MS SQL Benutzername und/oder Password ungültig: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Dein Web-Server ist noch nicht für Datei-Synchronisation bereit, weil die WebDAV-Schnittstelle vermutlich defekt ist.", -"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfen Sie die <a href='%s'>Instalationsanleitungen</a>.", +"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfe die <a href='%s'>Instalationsanleitungen</a>.", "seconds ago" => "Gerade eben", "1 minute ago" => "Vor einer Minute", "%d minutes ago" => "Vor %d Minuten", diff --git a/lib/l10n/de_DE.php b/lib/l10n/de_DE.php index 1f63fdd87b0..9978cdf8b31 100644 --- a/lib/l10n/de_DE.php +++ b/lib/l10n/de_DE.php @@ -30,10 +30,11 @@ "DB Error: \"%s\"" => "DB Fehler: \"%s\"", "Offending command was: \"%s\"" => "Fehlerhafter Befehl war: \"%s\"", "MySQL user '%s'@'localhost' exists already." => "MySQL Benutzer '%s'@'localhost' existiert bereits.", -"Drop this user from MySQL" => "Lösche diesen Benutzer von MySQL", +"Drop this user from MySQL" => "Lösche diesen Benutzer aus MySQL", "MySQL user '%s'@'%%' already exists" => "MySQL Benutzer '%s'@'%%' existiert bereits", -"Drop this user from MySQL." => "Lösche diesen Benutzer von MySQL.", +"Drop this user from MySQL." => "Lösche diesen Benutzer aus MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "Fehlerhafter Befehl war: \"%s\", Name: %s, Passwort: %s", +"MS SQL username and/or password not valid: %s" => "MS SQL Benutzername und/oder Passwort ungültig: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Ihr Web-Server ist noch nicht für Datei-Synchronisation bereit, weil die WebDAV-Schnittstelle vermutlich defekt ist.", "Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfen Sie die <a href='%s'>Instalationsanleitungen</a>.", "seconds ago" => "Gerade eben", diff --git a/lib/l10n/el.php b/lib/l10n/el.php index cf0be24b432..c17a33dfee1 100644 --- a/lib/l10n/el.php +++ b/lib/l10n/el.php @@ -16,6 +16,23 @@ "Files" => "Αρχεία", "Text" => "Κείμενο", "Images" => "Εικόνες", +"Set an admin username." => "Εισάγετε όνομα χρήστη διαχειριστή.", +"Set an admin password." => "Εισάγετε συνθηματικό διαχειριστή.", +"Specify a data folder." => "Καθορίστε τον φάκελο δεδομένων.", +"%s enter the database username." => "%s εισάγετε το όνομα χρήστη της βάσης δεδομένων.", +"%s enter the database name." => "%s εισάγετε το όνομα της βάσης δεδομένων.", +"%s you may not use dots in the database name" => "%s μάλλον δεν χρησιμοποιείτε τελείες στο όνομα της βάσης δεδομένων", +"PostgreSQL username and/or password not valid" => "Μη έγκυρος χρήστης και/ή συνθηματικό της PostgreSQL", +"You need to enter either an existing account or the administrator." => "Χρειάζεται να εισάγετε είτε έναν υπάρχον λογαριασμό ή του διαχειριστή.", +"Oracle username and/or password not valid" => "Μη έγκυρος χρήστης και/ή συνθηματικό της Oracle", +"MySQL username and/or password not valid" => "Μη έγκυρος χρήστης και/ή συνθηματικό της MySQL", +"DB Error: \"%s\"" => "Σφάλμα Βάσης Δεδομένων: \"%s\"", +"MySQL user '%s'@'localhost' exists already." => "Υπάρχει ήδη ο χρήστης '%s'@'localhost' της MySQL.", +"Drop this user from MySQL" => "Απόρριψη αυτού του χρήστη από την MySQL", +"MySQL user '%s'@'%%' already exists" => "Ο χρήστης '%s'@'%%' της MySQL υπάρχει ήδη", +"Drop this user from MySQL." => "Απόρριψη αυτού του χρήστη από την MySQL", +"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 λεπτά πριν", @@ -28,7 +45,7 @@ "%d months ago" => "%d μήνες πριν", "last year" => "τον προηγούμενο χρόνο", "years ago" => "χρόνια πριν", -"%s is available. Get <a href=\"%s\">more information</a>" => "%s είναι διαθέσιμα. Δείτε <a href=\"%s\">περισσότερες πληροφορίες</a>", +"%s is available. Get <a href=\"%s\">more information</a>" => "%s είναι διαθέσιμο. Δείτε <a href=\"%s\">περισσότερες πληροφορίες</a>", "up to date" => "ενημερωμένο", "updates check is disabled" => "ο έλεγχος ενημερώσεων είναι απενεργοποιημένος", "Could not find category \"%s\"" => "Αδυναμία εύρεσης κατηγορίας \"%s\"" diff --git a/lib/l10n/es.php b/lib/l10n/es.php index f3b03b56652..37b15a375c4 100644 --- a/lib/l10n/es.php +++ b/lib/l10n/es.php @@ -16,6 +16,25 @@ "Files" => "Archivos", "Text" => "Texto", "Images" => "Imágenes", +"Set an admin username." => "Configurar un nombre de usuario del administrador", +"Set an admin password." => "Configurar la contraseña del administrador.", +"Specify a data folder." => "Especificar la carpeta de datos.", +"%s enter the database username." => "%s ingresar el usuario de la base de datos.", +"%s enter the database name." => "%s ingresar el nombre de la base de datos", +"%s you may not use dots in the database name" => "%s no se puede utilizar puntos en el nombre de la base de datos", +"%s set the database host." => "%s ingresar el host de la base de datos.", +"PostgreSQL username and/or password not valid" => "Usuario y/o contraseña de PostgreSQL no válidos", +"You need to enter either an existing account or the administrator." => "Tiene que ingresar una cuenta existente o la del administrador.", +"Oracle username and/or password not valid" => "Usuario y/o contraseña de Oracle no válidos", +"MySQL username and/or password not valid" => "Usuario y/o contraseña de MySQL no válidos", +"DB Error: \"%s\"" => "Error BD: \"%s\"", +"Offending command was: \"%s\"" => "Comando infractor: \"%s\"", +"MySQL user '%s'@'localhost' exists already." => "Usuario MySQL '%s'@'localhost' ya existe.", +"Drop this user from MySQL" => "Eliminar este usuario de MySQL", +"MySQL user '%s'@'%%' already exists" => "Usuario MySQL '%s'@'%%' ya existe", +"Drop this user from MySQL." => "Eliminar este usuario de MySQL.", +"Offending command was: \"%s\", name: %s, password: %s" => "Comando infractor: \"%s\", nombre: %s, contraseña: %s", +"MS SQL username and/or password not valid: %s" => "Usuario y/o contraseña de MS SQL no válidos: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Su servidor web aún no está configurado adecuadamente para permitir sincronización de archivos ya que la interfaz WebDAV parece no estar funcionando.", "Please double check the <a href='%s'>installation guides</a>." => "Por favor, vuelva a comprobar las <a href='%s'>guías de instalación</a>.", "seconds ago" => "hace segundos", diff --git a/lib/l10n/es_AR.php b/lib/l10n/es_AR.php index a2391a45b23..ff3d47285fc 100644 --- a/lib/l10n/es_AR.php +++ b/lib/l10n/es_AR.php @@ -25,12 +25,16 @@ "%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 username and/or password not valid" => "El nombre de usuario y contraseña no son válidos", "MySQL username and/or password not valid" => "Usuario y/o contraseña MySQL no válido", "DB Error: \"%s\"" => "Error DB: \"%s\"", +"Offending command was: \"%s\"" => "El comando no comprendido es: \"%s\"", "MySQL user '%s'@'localhost' exists already." => "Usuario MySQL '%s'@'localhost' ya existente", "Drop this user from MySQL" => "Borrar este usuario de MySQL", "MySQL user '%s'@'%%' already exists" => "Usuario MySQL '%s'@'%%' ya existente", "Drop this user from MySQL." => "Borrar este usuario de MySQL", +"Offending command was: \"%s\", name: %s, password: %s" => "El comando no comprendido es: \"%s\", nombre: \"%s\", contraseña: \"%s\"", +"MS SQL username and/or password not valid: %s" => "Nombre de usuario y contraseña de MS SQL no son válidas: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Tu servidor web no está configurado todavía para permitir sincronización de archivos porque la interfaz WebDAV parece no funcionar.", "Please double check the <a href='%s'>installation guides</a>." => "Por favor, comprobá nuevamente la <a href='%s'>guía de instalación</a>.", "seconds ago" => "hace unos segundos", diff --git a/lib/l10n/eu.php b/lib/l10n/eu.php index 97eb6511198..36eb397e425 100644 --- a/lib/l10n/eu.php +++ b/lib/l10n/eu.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "MySQL '%s'@'%%' erabiltzailea dagoeneko existitzen da", "Drop this user from MySQL." => "Ezabatu erabiltzaile hau MySQLtik.", "Offending command was: \"%s\", name: %s, password: %s" => "Errorea komando honek sortu du: \"%s\", izena: %s, pasahitza: %s", +"MS SQL username and/or password not valid: %s" => "MS SQL erabiltzaile izena edota pasahitza ez dira egokiak: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Zure web zerbitzaria ez dago oraindik ongi konfiguratuta fitxategien sinkronizazioa egiteko, WebDAV interfazea ongi ez dagoela dirudi.", "Please double check the <a href='%s'>installation guides</a>." => "Mesedez begiratu <a href='%s'>instalazio gidak</a>.", "seconds ago" => "orain dela segundu batzuk", diff --git a/lib/l10n/fi_FI.php b/lib/l10n/fi_FI.php index c3ff3e9a2bf..89a584d389d 100644 --- a/lib/l10n/fi_FI.php +++ b/lib/l10n/fi_FI.php @@ -19,12 +19,16 @@ "Set an admin username." => "Aseta ylläpitäjän käyttäjätunnus.", "Set an admin password." => "Aseta ylläpitäjän salasana.", "Specify a data folder." => "Määritä datakansio.", +"%s enter the database username." => "%s anna tietokannan käyttäjätunnus.", +"%s enter the database name." => "%s anna tietokannan nimi.", +"%s you may not use dots in the database name" => "%s et voi käyttää pisteitä tietokannan nimessä", "PostgreSQL username and/or password not valid" => "PostgreSQL:n käyttäjätunnus ja/tai salasana on väärin", "Oracle username and/or password not valid" => "Oraclen käyttäjätunnus ja/tai salasana on väärin", "MySQL username and/or password not valid" => "MySQL:n käyttäjätunnus ja/tai salasana on väärin", "DB Error: \"%s\"" => "Tietokantavirhe: \"%s\"", "MySQL user '%s'@'localhost' exists already." => "MySQL-käyttäjä '%s'@'localhost' on jo olemassa.", "MySQL user '%s'@'%%' already exists" => "MySQL-käyttäjä '%s'@'%%' on jo olemassa", +"MS SQL username and/or password not valid: %s" => "MS SQL -käyttäjätunnus ja/tai -salasana on väärin: %s", "Please double check the <a href='%s'>installation guides</a>." => "Lue tarkasti <a href='%s'>asennusohjeet</a>.", "seconds ago" => "sekuntia sitten", "1 minute ago" => "1 minuutti sitten", diff --git a/lib/l10n/fr.php b/lib/l10n/fr.php index fc44f976084..9448502df6a 100644 --- a/lib/l10n/fr.php +++ b/lib/l10n/fr.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "L'utilisateur MySQL '%s'@'%%' existe déjà", "Drop this user from MySQL." => "Retirer cet utilisateur de la base MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "La requête en cause est : \"%s\", nom : %s, mot de passe : %s", +"MS SQL username and/or password not valid: %s" => "Le nom d'utilisateur et/ou le mot de passe de la base MS SQL est invalide : %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Votre serveur web, n'est pas correctement configuré pour permettre la synchronisation des fichiers, car l'interface WebDav ne fonctionne pas comme il faut.", "Please double check the <a href='%s'>installation guides</a>." => "Veuillez vous référer au <a href='%s'>guide d'installation</a>.", "seconds ago" => "à l'instant", diff --git a/lib/l10n/gl.php b/lib/l10n/gl.php index c49e8134af1..a11724fef43 100644 --- a/lib/l10n/gl.php +++ b/lib/l10n/gl.php @@ -6,7 +6,7 @@ "Apps" => "Aplicativos", "Admin" => "Administración", "ZIP download is turned off." => "As descargas ZIP están desactivadas.", -"Files need to be downloaded one by one." => "Os ficheiros necesitan seren descargados de un en un.", +"Files need to be downloaded one by one." => "Os ficheiros necesitan seren descargados dun en un.", "Back to Files" => "Volver aos ficheiros", "Selected files too large to generate zip file." => "Os ficheiros seleccionados son demasiado grandes como para xerar un ficheiro zip.", "couldn't be determined" => "non foi posíbel determinalo", @@ -16,6 +16,25 @@ "Files" => "Ficheiros", "Text" => "Texto", "Images" => "Imaxes", +"Set an admin username." => "Estabeleza un nome de usuario administrador", +"Set an admin password." => "Estabeleza un contrasinal de administrador", +"Specify a data folder." => "Especifique un cartafol de datos.", +"%s enter the database username." => "%s introduza o nome de usuario da base de datos", +"%s enter the database name." => "%s introduza o nome da base de datos", +"%s you may not use dots in the database name" => "%s non se poden empregar puntos na base de datos", +"%s set the database host." => "%s estabeleza o servidor da base de datos", +"PostgreSQL username and/or password not valid" => "Nome de usuario e/ou contrasinal de PostgreSQL incorrecto", +"You need to enter either an existing account or the administrator." => "Deberá introducir unha conta existente ou o administrador.", +"Oracle username and/or password not valid" => "Nome de usuario e/ou contrasinal de Oracle incorrecto", +"MySQL username and/or password not valid" => "Nome de usuario e/ou contrasinal de MySQL incorrecto", +"DB Error: \"%s\"" => "Produciuse un erro na base de datos: «%s»", +"Offending command was: \"%s\"" => "A orde ofensiva foi: «%s»", +"MySQL user '%s'@'localhost' exists already." => "O usuario MySQL '%s'@'localhost' xa existe.", +"Drop this user from MySQL" => "Omitir este usuario de MySQL", +"MySQL user '%s'@'%%' already exists" => "O usuario MySQL «%s»@«%%» xa existe.", +"Drop this user from MySQL." => "Omitir este usuario de MySQL.", +"Offending command was: \"%s\", name: %s, password: %s" => "A orde ofensiva foi: «%s», nome: %s, contrasinal: %s", +"MS SQL username and/or password not valid: %s" => "Nome de usuario e/ou contrasinal de MS SQL incorrecto: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "O seu servidor web non está aínda configurado adecuadamente para permitir a sincronización de ficheiros xa que semella que a interface WebDAV non está a funcionar.", "Please double check the <a href='%s'>installation guides</a>." => "Volva comprobar as <a href='%s'>guías de instalación</a>", "seconds ago" => "segundos atrás", @@ -31,7 +50,7 @@ "last year" => "último ano", "years ago" => "anos atrás", "%s is available. Get <a href=\"%s\">more information</a>" => "%s está dispoñíbel. Obtéña <a href=\"%s\">máis información</a>", -"up to date" => "ao día", +"up to date" => "actualizado", "updates check is disabled" => "a comprobación de actualizacións está desactivada", "Could not find category \"%s\"" => "Non foi posíbel atopar a categoría «%s»" ); diff --git a/lib/l10n/hu_HU.php b/lib/l10n/hu_HU.php index d1aeb621e23..537066c6fea 100644 --- a/lib/l10n/hu_HU.php +++ b/lib/l10n/hu_HU.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "A '%s'@'%%' MySQL felhasználó már létezik", "Drop this user from MySQL." => "Törölje ezt a felhasználót a MySQL-ből.", "Offending command was: \"%s\", name: %s, password: %s" => "A hibát okozó parancs ez volt: \"%s\", login név: %s, jelszó: %s", +"MS SQL username and/or password not valid: %s" => "Az MS SQL felhasználónév és/vagy jelszó érvénytelen: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Az Ön webkiszolgálója nincs megfelelően beállítva az állományok szinkronizálásához, mert a WebDAV-elérés úgy tűnik, nem működik.", "Please double check the <a href='%s'>installation guides</a>." => "Kérjük tüzetesen tanulmányozza át a <a href='%s'>telepítési útmutatót</a>.", "seconds ago" => "másodperce", diff --git a/lib/l10n/it.php b/lib/l10n/it.php index fa4bac8ec46..297f1efde05 100644 --- a/lib/l10n/it.php +++ b/lib/l10n/it.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "L'utente MySQL '%s'@'%%' esiste già", "Drop this user from MySQL." => "Elimina questo utente da MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "Il comando non consentito era: \"%s\", nome: %s, password: %s", +"MS SQL username and/or password not valid: %s" => "Nome utente e/o password MS SQL non validi: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Il tuo server web non è configurato correttamente per consentire la sincronizzazione dei file poiché l'interfaccia WebDAV sembra essere danneggiata.", "Please double check the <a href='%s'>installation guides</a>." => "Leggi attentamente le <a href='%s'>guide d'installazione</a>.", "seconds ago" => "secondi fa", diff --git a/lib/l10n/ja_JP.php b/lib/l10n/ja_JP.php index 51b5b40940a..529eec3ac52 100644 --- a/lib/l10n/ja_JP.php +++ b/lib/l10n/ja_JP.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "MySQLのユーザ '%s'@'%%' はすでに存在します。", "Drop this user from MySQL." => "MySQLからこのユーザを削除する。", "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." => "WebDAVインタフェースが動作していないと考えられるため、あなたのWEBサーバはまだファイルの同期を許可するように適切な設定がされていません。", "Please double check the <a href='%s'>installation guides</a>." => "<a href='%s'>インストールガイド</a>をよく確認してください。", "seconds ago" => "秒前", diff --git a/lib/l10n/ka.php b/lib/l10n/ka.php new file mode 100644 index 00000000000..e5a3e659668 --- /dev/null +++ b/lib/l10n/ka.php @@ -0,0 +1,15 @@ +<?php $TRANSLATIONS = array( +"Help" => "შველა", +"Personal" => "პერსონა", +"Users" => "მომხმარებლები", +"Admin" => "ადმინისტრატორი", +"ZIP download is turned off." => "ZIP გადმოწერა გამორთულია", +"Files" => "ფაილები", +"seconds ago" => "წამის წინ", +"1 minute ago" => "1 წუთის წინ", +"%d minutes ago" => "%d წუთის წინ", +"1 hour ago" => "1 საათის წინ", +"today" => "დღეს", +"yesterday" => "გუშინ", +"%d days ago" => "%d დღის წინ" +); diff --git a/lib/l10n/lv.php b/lib/l10n/lv.php index 5ec9ddd9693..c73d306ca0a 100644 --- a/lib/l10n/lv.php +++ b/lib/l10n/lv.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "MySQL lietotājs '%s'@'%%' jau eksistē", "Drop this user from MySQL." => "Izmest šo lietotāju no MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "Vainīgā komanda bija \"%s\", vārds: %s, parole: %s", +"MS SQL username and/or password not valid: %s" => "Nav derīga MySQL parole un/vai lietotājvārds — %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Jūsu serveris vēl nav pareizi iestatīts, lai ļautu sinhronizēt datnes, jo izskatās, ka WebDAV saskarne ir salauzta.", "Please double check the <a href='%s'>installation guides</a>." => "Lūdzu, vēlreiz pārbaudiet <a href='%s'>instalēšanas palīdzību</a>.", "seconds ago" => "sekundes atpakaļ", diff --git a/lib/l10n/my_MM.php b/lib/l10n/my_MM.php new file mode 100644 index 00000000000..d725a06a3a9 --- /dev/null +++ b/lib/l10n/my_MM.php @@ -0,0 +1,31 @@ +<?php $TRANSLATIONS = array( +"Help" => "အကူအညီ", +"Users" => "သုံးစွဲသူ", +"Apps" => "Apps", +"Admin" => "အက်ဒမင်", +"ZIP download is turned off." => "ZIP ဒေါင်းလုတ်ကိုပိတ်ထားသည်", +"Files need to be downloaded one by one." => "ဖိုင်များသည် တစ်ခုပြီး တစ်ခုဒေါင်းလုတ်ချရန်လိုအပ်သည်", +"Back to Files" => "ဖိုင်သို့ပြန်သွားမည်", +"Selected files too large to generate zip file." => "zip ဖိုင်အဖြစ်ပြုလုပ်ရန် ရွေးချယ်ထားသောဖိုင်များသည် အရမ်းကြီးလွန်းသည်", +"couldn't be determined" => "မဆုံးဖြတ်နိုင်ပါ။", +"Authentication error" => "ခွင့်ပြုချက်မအောင်မြင်", +"Files" => "ဖိုင်များ", +"Text" => "စာသား", +"Images" => "ပုံရိပ်များ", +"seconds ago" => "စက္ကန့်အနည်းငယ်က", +"1 minute ago" => "၁ မိနစ်အရင်က", +"%d minutes ago" => "%d မိနစ်အရင်က", +"1 hour ago" => "၁ နာရီ အရင်က", +"%d hours ago" => "%d နာရီအရင်က", +"today" => "ယနေ့", +"yesterday" => "မနေ့က", +"%d days ago" => "%d ရက် အရင်က", +"last month" => "ပြီးခဲ့သောလ", +"%d months ago" => "%d လအရင်က", +"last year" => "မနှစ်က", +"years ago" => "နှစ် အရင်က", +"%s is available. Get <a href=\"%s\">more information</a>" => "%s ကိုရရှိနိုင်ပါပြီ။ <a href=\"%s\">နောက်ထပ်အချက်အလက်များ</a>ရယူပါ။", +"up to date" => "နောက်ဆုံးပေါ်", +"updates check is disabled" => "နောက်ဆုံးပေါ်စစ်ဆေးခြင်းကိုပိတ်ထားသည်", +"Could not find category \"%s\"" => "\"%s\"ခေါင်းစဉ်ကို ရှာမတွေ့ပါ" +); diff --git a/lib/l10n/nl.php b/lib/l10n/nl.php index 4a357889fdc..e26a663e9cc 100644 --- a/lib/l10n/nl.php +++ b/lib/l10n/nl.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "MySQL gebruiker '%s'@'%%' bestaat al", "Drop this user from MySQL." => "Verwijder deze gebruiker uit MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "Onjuiste commando was: \"%s\", naam: %s, wachtwoord: %s", +"MS SQL username and/or password not valid: %s" => "MS SQL gebruikersnaam en/of wachtwoord niet geldig: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Uw webserver is nog niet goed ingesteld voor bestandssynchronisatie omdat de WebDAV interface verbroken lijkt.", "Please double check the <a href='%s'>installation guides</a>." => "Conntroleer de <a href='%s'>installatie handleiding</a> goed.", "seconds ago" => "seconden geleden", diff --git a/lib/l10n/pl.php b/lib/l10n/pl.php index 6ec35445bc2..9a1a5e836c9 100644 --- a/lib/l10n/pl.php +++ b/lib/l10n/pl.php @@ -16,6 +16,27 @@ "Files" => "Pliki", "Text" => "Połączenie tekstowe", "Images" => "Obrazy", +"Set an admin username." => "Ustaw nazwę administratora.", +"Set an admin password." => "Ustaw hasło administratora.", +"Specify a data folder." => "Określ folder danych.", +"%s enter the database username." => "%s wpisz nazwę użytkownika do bazy", +"%s enter the database name." => "%s wpisz nazwę bazy.", +"%s you may not use dots in the database name" => "%s nie można używać kropki w nazwie bazy danych", +"%s set the database host." => "%s ustaw hosta bazy danych.", +"PostgreSQL username and/or password not valid" => "PostgreSQL: Nazwa użytkownika i/lub hasło jest niepoprawne", +"You need to enter either an existing account or the administrator." => "Należy wprowadzić istniejące konto użytkownika lub administratora.", +"Oracle username and/or password not valid" => "Oracle: Nazwa użytkownika i/lub hasło jest niepoprawne", +"MySQL username and/or password not valid" => "MySQL: Nazwa użytkownika i/lub hasło jest niepoprawne", +"DB Error: \"%s\"" => "Błąd DB: \"%s\"", +"Offending command was: \"%s\"" => "Niepoprawna komenda: \"%s\"", +"MySQL user '%s'@'localhost' exists already." => "Użytkownik MySQL '%s'@'localhost' już istnieje", +"Drop this user from MySQL" => "Usuń tego użytkownika z MySQL", +"MySQL user '%s'@'%%' already exists" => "Użytkownik MySQL '%s'@'%%t' już istnieje", +"Drop this user from MySQL." => "Usuń tego użytkownika z MySQL.", +"Offending command was: \"%s\", name: %s, password: %s" => "Niepoprawne polecania: \"%s\", nazwa: %s, hasło: %s", +"MS SQL username and/or password not valid: %s" => "Nazwa i/lub hasło serwera MS SQL jest niepoprawne: %s.", +"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Serwer www nie jest jeszcze poprawnie ustawiony, aby umożliwić synchronizację plików, ponieważ interfejs WebDAV wydaje się być uszkodzony. Sprawdź ustawienia serwera.", +"Please double check the <a href='%s'>installation guides</a>." => "Proszę sprawdź ponownie <a href='%s'>przewodnik instalacji</a>.", "seconds ago" => "sekund temu", "1 minute ago" => "1 minutę temu", "%d minutes ago" => "%d minut temu", diff --git a/lib/l10n/pt_BR.php b/lib/l10n/pt_BR.php index 25645b1dcd9..d4f410d8885 100644 --- a/lib/l10n/pt_BR.php +++ b/lib/l10n/pt_BR.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "Usuário MySQL '%s'@'%%' já existe", "Drop this user from MySQL." => "Derrube este usuário do MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "Comando ofensivo era: \"%s\", nome: %s, senha: %s", +"MS SQL username and/or password not valid: %s" => "Nome de usuário e/ou senha MS SQL inválido(s): %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Seu servidor web não está configurado corretamente para permitir sincronização de arquivos porque a interface WebDAV parece estar quebrada.", "Please double check the <a href='%s'>installation guides</a>." => "Por favor, confira os <a href='%s'>guias de instalação</a>.", "seconds ago" => "segundos atrás", diff --git a/lib/l10n/pt_PT.php b/lib/l10n/pt_PT.php index a3585f914da..2c813f5b07c 100644 --- a/lib/l10n/pt_PT.php +++ b/lib/l10n/pt_PT.php @@ -23,8 +23,18 @@ "%s enter the database name." => "%s introduza o nome da base de dados", "%s you may not use dots in the database name" => "%s não é permitido utilizar pontos (.) no nome da base de dados", "%s set the database host." => "%s defina o servidor da base de dados (geralmente localhost)", -"PostgreSQL username and/or password not valid" => "Nome de utilizador/passwor do PostgreSQL inválido", +"PostgreSQL username and/or password not valid" => "Nome de utilizador/password do PostgreSQL inválido", "You need to enter either an existing account or the administrator." => "Precisa de introduzir uma conta existente ou de administrador", +"Oracle username and/or password not valid" => "Nome de utilizador/password do Oracle inválida", +"MySQL username and/or password not valid" => "Nome de utilizador/password do MySQL inválida", +"DB Error: \"%s\"" => "Erro na BD: \"%s\"", +"Offending command was: \"%s\"" => "O comando gerador de erro foi: \"%s\"", +"MySQL user '%s'@'localhost' exists already." => "O utilizador '%s'@'localhost' do MySQL já existe.", +"Drop this user from MySQL" => "Eliminar este utilizador do MySQL", +"MySQL user '%s'@'%%' already exists" => "O utilizador '%s'@'%%' do MySQL já existe", +"Drop this user from MySQL." => "Eliminar este utilizador do MySQL", +"Offending command was: \"%s\", name: %s, password: %s" => "O comando gerador de erro foi: \"%s\", nome: %s, password: %s", +"MS SQL username and/or password not valid: %s" => "Nome de utilizador/password do MySQL é inválido: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "O seu servidor web não está configurado correctamente para autorizar sincronização de ficheiros, pois o interface WebDAV parece estar com problemas.", "Please double check the <a href='%s'>installation guides</a>." => "Por favor verifique <a href='%s'>installation guides</a>.", "seconds ago" => "há alguns segundos", diff --git a/lib/l10n/ru.php b/lib/l10n/ru.php index c0ffcd68064..25a88d5efc2 100644 --- a/lib/l10n/ru.php +++ b/lib/l10n/ru.php @@ -19,15 +19,24 @@ "Set an admin username." => "Установить имя пользователя для admin.", "Set an admin password." => "становит пароль для admin.", "Specify a data folder." => "Указать папку данных.", +"%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 username and/or password not valid" => "Неверное имя пользователя и/или пароль 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.", +"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." => "Ваш веб сервер до сих пор не настроен правильно для возможности синхронизации файлов, похоже что проблема в неисправности интерфейса 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/sk_SK.php b/lib/l10n/sk_SK.php index 97a4999407f..8c9ce61622c 100644 --- a/lib/l10n/sk_SK.php +++ b/lib/l10n/sk_SK.php @@ -34,6 +34,7 @@ "MySQL user '%s'@'%%' already exists" => "Používateľ '%s'@'%%' už v MySQL existuje", "Drop this user from MySQL." => "Zahodiť používateľa z MySQL.", "Offending command was: \"%s\", name: %s, password: %s" => "Podozrivý príkaz bol: \"%s\", meno: %s, heslo: %s", +"MS SQL username and/or password not valid: %s" => "Používateľské meno, alebo heslo MS SQL nie je platné: %s", "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Váš webový server nie je správne nastavený na synchronizáciu, pretože rozhranie WebDAV je poškodené.", "Please double check the <a href='%s'>installation guides</a>." => "Prosím skontrolujte <a href='%s'>inštalačnú príručku</a>.", "seconds ago" => "pred sekundami", diff --git a/lib/l10n/uk.php b/lib/l10n/uk.php index 053644ddede..68f7151d15e 100644 --- a/lib/l10n/uk.php +++ b/lib/l10n/uk.php @@ -16,6 +16,27 @@ "Files" => "Файли", "Text" => "Текст", "Images" => "Зображення", +"Set an admin username." => "Встановіть ім'я адміністратора.", +"Set an admin password." => "Встановіть пароль адміністратора.", +"Specify a data folder." => "Вкажіть теку для даних.", +"%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." => "Вам потрібно ввести або існуючий обліковий запис або administrator.", +"Oracle username and/or password not valid" => "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.", +"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 хвилину тому", "%d minutes ago" => "%d хвилин тому", diff --git a/lib/l10n/ur_PK.php b/lib/l10n/ur_PK.php new file mode 100644 index 00000000000..7e09d79bc68 --- /dev/null +++ b/lib/l10n/ur_PK.php @@ -0,0 +1,8 @@ +<?php $TRANSLATIONS = array( +"Help" => "مدد", +"Personal" => "ذاتی", +"Settings" => "سیٹینگز", +"Users" => "یوزرز", +"Apps" => "ایپز", +"Admin" => "ایڈمن" +); diff --git a/lib/mail.php b/lib/mail.php index 22194045a76..61634632efc 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -119,4 +119,12 @@ class OC_Mail { return($txt); } + + /** + * @param string $emailAddress a given email address to be validated + * @return bool + */ + public static function ValidateAddress($emailAddress) { + return PHPMailer::ValidateAddress($emailAddress); + } } diff --git a/lib/public/files.php b/lib/public/files.php index c2945b200e8..700bf574537 100644 --- a/lib/public/files.php +++ b/lib/public/files.php @@ -62,7 +62,8 @@ class Files { * @return int the number of bytes copied */ public static function streamCopy( $source, $target ) { - return(\OC_Helper::streamCopy( $source, $target )); + list($count, $result) = \OC_Helper::streamCopy( $source, $target ); + return $count; } /** diff --git a/lib/public/share.php b/lib/public/share.php index c0f35333e83..59f41a9bfd6 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -61,6 +61,7 @@ class Share { private static $shareTypeGroupUserUnique = 2; private static $backends = array(); private static $backendTypes = array(); + private static $isResharingAllowed; /** * @brief Register a sharing backend class that implements OCP\Share_Backend for an item type @@ -384,7 +385,7 @@ class Share { 'itemSource' => $itemSource, 'shareType' => $shareType, 'shareWith' => $shareWith, - )); + )); self::delete($item['id']); return true; } @@ -404,7 +405,7 @@ class Share { 'itemType' => $itemType, 'itemSource' => $itemSource, 'shares' => $shares - )); + )); foreach ($shares as $share) { self::delete($share['id']); } @@ -568,6 +569,24 @@ class Share { } /** + * @brief Check if resharing is allowed + * @return Returns true if allowed or false + * + * Resharing is allowed by default if not configured + * + */ + private static function isResharingAllowed() { + if (!isset(self::$isResharingAllowed)) { + if (\OC_Appconfig::getValue('core', 'shareapi_allow_resharing', 'yes') == 'yes') { + self::$isResharingAllowed = true; + } else { + self::$isResharingAllowed = false; + } + } + return self::$isResharingAllowed; + } + + /** * @brief Get a list of collection item types for the specified item type * @param string Item type * @return array @@ -767,7 +786,7 @@ class Share { } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, - `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`'; + `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`, `storage`'; } } else { $select = '*'; @@ -840,7 +859,10 @@ class Share { continue; } } - + // Check if resharing is allowed, if not remove share permission + if (isset($row['permissions']) && !self::isResharingAllowed()) { + $row['permissions'] &= ~PERMISSION_SHARE; + } // Add display names to result if ( isset($row['share_with']) && $row['share_with'] != '') { $row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']); @@ -848,7 +870,7 @@ class Share { if ( isset($row['uid_owner']) && $row['uid_owner'] != '') { $row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']); } - + $items[$row['id']] = $row; } if (!empty($items)) { @@ -978,7 +1000,7 @@ class Share { throw new \Exception($message); } // Check if share permissions is granted - if ((int)$checkReshare['permissions'] & PERMISSION_SHARE) { + if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & PERMISSION_SHARE) { if (~(int)$checkReshare['permissions'] & $permissions) { $message = 'Sharing '.$itemSource .' failed, because the permissions exceed permissions granted to '.$uidOwner; diff --git a/lib/public/user.php b/lib/public/user.php index 86d1d0ccde8..9edebe0e7cf 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -52,25 +52,25 @@ class User { public static function getUsers($search = '', $limit = null, $offset = null) { return \OC_USER::getUsers(); } - - /**
- * @brief get the user display name of the user currently logged in.
- * @return string display name
- */
- public static function getDisplayName($user=null) {
- return \OC_USER::getDisplayName($user);
+ + /** + * @brief get the user display name of the user currently logged in. + * @return string display name + */ + public static function getDisplayName($user=null) { + return \OC_USER::getDisplayName($user); } - - /**
- * @brief Get a list of all display names
- * @returns array with all display names (value) and the correspondig uids (key)
- *
- * Get a list of all display names and user ids.
- */
- public static function getDisplayNames($search = '', $limit = null, $offset = null) {
- return \OC_USER::getDisplayNames($search, $limit, $offset);
+ + /** + * @brief Get a list of all display names + * @returns array with all display names (value) and the correspondig uids (key) + * + * Get a list of all display names and user ids. + */ + public static function getDisplayNames($search = '', $limit = null, $offset = null) { + return \OC_USER::getDisplayNames($search, $limit, $offset); } - + /** * @brief Check if the user is logged in * @returns true/false diff --git a/lib/public/util.php b/lib/public/util.php index 13498b260ef..db07cbcfff3 100644 --- a/lib/public/util.php +++ b/lib/public/util.php @@ -217,11 +217,14 @@ class Util { */ public static function getDefaultEmailAddress($user_part) { $host_name = self::getServerHostName(); - // handle localhost installations - if ($host_name === 'localhost') { - $host_name = "example.com"; + $defaultEmailAddress = $user_part.'@'.$host_name; + + if (\OC_Mail::ValidateAddress($defaultEmailAddress)) { + return $defaultEmailAddress; } - return $user_part.'@'.$host_name; + + // in case we cannot build a valid email address from the hostname let's fallback to 'localhost.localdomain' + return $user_part.'@localhost.localdomain'; } /** diff --git a/lib/request.php b/lib/request.php index 3af93289670..9f74cf9beb5 100755 --- a/lib/request.php +++ b/lib/request.php @@ -107,7 +107,7 @@ class OC_Request { if (array_key_exists('PATH_INFO', $_SERVER)) { $path_info = $_SERVER['PATH_INFO']; }else{ - $path_info = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME'])); + $path_info = self::getRawPathInfo(); // following is taken from Sabre_DAV_URLUtil::decodePathSegment $path_info = rawurldecode($path_info); $encoding = mb_detect_encoding($path_info, array('UTF-8', 'ISO-8859-1')); @@ -124,6 +124,19 @@ class OC_Request { } /** + * @brief get Path info from request, not urldecoded + * @returns string Path info or false when not found + */ + public static function getRawPathInfo() { + $path_info = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME'])); + // Remove the query string from REQUEST_URI + if ($pos = strpos($path_info, '?')) { + $path_info = substr($path_info, 0, $pos); + } + return $path_info; + } + + /** * @brief Check if this is a no-cache request * @returns true for no-cache */ @@ -149,7 +162,7 @@ class OC_Request { return 'gzip'; return false; } - + /** * @brief Check if the requester sent along an mtime * @returns false or an mtime diff --git a/lib/search.php b/lib/search.php index e5a65f7157d..b9c75dfc333 100644 --- a/lib/search.php +++ b/lib/search.php @@ -57,14 +57,14 @@ class OC_Search{ } return $results; } - + /** * remove an existing search provider * @param string $provider class name of a OC_Search_Provider */ public static function removeProvider($provider) { self::$registeredProviders = array_filter( - self::$registeredProviders, + self::$registeredProviders, function ($element) use ($provider) { return ($element['class'] != $provider); } diff --git a/lib/setup.php b/lib/setup.php index 0c049841b2a..8814447f52f 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -40,11 +40,13 @@ class OC_Setup { $error[] = $l->t('Specify a data folder.'); } - if($dbtype=='mysql' or $dbtype == 'pgsql' or $dbtype == 'oci') { //mysql and postgresql needs more config options - if($dbtype=='mysql') + if($dbtype == 'mysql' or $dbtype == 'pgsql' or $dbtype == 'oci' or $dbtype == 'mssql') { //mysql and postgresql needs more config options + if($dbtype == 'mysql') $dbprettyname = 'MySQL'; - else if($dbtype=='pgsql') + else if($dbtype == 'pgsql') $dbprettyname = 'PostgreSQL'; + else if ($dbtype == 'mssql') + $dbprettyname = 'MS SQL Server'; else $dbprettyname = 'Oracle'; @@ -98,7 +100,7 @@ class OC_Setup { $error[] = array( 'error' => $e->getMessage(), 'hint' => $e->getHint() - ); + ); return($error); } catch (Exception $e) { $error[] = array( @@ -152,6 +154,29 @@ class OC_Setup { return $error; } } + elseif ($dbtype == 'mssql') { + $dbuser = $options['dbuser']; + $dbpass = $options['dbpass']; + $dbname = $options['dbname']; + $dbhost = $options['dbhost']; + $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_'; + + OC_Config::setValue('dbname', $dbname); + OC_Config::setValue('dbhost', $dbhost); + OC_Config::setValue('dbuser', $dbuser); + OC_Config::setValue('dbpassword', $dbpass); + OC_Config::setValue('dbtableprefix', $dbtableprefix); + + try { + self::setupMSSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix); + } catch (Exception $e) { + $error[] = array( + 'error' => 'MS SQL username and/or password not valid', + 'hint' => 'You need to enter either an existing account or the administrator.' + ); + return $error; + } + } else { //delete the old sqlite database first, might cause infinte loops otherwise if(file_exists("$datadir/owncloud.db")) { @@ -174,7 +199,7 @@ class OC_Setup { 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'); - + OC_Group::createGroup('admin'); OC_Group::addToGroup($username, 'admin'); OC_User::login($username, $password); @@ -236,8 +261,8 @@ class OC_Setup { } //fill the database if needed - $query="select count(*) from information_schema.tables' - .' where table_schema='$dbname' AND table_name = '{$dbtableprefix}users';"; + $query='select count(*) from information_schema.tables' + ." where table_schema='$dbname' AND table_name = '{$dbtableprefix}users';"; $result = mysql_query($query, $connection); if($result) { $row=mysql_fetch_row($result); @@ -256,11 +281,12 @@ class OC_Setup { if(!$result) { $entry = $l->t('DB Error: "%s"', array(mysql_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); } $query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'"; - //this query will fail if there aren't the right permissons, ignore the error - $result = mysql_query($query, $connection); + + //this query will fail if there aren't the right permissions, ignore the error + mysql_query($query, $connection); } private static function createDBUser($name, $password, $connection) { @@ -276,7 +302,7 @@ class OC_Setup { $query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'"; $result = mysql_query($query, $connection); if (!$result) { - throw new DatabaseSetupException($l->t("MySQL user '%s'@'%%' already exists", array($name)), + throw new DatabaseSetupException($l->t("MySQL user '%s'@'%%' already exists", array($name)), $l->t("Drop this user from MySQL.")); } } @@ -359,7 +385,7 @@ class OC_Setup { if(!$result) { $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } if(! pg_fetch_row($result)) { //The database does not exists... let's create it @@ -368,11 +394,11 @@ class OC_Setup { if(!$result) { $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } else { $query = "REVOKE ALL PRIVILEGES ON DATABASE \"$e_name\" FROM PUBLIC"; - $result = pg_query($connection, $query); + pg_query($connection, $query); } } } @@ -386,7 +412,7 @@ class OC_Setup { if(!$result) { $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } if(! pg_fetch_row($result)) { @@ -396,7 +422,7 @@ class OC_Setup { if(!$result) { $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } } else { // change password of the existing role @@ -405,7 +431,7 @@ class OC_Setup { if(!$result) { $entry = $l->t('DB Error: "%s"', array(pg_last_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.pg', $entry, \OC_Log::WARN); } } } @@ -428,13 +454,13 @@ class OC_Setup { } //check for roles creation rights in oracle - $query="SELECT count(*) FROM user_role_privs, role_sys_privs' - .' WHERE user_role_privs.granted_role = role_sys_privs.role AND privilege = 'CREATE ROLE'"; + $query='SELECT count(*) FROM user_role_privs, role_sys_privs' + ." WHERE user_role_privs.granted_role = role_sys_privs.role AND privilege = 'CREATE ROLE'"; $stmt = oci_parse($connection, $query); if (!$stmt) { $entry = $l->t('DB Error: "%s"', array(oci_last_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } $result = oci_execute($stmt); if($result) { @@ -498,9 +524,9 @@ class OC_Setup { $un = $dbtableprefix.'users'; oci_bind_by_name($stmt, ':un', $un); if (!$stmt) { - $entry = $l->t('DB Error: "%s"', array(oci_last_error($connection))) . '<br />'; + $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } $result = oci_execute($stmt); @@ -526,14 +552,14 @@ class OC_Setup { if (!$stmt) { $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } oci_bind_by_name($stmt, ':un', $name); $result = oci_execute($stmt); if(!$result) { $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } if(! oci_fetch_row($stmt)) { @@ -544,15 +570,15 @@ class OC_Setup { if (!$stmt) { $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } //oci_bind_by_name($stmt, ':un', $name); $result = oci_execute($stmt); if(!$result) { $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; - $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', + $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', array($query, $name, $password)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } } else { // change password of the existing role $query = "ALTER USER :un IDENTIFIED BY :pw"; @@ -560,7 +586,7 @@ class OC_Setup { if (!$stmt) { $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } oci_bind_by_name($stmt, ':un', $name); oci_bind_by_name($stmt, ':pw', $password); @@ -568,26 +594,200 @@ class OC_Setup { if(!$result) { $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } } - // grant neccessary roles + // grant necessary roles $query = 'GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER, UNLIMITED TABLESPACE TO '.$name; $stmt = oci_parse($connection, $query); if (!$stmt) { $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; $entry .= $l->t('Offending command was: "%s"', array($query)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } $result = oci_execute($stmt); if(!$result) { $entry = $l->t('DB Error: "%s"', array(oci_error($connection))) . '<br />'; - $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', + $entry .= $l->t('Offending command was: "%s", name: %s, password: %s', array($query, $name, $password)) . '<br />'; - echo($entry); + \OC_Log::write('setup.oci', $entry, \OC_Log::WARN); } } + private static function setupMSSQLDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix) { + $l = self::getTrans(); + + //check if the database user has admin right + $masterConnectionInfo = array( "Database" => "master", "UID" => $dbuser, "PWD" => $dbpass); + + $masterConnection = @sqlsrv_connect($dbhost, $masterConnectionInfo); + if(!$masterConnection) { + $entry = null; + if( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + throw new Exception($l->t('MS SQL username and/or password not valid: %s', array($entry))); + } + + OC_Config::setValue('dbuser', $dbuser); + OC_Config::setValue('dbpassword', $dbpass); + + self::mssql_createDBLogin($dbuser, $dbpass, $masterConnection); + + self::mssql_createDatabase($dbname, $masterConnection); + + self::mssql_createDBUser($dbuser, $dbname, $masterConnection); + + sqlsrv_close($masterConnection); + + self::mssql_createDatabaseStructure($dbhost, $dbname, $dbuser, $dbpass, $dbtableprefix); + } + + private static function mssql_createDBLogin($name, $password, $connection) { + $query = "SELECT * FROM master.sys.server_principals WHERE name = '".$name."';"; + $result = sqlsrv_query($connection, $query); + if ($result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + $row = sqlsrv_fetch_array($result); + + if ($row === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + if ($row == null) { + $query = "CREATE LOGIN [".$name."] WITH PASSWORD = '".$password."';"; + $result = sqlsrv_query($connection, $query); + if (!$result or $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + } + } + } + + private static function mssql_createDBUser($name, $dbname, $connection) { + $query = "SELECT * FROM [".$dbname."].sys.database_principals WHERE name = '".$name."';"; + $result = sqlsrv_query($connection, $query); + if ($result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + $row = sqlsrv_fetch_array($result); + + if ($row === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + if ($row == null) { + $query = "USE [".$dbname."]; CREATE USER [".$name."] FOR LOGIN [".$name."];"; + $result = sqlsrv_query($connection, $query); + if (!$result || $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry = 'DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + + $query = "USE [".$dbname."]; EXEC sp_addrolemember 'db_owner', '".$name."';"; + $result = sqlsrv_query($connection, $query); + if (!$result || $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + } + } + + private static function mssql_createDatabase($dbname, $connection) { + $query = "CREATE DATABASE [".$dbname."];"; + $result = sqlsrv_query($connection, $query); + if (!$result || $result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } + } + + private static function mssql_createDatabaseStructure($dbhost, $dbname, $dbuser, $dbpass, $dbtableprefix) { + $connectionInfo = array( "Database" => $dbname, "UID" => $dbuser, "PWD" => $dbpass); + + $connection = @sqlsrv_connect($dbhost, $connectionInfo); + + //fill the database if needed + $query = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{$dbname}' AND TABLE_NAME = '{$dbtableprefix}users'"; + $result = sqlsrv_query($connection, $query); + if ($result === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + $row = sqlsrv_fetch_array($result); + + if ($row === false) { + if ( ($errors = sqlsrv_errors() ) != null) { + $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />'; + } else { + $entry = ''; + } + $entry.='Offending command was: '.$query.'<br />'; + \OC_Log::write('setup.mssql', $entry, \OC_Log::WARN); + } else { + if ($row == null) { + OC_DB::createDbFromStructure('db_structure.xml'); + } + } + } + + sqlsrv_close($connection); + } + /** * create .htaccess files for apache hosts */ @@ -646,13 +846,12 @@ class OC_Setup { header("Location: ".OC::$WEBROOT.'/'); } else { - $error = $l->t('Your web server is not yet properly setup to allow files' - .' synchronization because the WebDAV interface seems to be broken.'); + $error = $l->t('Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken.'); $hint = $l->t('Please double check the <a href=\'%s\'>installation guides</a>.', 'http://doc.owncloud.org/server/5.0/admin_manual/installation.html'); $tmpl = new OC_Template('', 'error', 'guest'); - $tmpl->assign('errors', array(1 => array('error' => $error, 'hint' => $hint)), false); + $tmpl->assign('errors', array(1 => array('error' => $error, 'hint' => $hint))); $tmpl->printPage(); exit(); } diff --git a/lib/template.php b/lib/template.php index 3df5a24f946..434c1e9e990 100644 --- a/lib/template.php +++ b/lib/template.php @@ -147,7 +147,7 @@ function html_select_options($options, $selected, $params=array()) { $label = $label[$label_name]; } $select = in_array($value, $selected) ? ' selected="selected"' : ''; - $html .= '<option value="' . $value . '"' . $select . '>' . $label . '</option>'."\n"; + $html .= '<option value="' . OC_Util::sanitizeHTML($value) . '"' . $select . '>' . OC_Util::sanitizeHTML($label) . '</option>'."\n"; } return $html; } @@ -200,7 +200,6 @@ class OC_Template{ .'img-src *; ' .'font-src \'self\' data:'); header('Content-Security-Policy:'.$policy); // Standard - header('X-WebKit-CSP:'.$policy); // Older webkit browsers $this->findTemplate($name); } @@ -341,7 +340,6 @@ class OC_Template{ * @brief Assign variables * @param string $key key * @param string $value value - * @param bool $sanitizeHTML false, if data shouldn't get passed through htmlentities * @return bool * * This function assigns a variable. It can be accessed via $_[$key] in @@ -349,8 +347,7 @@ class OC_Template{ * * If the key existed before, it will be overwritten */ - public function assign( $key, $value, $sanitizeHTML=true ) { - if($sanitizeHTML == true) $value=OC_Util::sanitizeHTML($value); + public function assign( $key, $value) { $this->vars[$key] = $value; return true; } @@ -413,11 +410,6 @@ class OC_Template{ if( $this->renderas ) { $page = new OC_TemplateLayout($this->renderas); - if($this->renderas == 'user') { - $page->assign('requesttoken', $this->vars['requesttoken']); - $user = OC_User::getUser(); - $page->assign('displayname', OCP\User::getDisplayName($user)); - } // Add custom headers $page->assign('headers', $this->headers, false); @@ -489,7 +481,7 @@ class OC_Template{ public static function printUserPage( $application, $name, $parameters = array() ) { $content = new OC_Template( $application, $name, "user" ); foreach( $parameters as $key => $value ) { - $content->assign( $key, $value, false ); + $content->assign( $key, $value ); } print $content->printPage(); } @@ -504,7 +496,7 @@ class OC_Template{ public static function printAdminPage( $application, $name, $parameters = array() ) { $content = new OC_Template( $application, $name, "admin" ); foreach( $parameters as $key => $value ) { - $content->assign( $key, $value, false ); + $content->assign( $key, $value ); } return $content->printPage(); } @@ -519,7 +511,7 @@ class OC_Template{ public static function printGuestPage( $application, $name, $parameters = array() ) { $content = new OC_Template( $application, $name, "guest" ); foreach( $parameters as $key => $value ) { - $content->assign( $key, $value, false ); + $content->assign( $key, $value ); } return $content->printPage(); } @@ -527,11 +519,14 @@ class OC_Template{ /** * @brief Print a fatal error page and terminates the script * @param string $error The error message to show - * @param string $hint An option hint message + * @param string $hint An optional hint message + * Warning: All data passed to $hint needs to get sanitized using OC_Util::sanitizeHTML */ public static function printErrorPage( $error_msg, $hint = '' ) { + $content = new OC_Template( '', 'error', 'error' ); $errors = array(array('error' => $error_msg, 'hint' => $hint)); - OC_Template::printGuestPage("", "error", array("errors" => $errors)); + $content->assign( 'errors', $errors ); + $content->printPage(); die(); } } diff --git a/lib/templatelayout.php b/lib/templatelayout.php index 25d4033d9ee..29f120a6041 100644 --- a/lib/templatelayout.php +++ b/lib/templatelayout.php @@ -13,25 +13,26 @@ class OC_TemplateLayout extends OC_Template { if( $renderas == 'user' ) { parent::__construct( 'core', 'layout.user' ); if(in_array(OC_APP::getCurrentApp(), array('settings','admin', 'help'))!==false) { - $this->assign('bodyid', 'body-settings', false); + $this->assign('bodyid', 'body-settings'); }else{ - $this->assign('bodyid', 'body-user', false); + $this->assign('bodyid', 'body-user'); } // Add navigation entry $this->assign( 'application', '', false ); $navigation = OC_App::getNavigation(); - $this->assign( 'navigation', $navigation, false); - $this->assign( 'settingsnavigation', OC_App::getSettingsNavigation(), false); + $this->assign( 'navigation', $navigation); + $this->assign( 'settingsnavigation', OC_App::getSettingsNavigation()); foreach($navigation as $entry) { if ($entry['active']) { - $this->assign( 'application', $entry['name'], false ); + $this->assign( 'application', $entry['name'] ); break; } } $user_displayname = OC_User::getDisplayName(); $this->assign( 'user_displayname', $user_displayname ); - } else if ($renderas == 'guest') { + $this->assign( 'user_uid', OC_User::getUser() ); + } else if ($renderas == 'guest' || $renderas == 'error') { parent::__construct('core', 'layout.guest'); } else { parent::__construct('core', 'layout.base'); @@ -39,7 +40,7 @@ class OC_TemplateLayout extends OC_Template { // Add the js files $jsfiles = self::findJavascriptFiles(OC_Util::$scripts); $this->assign('jsfiles', array(), false); - if (OC_Config::getValue('installed', false)) { + if (OC_Config::getValue('installed', false) && $renderas!='error') { $this->append( 'jsfiles', OC_Helper::linkToRoute('js_config')); } if (!empty(OC_Util::$core_scripts)) { diff --git a/lib/user.php b/lib/user.php index e69fef95a13..6144f0f6bf9 100644 --- a/lib/user.php +++ b/lib/user.php @@ -437,7 +437,7 @@ class OC_User { } return false; } - + /** * @brief Check whether user can change his display name * @param $uid The username @@ -530,7 +530,7 @@ class OC_User { $displayNames = array_merge($displayNames, $backendDisplayNames); } } - ksort($displayNames); + asort($displayNames); return $displayNames; } @@ -589,8 +589,8 @@ class OC_User { * @param string $userid */ public static function enableUser($userid) { - $sql = "DELETE FROM `*PREFIX*preferences`' - .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ? AND `configvalue` = ?"; + $sql = 'DELETE FROM `*PREFIX*preferences`' + ." WHERE `userid` = ? AND `appid` = ? AND `configkey` = ? AND `configvalue` = ?"; $stmt = OC_DB::prepare($sql); if ( ! OC_DB::isError($stmt) ) { $result = $stmt->execute(array($userid, 'core', 'enabled', 'false')); diff --git a/lib/user/backend.php b/lib/user/backend.php index 60b3cc6c5e4..93e8f17ca98 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -124,7 +124,7 @@ abstract class OC_User_Backend implements OC_User_Interface { public function getHome($uid) { return false; } - + /** * @brief get display name of the user * @param $uid user ID of the user @@ -133,7 +133,7 @@ abstract class OC_User_Backend implements OC_User_Interface { public function getDisplayName($uid) { return $uid; } - + /** * @brief Get a list of all display names * @returns array with all displayNames (value) and the corresponding uids (key) diff --git a/lib/user/database.php b/lib/user/database.php index a0ad03fe0a0..210c7f3e1eb 100644 --- a/lib/user/database.php +++ b/lib/user/database.php @@ -110,7 +110,7 @@ class OC_User_Database extends OC_User_Backend { return false; } } - + /** * @brief Set display name * @param $uid The username @@ -146,7 +146,7 @@ class OC_User_Database extends OC_User_Backend { } } } - + /** * @brief Get a list of all display names * @returns array with all displayNames (value) and the correspondig uids (key) @@ -162,7 +162,7 @@ class OC_User_Database extends OC_User_Backend { while ($row = $result->fetchRow()) { $displayNames[$row['uid']] = $row['displayname']; } - + // let's see if we can also find some users who don't have a display name yet $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users`' .' WHERE LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); @@ -173,11 +173,11 @@ class OC_User_Database extends OC_User_Backend { $displayNames[$row['uid']] = $row['uid']; } } - - + + return $displayNames; } - + /** * @brief Check if the password is correct * @param $uid The username diff --git a/lib/util.php b/lib/util.php index e739f76034c..6ed3b8b942f 100755 --- a/lib/util.php +++ b/lib/util.php @@ -73,9 +73,9 @@ class OC_Util { * @return array */ public static function getVersion() { - // hint: We only can count up. So the internal version number - // of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4, 92, 11); + // hint: We only can count up. Reset minor/patchlevel when + // updating major/minor version number. + return array(4, 97, 11); } /** @@ -83,7 +83,7 @@ class OC_Util { * @return string */ public static function getVersionString() { - return '5.0 alpha 1'; + return '5.0 RC 3'; } /** @@ -172,20 +172,20 @@ class OC_Util { if(!(is_callable('sqlite_open') or class_exists('SQLite3')) and !is_callable('mysql_connect') and !is_callable('pg_connect')) { - $errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.<br/>', + $errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.', 'hint'=>'');//TODO: sane hint $web_server_restart= true; } //common hint for all file permissons error messages - $permissionsHint="Permissions can usually be fixed by giving the webserver write access' - .' to the ownCloud directory"; + $permissionsHint='Permissions can usually be fixed by giving the webserver write access' + .' to the ownCloud directory'; // Check if config folder is writable. if(!is_writable(OC::$SERVERROOT."/config/") or !is_readable(OC::$SERVERROOT."/config/")) { $errors[]=array('error'=>"Can't write into config directory 'config'", - 'hint'=>"You can usually fix this by giving the webserver user write access' - .' to the config directory in owncloud"); + 'hint'=>'You can usually fix this by giving the webserver user write access' + .' to the config directory in owncloud'); } // Check if there is a writable install folder. @@ -194,8 +194,8 @@ class OC_Util { || !is_writable(OC_App::getInstallPath()) || !is_readable(OC_App::getInstallPath()) ) { $errors[]=array('error'=>"Can't write into apps directory", - 'hint'=>"You can usually fix this by giving the webserver user write access' - .' to the apps directory in owncloud or disabling the appstore in the config file."); + 'hint'=>'You can usually fix this by giving the webserver user write access' + .' to the apps directory in owncloud or disabling the appstore in the config file.'); } } $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); @@ -218,73 +218,74 @@ class OC_Util { } // check if all required php modules are present if(!class_exists('ZipArchive')) { - $errors[]=array('error'=>'PHP module zip not installed.<br/>', + $errors[]=array('error'=>'PHP module zip not installed.', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } - + if(!class_exists('DOMDocument')) { + $errors[] = array('error' => 'PHP module dom not installed.', + 'hint' => 'Please ask your server administrator to install the module.'); + $web_server_restart = false; + } + if(!function_exists('xml_parser_create')) { + $errors[] = array('error' => 'PHP module libxml not installed.', + 'hint' => 'Please ask your server administrator to install the module.'); + $web_server_restart = false; + } if(!function_exists('mb_detect_encoding')) { - $errors[]=array('error'=>'PHP module mb multibyte not installed.<br/>', + $errors[]=array('error'=>'PHP module mb multibyte not installed.', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('ctype_digit')) { - $errors[]=array('error'=>'PHP module ctype is not installed.<br/>', + $errors[]=array('error'=>'PHP module ctype is not installed.', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('json_encode')) { - $errors[]=array('error'=>'PHP module JSON is not installed.<br/>', + $errors[]=array('error'=>'PHP module JSON is not installed.', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('imagepng')) { - $errors[]=array('error'=>'PHP module GD is not installed.<br/>', + $errors[]=array('error'=>'PHP module GD is not installed.', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('gzencode')) { - $errors[]=array('error'=>'PHP module zlib is not installed.<br/>', + $errors[]=array('error'=>'PHP module zlib is not installed.', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('iconv')) { - $errors[]=array('error'=>'PHP module iconv is not installed.<br/>', + $errors[]=array('error'=>'PHP module iconv is not installed.', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(!function_exists('simplexml_load_string')) { - $errors[]=array('error'=>'PHP module SimpleXML is not installed.<br/>', + $errors[]=array('error'=>'PHP module SimpleXML is not installed.', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } if(floatval(phpversion())<5.3) { - $errors[]=array('error'=>'PHP 5.3 is required.<br/>', + $errors[]=array('error'=>'PHP 5.3 is required.', 'hint'=>'Please ask your server administrator to update PHP to version 5.3 or higher.' .' PHP 5.2 is no longer supported by ownCloud and the PHP community.'); $web_server_restart= false; } if(!defined('PDO::ATTR_DRIVER_NAME')) { - $errors[]=array('error'=>'PHP PDO module is not installed.<br/>', + $errors[]=array('error'=>'PHP PDO module is not installed.', 'hint'=>'Please ask your server administrator to install the module.'); $web_server_restart= false; } - - $handler = ini_get("session.save_handler"); - if($handler == "files") { - $tmpDir = session_save_path(); - if($tmpDir != "") { - if(!@is_writable($tmpDir)) { - $errors[]=array('error' => 'The temporary folder used by PHP to save the session data' - .' is either incorrect or not writable! Please check : '.session_save_path().'<br/>', - 'hint'=>'Please ask your server administrator to grant write access' - .' or define another temporary folder.'); - } - } + if(ini_get('safe_mode')) { + $errors[]=array('error'=>'PHP Safe Mode is enabled. ownCloud requires that it is disabled to work properly.', + 'hint'=>'PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config.'); + $web_server_restart= false; } if($web_server_restart) { - $errors[]=array('error'=>'PHP modules have been installed, but they are still listed as missing?<br/>', + $errors[]=array('error'=>'PHP modules have been installed, but they are still listed as missing?', 'hint'=>'Please ask your server administrator to restart the web server.'); } @@ -322,14 +323,14 @@ class OC_Util { $parameters[$value] = true; } if (!empty($_POST['user'])) { - $parameters["username"] = OC_Util::sanitizeHTML($_POST['user']).'"'; + $parameters["username"] = $_POST['user']; $parameters['user_autofocus'] = false; } else { $parameters["username"] = ''; $parameters['user_autofocus'] = true; } if (isset($_REQUEST['redirect_url'])) { - $redirect_url = OC_Util::sanitizeHTML($_REQUEST['redirect_url']); + $redirect_url = $_REQUEST['redirect_url']; $parameters['redirect_url'] = urlencode($redirect_url); } @@ -463,13 +464,17 @@ class OC_Util { * @see OC_Util::callRegister() */ public static function isCallRegistered() { + if(!isset($_SESSION['requesttoken'])) { + return false; + } + if(isset($_GET['requesttoken'])) { $token=$_GET['requesttoken']; - }elseif(isset($_POST['requesttoken'])) { + } elseif(isset($_POST['requesttoken'])) { $token=$_POST['requesttoken']; - }elseif(isset($_SERVER['HTTP_REQUESTTOKEN'])) { + } elseif(isset($_SERVER['HTTP_REQUESTTOKEN'])) { $token=$_SERVER['HTTP_REQUESTTOKEN']; - }else{ + } else { //no token found. return false; } @@ -504,10 +509,10 @@ class OC_Util { * @return array with sanitized strings or a single sanitized string, depends on the input parameter. */ public static function sanitizeHTML( &$value ) { - if (is_array($value) || is_object($value)) { + if (is_array($value)) { array_walk_recursive($value, 'OC_Util::sanitizeHTML'); } else { - $value = htmlentities($value, ENT_QUOTES, 'UTF-8'); //Specify encoding for PHP<5.4 + $value = htmlentities((string)$value, ENT_QUOTES, 'UTF-8'); //Specify encoding for PHP<5.4 } return $value; } @@ -562,15 +567,23 @@ class OC_Util { */ public static function isWebDAVWorking() { if (!function_exists('curl_init')) { - return; + return true; } - $settings = array( 'baseUri' => OC_Helper::linkToRemote('webdav'), ); + // save the old timeout so that we can restore it later + $old_timeout=ini_get("default_socket_timeout"); + + // use a 5 sec timeout for the check. Should be enough for local requests. + ini_set("default_socket_timeout", 5); + $client = new \Sabre_DAV_Client($settings); + // for this self test we don't care if the ssl certificate is self signed and the peer cannot be verified. + $client->setVerifyPeer(false); + $return = true; try { // test PROPFIND @@ -578,9 +591,13 @@ class OC_Util { } catch(\Sabre_DAV_Exception_NotAuthenticated $e) { $return = true; } catch(\Exception $e) { + OC_Log::write('core', 'isWebDAVWorking: NO - Reason: '.$e, OC_Log::WARN); $return = false; } + // restore the original timeout + ini_set("default_socket_timeout", $old_timeout); + return $return; } diff --git a/lib/vcategories.php b/lib/vcategories.php index 8de497a6191..2f990c5d2d2 100644 --- a/lib/vcategories.php +++ b/lib/vcategories.php @@ -306,12 +306,18 @@ class OC_VCategories { OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', OCP\Util::DEBUG); return false; } - OCP\DB::insertIfNotExist(self::CATEGORY_TABLE, - array( - 'uid' => $this->user, - 'type' => $this->type, - 'category' => $name, - )); + try { + OCP\DB::insertIfNotExist(self::CATEGORY_TABLE, + array( + 'uid' => $this->user, + 'type' => $this->type, + 'category' => $name, + )); + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + return false; + } $id = OCP\DB::insertid(self::CATEGORY_TABLE); OCP\Util::writeLog('core', __METHOD__.', id: ' . $id, OCP\Util::DEBUG); $this->categories[$id] = $name; @@ -342,12 +348,11 @@ class OC_VCategories { self::$relations[] = array('objid' => $id, 'category' => $name); } } - if(count($newones) > 0) { - $this->categories = array_merge($this->categories, $newones); - if($sync === true) { - $this->save(); - } + $this->categories = array_merge($this->categories, $newones); + if($sync === true) { + $this->save(); } + return true; } @@ -436,12 +441,17 @@ class OC_VCategories { private function save() { if(is_array($this->categories)) { foreach($this->categories as $category) { - OCP\DB::insertIfNotExist(self::CATEGORY_TABLE, - array( - 'uid' => $this->user, - 'type' => $this->type, - 'category' => $category, - )); + try { + OCP\DB::insertIfNotExist(self::CATEGORY_TABLE, + array( + 'uid' => $this->user, + 'type' => $this->type, + 'category' => $category, + )); + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + } } // reload categories to get the proper ids. $this->loadCategories(); @@ -454,12 +464,17 @@ class OC_VCategories { $catid = $this->array_searchi($relation['category'], $categories); OC_Log::write('core', __METHOD__ . 'catid, ' . $relation['category'] . ' ' . $catid, OC_Log::DEBUG); if($catid) { - OCP\DB::insertIfNotExist(self::RELATION_TABLE, - array( - 'objid' => $relation['objid'], - 'categoryid' => $catid, - 'type' => $this->type, - )); + try { + OCP\DB::insertIfNotExist(self::RELATION_TABLE, + array( + 'objid' => $relation['objid'], + 'categoryid' => $catid, + 'type' => $this->type, + )); + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + } } } self::$relations = array(); // reset |