summaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rwxr-xr-xlib/private/activitymanager.php69
-rw-r--r--lib/private/api.php22
-rw-r--r--lib/private/app.php1
-rw-r--r--lib/private/appconfig.php6
-rw-r--r--lib/private/appframework/dependencyinjection/dicontainer.php7
-rw-r--r--lib/private/appframework/http.php (renamed from lib/private/appframework/http/http.php)5
-rw-r--r--lib/private/appframework/http/dispatcher.php1
-rw-r--r--lib/private/appframework/http/redirectresponse.php3
-rw-r--r--lib/private/appframework/middleware/security/securitymiddleware.php2
-rw-r--r--lib/private/config.php2
-rw-r--r--lib/private/connector/sabre/file.php3
-rw-r--r--lib/private/connector/sabre/node.php11
-rw-r--r--lib/private/connector/sabre/objecttree.php5
-rw-r--r--lib/private/connector/sabre/server.php235
-rw-r--r--lib/private/davclient.php46
-rw-r--r--lib/private/db/connection.php2
-rw-r--r--lib/private/db/connectionwrapper.php99
-rw-r--r--lib/private/db/mdb2schemamanager.php7
-rw-r--r--lib/private/files/cache/cache.php16
-rw-r--r--lib/private/files/cache/scanner.php36
-rw-r--r--lib/private/group.php2
-rw-r--r--lib/private/helper.php9
-rw-r--r--lib/private/log/owncloud.php13
-rw-r--r--lib/private/ocs/cloud.php13
-rw-r--r--lib/private/preview/movies.php2
-rw-r--r--lib/private/preview/office.php6
-rw-r--r--lib/private/server.php14
-rw-r--r--lib/private/setup.php2
-rw-r--r--lib/private/template/functions.php8
-rwxr-xr-xlib/private/util.php27
30 files changed, 626 insertions, 48 deletions
diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php
new file mode 100755
index 00000000000..7e7e2257874
--- /dev/null
+++ b/lib/private/activitymanager.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright (c) 2013 Thomas Müller thomas.mueller@tmit.eu
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+namespace OC;
+
+
+use OCP\Activity\IConsumer;
+use OCP\Activity\IManager;
+
+class ActivityManager implements IManager {
+
+ private $consumers = array();
+
+ /**
+ * @param $app
+ * @param $subject
+ * @param $subjectParams
+ * @param $message
+ * @param $messageParams
+ * @param $file
+ * @param $link
+ * @param $affectedUser
+ * @param $type
+ * @param $priority
+ * @return mixed
+ */
+ function publishActivity($app, $subject, $subjectParams, $message, $messageParams, $file, $link, $affectedUser, $type, $priority) {
+ foreach($this->consumers as $consumer) {
+ $c = $consumer();
+ if ($c instanceof IConsumer) {
+ try {
+ $c->receive(
+ $app,
+ $subject,
+ $subjectParams,
+ $message,
+ $messageParams,
+ $file,
+ $link,
+ $affectedUser,
+ $type,
+ $priority);
+ } catch (\Exception $ex) {
+ // TODO: log the excepetion
+ }
+ }
+
+ }
+ }
+
+ /**
+ * In order to improve lazy loading a closure can be registered which will be called in case
+ * activity consumers are actually requested
+ *
+ * $callable has to return an instance of OCA\Activity\IConsumer
+ *
+ * @param string $key
+ * @param \Closure $callable
+ */
+ function registerConsumer(\Closure $callable) {
+ array_push($this->consumers, $callable);
+ }
+
+}
diff --git a/lib/private/api.php b/lib/private/api.php
index 31f3f968d9b..26091657b31 100644
--- a/lib/private/api.php
+++ b/lib/private/api.php
@@ -46,6 +46,7 @@ class OC_API {
* api actions
*/
protected static $actions = array();
+ private static $logoutRequired = false;
/**
* registers an api call
@@ -115,7 +116,9 @@ class OC_API {
$formats = array('json', 'xml');
$format = !empty($_GET['format']) && in_array($_GET['format'], $formats) ? $_GET['format'] : 'xml';
- OC_User::logout();
+ if (self::$logoutRequired) {
+ OC_User::logout();
+ }
self::respond($response, $format);
}
@@ -235,10 +238,23 @@ class OC_API {
* http basic auth
* @return string|false (username, or false on failure)
*/
- private static function loginUser(){
+ private static function loginUser(){
+ // basic auth
$authUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
$authPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
- return OC_User::login($authUser, $authPw) ? $authUser : false;
+ $return = OC_User::login($authUser, $authPw);
+ if ($return === true) {
+ self::$logoutRequired = true;
+ return $authUser;
+ }
+
+ // reuse existing login
+ $loggedIn = OC_User::isLoggedIn();
+ if ($loggedIn === true) {
+ return OC_User::getUser();
+ }
+
+ return false;
}
/**
diff --git a/lib/private/app.php b/lib/private/app.php
index 6f45b6e6dd7..eca40a81cc1 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -249,6 +249,7 @@ class OC_App{
if(isset($appdata['id'])) {
OC_Appconfig::setValue( $app, 'ocsid', $appdata['id'] );
}
+ \OC_Hook::emit('OC_App', 'post_enable', array('app' => $app));
}
}else{
throw new \Exception($l->t("No app name specified"));
diff --git a/lib/private/appconfig.php b/lib/private/appconfig.php
index e615d838173..4f170e054e9 100644
--- a/lib/private/appconfig.php
+++ b/lib/private/appconfig.php
@@ -134,6 +134,12 @@ class OC_Appconfig{
.' WHERE `appid` = ? AND `configkey` = ?' );
$query->execute( array( $value, $app, $key ));
}
+ // TODO where should this be documented?
+ \OC_Hook::emit('OC_Appconfig', 'post_set_value', array(
+ 'app' => $app,
+ 'key' => $key,
+ 'value' => $value
+ ));
}
/**
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php
index 81910df6990..e2ea974e104 100644
--- a/lib/private/appframework/dependencyinjection/dicontainer.php
+++ b/lib/private/appframework/dependencyinjection/dicontainer.php
@@ -24,7 +24,7 @@
namespace OC\AppFramework\DependencyInjection;
-use OC\AppFramework\Http\Http;
+use OC\AppFramework\Http;
use OC\AppFramework\Http\Request;
use OC\AppFramework\Http\Dispatcher;
use OC\AppFramework\Core\API;
@@ -88,8 +88,9 @@ class DIContainer extends SimpleContainer implements IAppContainer{
/**
* Middleware
*/
- $this['SecurityMiddleware'] = $this->share(function($c){
- return new SecurityMiddleware($this, $c['Request']);
+ $app = $this;
+ $this['SecurityMiddleware'] = $this->share(function($c) use ($app){
+ return new SecurityMiddleware($app, $c['Request']);
});
$middleWares = $this->middleWares;
diff --git a/lib/private/appframework/http/http.php b/lib/private/appframework/http.php
index e00dc9cdc4a..41fc0db6b38 100644
--- a/lib/private/appframework/http/http.php
+++ b/lib/private/appframework/http.php
@@ -22,10 +22,11 @@
*/
-namespace OC\AppFramework\Http;
+namespace OC\AppFramework;
+use OCP\AppFramework\Http as BaseHttp;
-class Http extends \OCP\AppFramework\Http\Http{
+class Http extends BaseHttp {
private $server;
private $protocolVersion;
diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/appframework/http/dispatcher.php
index 51283fd64e7..a2afb53f0fa 100644
--- a/lib/private/appframework/http/dispatcher.php
+++ b/lib/private/appframework/http/dispatcher.php
@@ -25,6 +25,7 @@
namespace OC\AppFramework\Http;
use \OC\AppFramework\Middleware\MiddlewareDispatcher;
+use \OC\AppFramework\Http;
use OCP\AppFramework\Controller;
diff --git a/lib/private/appframework/http/redirectresponse.php b/lib/private/appframework/http/redirectresponse.php
index 688447f1618..c4e21059480 100644
--- a/lib/private/appframework/http/redirectresponse.php
+++ b/lib/private/appframework/http/redirectresponse.php
@@ -24,7 +24,8 @@
namespace OC\AppFramework\Http;
-use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\Http\Response,
+ OCP\AppFramework\Http;
/**
diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php
index f103a40ee7f..c3143754823 100644
--- a/lib/private/appframework/middleware/security/securitymiddleware.php
+++ b/lib/private/appframework/middleware/security/securitymiddleware.php
@@ -24,7 +24,7 @@
namespace OC\AppFramework\Middleware\Security;
-use OC\AppFramework\Http\Http;
+use OC\AppFramework\Http;
use OC\AppFramework\Http\RedirectResponse;
use OC\AppFramework\Utility\MethodAnnotationReader;
use OCP\AppFramework\Middleware;
diff --git a/lib/private/config.php b/lib/private/config.php
index 72423137fa3..caf7b1d7066 100644
--- a/lib/private/config.php
+++ b/lib/private/config.php
@@ -172,7 +172,7 @@ class Config {
$result = @file_put_contents($this->configFilename, $content);
if (!$result) {
$defaults = new \OC_Defaults;
- $url = $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html#set-the-directory-permissions';
+ $url = \OC_Helper::linkToDocs('admin-dir-permissions');
throw new HintException(
"Can't write into config directory!",
'This can usually be fixed by '
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 3402946a136..6ace8d14484 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -148,6 +148,9 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
}
\OC\Files\Filesystem::unlink($this->path);
+ // remove properties
+ $this->removeProperties();
+
}
/**
diff --git a/lib/private/connector/sabre/node.php b/lib/private/connector/sabre/node.php
index c38e9f86375..3c2ad60f1dd 100644
--- a/lib/private/connector/sabre/node.php
+++ b/lib/private/connector/sabre/node.php
@@ -191,6 +191,17 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
}
/**
+ * removes all properties for this node and user
+ */
+ public function removeProperties() {
+ $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`'
+ .' WHERE `userid` = ? AND `propertypath` = ?' );
+ $query->execute( array( OC_User::getUser(), $this->path));
+
+ $this->setPropertyCache(null);
+ }
+
+ /**
* @brief Returns a list of properties for this nodes.;
* @param array $properties
* @return array
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index df8902f66e2..cd3f081f7cc 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -97,6 +97,11 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
throw new \Sabre_DAV_Exception_Forbidden('');
}
+ // update properties
+ $query = \OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertypath` = ?'
+ .' WHERE `userid` = ? AND `propertypath` = ?' );
+ $query->execute( array( $destinationPath, \OC_User::getUser(), $sourcePath ));
+
$this->markDirty($sourceDir);
$this->markDirty($destinationDir);
diff --git a/lib/private/connector/sabre/server.php b/lib/private/connector/sabre/server.php
new file mode 100644
index 00000000000..41e8885917a
--- /dev/null
+++ b/lib/private/connector/sabre/server.php
@@ -0,0 +1,235 @@
+<?php
+/**
+ * ownCloud / SabreDAV
+ *
+ * @author Markus Goetz
+ *
+ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+
+/**
+ * Class OC_Connector_Sabre_Server
+ *
+ * This class reimplements some methods from @see Sabre_DAV_Server.
+ *
+ * Basically we add handling of depth: infinity.
+ *
+ * The right way to handle this would have been to submit a patch to the upstream project
+ * and grab the corresponding version one merged.
+ *
+ * Due to time constrains and the limitations where we don't want to upgrade 3rdparty code in
+ * this stage of the release cycle we did choose this approach.
+ *
+ * For ownCloud 7 we will upgrade SabreDAV and submit the patch - if needed.
+ *
+ * @see Sabre_DAV_Server
+ */
+class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
+
+ /**
+ * @see Sabre_DAV_Server
+ */
+ protected function httpPropfind($uri) {
+
+ // $xml = new Sabre_DAV_XMLReader(file_get_contents('php://input'));
+ $requestedProperties = $this->parsePropFindRequest($this->httpRequest->getBody(true));
+
+ $depth = $this->getHTTPDepth(1);
+ // The only two options for the depth of a propfind is 0 or 1
+ // if ($depth!=0) $depth = 1;
+
+ $newProperties = $this->getPropertiesForPath($uri,$requestedProperties,$depth);
+
+ // This is a multi-status response
+ $this->httpResponse->sendStatus(207);
+ $this->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
+ $this->httpResponse->setHeader('Vary','Brief,Prefer');
+
+ // Normally this header is only needed for OPTIONS responses, however..
+ // iCal seems to also depend on these being set for PROPFIND. Since
+ // this is not harmful, we'll add it.
+ $features = array('1','3', 'extended-mkcol');
+ foreach($this->plugins as $plugin) {
+ $features = array_merge($features,$plugin->getFeatures());
+ }
+
+ $this->httpResponse->setHeader('DAV',implode(', ',$features));
+
+ $prefer = $this->getHTTPPrefer();
+ $minimal = $prefer['return-minimal'];
+
+ $data = $this->generateMultiStatus($newProperties, $minimal);
+ $this->httpResponse->sendBody($data);
+
+ }
+
+ /**
+ * Small helper to support PROPFIND with DEPTH_INFINITY.
+ */
+ private function addPathNodesRecursively(&$nodes, $path) {
+ foreach($this->tree->getChildren($path) as $childNode) {
+ $nodes[$path . '/' . $childNode->getName()] = $childNode;
+ if ($childNode instanceof Sabre_DAV_ICollection)
+ $this->addPathNodesRecursively($nodes, $path . '/' . $childNode->getName());
+ }
+ }
+
+ public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0) {
+
+ // if ($depth!=0) $depth = 1;
+
+ $path = rtrim($path,'/');
+
+ $returnPropertyList = array();
+
+ $parentNode = $this->tree->getNodeForPath($path);
+ $nodes = array(
+ $path => $parentNode
+ );
+ if ($depth==1 && $parentNode instanceof Sabre_DAV_ICollection) {
+ foreach($this->tree->getChildren($path) as $childNode)
+ $nodes[$path . '/' . $childNode->getName()] = $childNode;
+ } else if ($depth == self::DEPTH_INFINITY && $parentNode instanceof Sabre_DAV_ICollection) {
+ $this->addPathNodesRecursively($nodes, $path);
+ }
+
+ // If the propertyNames array is empty, it means all properties are requested.
+ // We shouldn't actually return everything we know though, and only return a
+ // sensible list.
+ $allProperties = count($propertyNames)==0;
+
+ foreach($nodes as $myPath=>$node) {
+
+ $currentPropertyNames = $propertyNames;
+
+ $newProperties = array(
+ '200' => array(),
+ '404' => array(),
+ );
+
+ if ($allProperties) {
+ // Default list of propertyNames, when all properties were requested.
+ $currentPropertyNames = array(
+ '{DAV:}getlastmodified',
+ '{DAV:}getcontentlength',
+ '{DAV:}resourcetype',
+ '{DAV:}quota-used-bytes',
+ '{DAV:}quota-available-bytes',
+ '{DAV:}getetag',
+ '{DAV:}getcontenttype',
+ );
+ }
+
+ // If the resourceType was not part of the list, we manually add it
+ // and mark it for removal. We need to know the resourcetype in order
+ // to make certain decisions about the entry.
+ // WebDAV dictates we should add a / and the end of href's for collections
+ $removeRT = false;
+ if (!in_array('{DAV:}resourcetype',$currentPropertyNames)) {
+ $currentPropertyNames[] = '{DAV:}resourcetype';
+ $removeRT = true;
+ }
+
+ $result = $this->broadcastEvent('beforeGetProperties',array($myPath, $node, &$currentPropertyNames, &$newProperties));
+ // If this method explicitly returned false, we must ignore this
+ // node as it is inaccessible.
+ if ($result===false) continue;
+
+ if (count($currentPropertyNames) > 0) {
+
+ if ($node instanceof Sabre_DAV_IProperties) {
+ $nodeProperties = $node->getProperties($currentPropertyNames);
+
+ // The getProperties method may give us too much,
+ // properties, in case the implementor was lazy.
+ //
+ // So as we loop through this list, we will only take the
+ // properties that were actually requested and discard the
+ // rest.
+ foreach($currentPropertyNames as $k=>$currentPropertyName) {
+ if (isset($nodeProperties[$currentPropertyName])) {
+ unset($currentPropertyNames[$k]);
+ $newProperties[200][$currentPropertyName] = $nodeProperties[$currentPropertyName];
+ }
+ }
+
+ }
+
+ }
+
+ foreach($currentPropertyNames as $prop) {
+
+ if (isset($newProperties[200][$prop])) continue;
+
+ switch($prop) {
+ case '{DAV:}getlastmodified' : if ($node->getLastModified()) $newProperties[200][$prop] = new Sabre_DAV_Property_GetLastModified($node->getLastModified()); break;
+ case '{DAV:}getcontentlength' :
+ if ($node instanceof Sabre_DAV_IFile) {
+ $size = $node->getSize();
+ if (!is_null($size)) {
+ $newProperties[200][$prop] = (int)$node->getSize();
+ }
+ }
+ break;
+ case '{DAV:}quota-used-bytes' :
+ if ($node instanceof Sabre_DAV_IQuota) {
+ $quotaInfo = $node->getQuotaInfo();
+ $newProperties[200][$prop] = $quotaInfo[0];
+ }
+ break;
+ case '{DAV:}quota-available-bytes' :
+ if ($node instanceof Sabre_DAV_IQuota) {
+ $quotaInfo = $node->getQuotaInfo();
+ $newProperties[200][$prop] = $quotaInfo[1];
+ }
+ break;
+ case '{DAV:}getetag' : if ($node instanceof Sabre_DAV_IFile && $etag = $node->getETag()) $newProperties[200][$prop] = $etag; break;
+ case '{DAV:}getcontenttype' : if ($node instanceof Sabre_DAV_IFile && $ct = $node->getContentType()) $newProperties[200][$prop] = $ct; break;
+ case '{DAV:}supported-report-set' :
+ $reports = array();
+ foreach($this->plugins as $plugin) {
+ $reports = array_merge($reports, $plugin->getSupportedReportSet($myPath));
+ }
+ $newProperties[200][$prop] = new Sabre_DAV_Property_SupportedReportSet($reports);
+ break;
+ case '{DAV:}resourcetype' :
+ $newProperties[200]['{DAV:}resourcetype'] = new Sabre_DAV_Property_ResourceType();
+ foreach($this->resourceTypeMapping as $className => $resourceType) {
+ if ($node instanceof $className) $newProperties[200]['{DAV:}resourcetype']->add($resourceType);
+ }
+ break;
+
+ }
+
+ // If we were unable to find the property, we will list it as 404.
+ if (!$allProperties && !isset($newProperties[200][$prop])) $newProperties[404][$prop] = null;
+
+ }
+
+ $this->broadcastEvent('afterGetProperties',array(trim($myPath,'/'),&$newProperties, $node));
+
+ $newProperties['href'] = trim($myPath,'/');
+
+ // Its is a WebDAV recommendation to add a trailing slash to collectionnames.
+ // Apple's iCal also requires a trailing slash for principals (rfc 3744), though this is non-standard.
+ if ($myPath!='' && isset($newProperties[200]['{DAV:}resourcetype'])) {
+ $rt = $newProperties[200]['{DAV:}resourcetype'];
+ if ($rt->is('{DAV:}collection') || $rt->is('{DAV:}principal')) {
+ $newProperties['href'] .='/';
+ }
+ }
+
+ // If the resourcetype property was manually added to the requested property list,
+ // we will remove it again.
+ if ($removeRT) unset($newProperties[200]['{DAV:}resourcetype']);
+
+ $returnPropertyList[] = $newProperties;
+
+ }
+
+ return $returnPropertyList;
+
+ }
+}
diff --git a/lib/private/davclient.php b/lib/private/davclient.php
new file mode 100644
index 00000000000..28f48f3b921
--- /dev/null
+++ b/lib/private/davclient.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Vincent Petry
+ * @copyright 2013 Vincent Petry <pvince81@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/>.
+ *
+ */
+
+/**
+ * This class extends the SabreDAV client with additional functionality
+ * like request timeout.
+ */
+
+class OC_DAVClient extends \Sabre_DAV_Client {
+
+ protected $requestTimeout;
+
+ /**
+ * @brief Sets the request timeout or 0 to disable timeout.
+ * @param int timeout in seconds or 0 to disable
+ */
+ public function setRequestTimeout($timeout) {
+ $this->requestTimeout = (int)$timeout;
+ }
+
+ protected function curlRequest($url, $settings) {
+ if ($this->requestTimeout > 0) {
+ $settings[CURLOPT_TIMEOUT] = $this->requestTimeout;
+ }
+ return parent::curlRequest($url, $settings);
+ }
+}
diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php
index 2d3193a148a..2581969dbd0 100644
--- a/lib/private/db/connection.php
+++ b/lib/private/db/connection.php
@@ -12,7 +12,7 @@ use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\Common\EventManager;
-class Connection extends \Doctrine\DBAL\Connection implements \OCP\IDBConnection {
+class Connection extends \Doctrine\DBAL\Connection {
/**
* @var string $tablePrefix
*/
diff --git a/lib/private/db/connectionwrapper.php b/lib/private/db/connectionwrapper.php
new file mode 100644
index 00000000000..93d4fb57f74
--- /dev/null
+++ b/lib/private/db/connectionwrapper.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright (c) 2013 Thomas Müller <deepdiver@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\DB;
+
+
+class ConnectionWrapper implements \OCP\IDBConnection {
+
+ private $connection;
+
+ public function __construct(Connection $conn) {
+ $this->connection = $conn;
+ }
+
+ /**
+ * Used to the owncloud database access away
+ * @param string $sql the sql query with ? placeholder for params
+ * @param int $limit the maximum number of rows
+ * @param int $offset from which row we want to start
+ * @return \Doctrine\DBAL\Driver\Statement The prepared statement.
+ */
+ public function prepare($sql, $limit = null, $offset = null)
+ {
+ return $this->connection->prepare($sql, $limit, $offset);
+ }
+
+ /**
+ * Used to get the id of the just inserted element
+ * @param string $tableName the name of the table where we inserted the item
+ * @return int the id of the inserted element
+ */
+ public function lastInsertId($table = null)
+ {
+ return $this->connection->lastInsertId($table);
+ }
+
+ /**
+ * Insert a row if a matching row doesn't exists.
+ * @param string The table name (will replace *PREFIX*) to perform the replace on.
+ * @param array
+ *
+ * The input array if in the form:
+ *
+ * array ( 'id' => array ( 'value' => 6,
+ * 'key' => true
+ * ),
+ * 'name' => array ('value' => 'Stoyan'),
+ * 'family' => array ('value' => 'Stefanov'),
+ * 'birth_date' => array ('value' => '1975-06-20')
+ * );
+ * @return bool
+ *
+ */
+ public function insertIfNotExist($table, $input)
+ {
+ return $this->connection->insertIfNotExist($table, $input);
+ }
+
+ /**
+ * Start a transaction
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function beginTransaction()
+ {
+ return $this->connection->beginTransaction();
+ }
+
+ /**
+ * Commit the database changes done during a transaction that is in progress
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function commit()
+ {
+ return $this->connection->commit();
+ }
+
+ /**
+ * Rollback the database changes done during a transaction that is in progress
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function rollBack()
+ {
+ return $this->connection->rollBack();
+ }
+
+ /**
+ * Gets the error code and message as a string for logging
+ * @return string
+ */
+ public function getError()
+ {
+ return $this->connection->getError();
+ }
+}
diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php
index fc13e881bff..416e2f55426 100644
--- a/lib/private/db/mdb2schemamanager.php
+++ b/lib/private/db/mdb2schemamanager.php
@@ -61,6 +61,7 @@ class MDB2SchemaManager {
$toSchema = $schemaReader->loadSchemaFromFile($file);
// remove tables we don't know about
+ /** @var $table \Doctrine\DBAL\Schema\Table */
foreach($fromSchema->getTables() as $table) {
if (!$toSchema->hasTable($table->getName())) {
$fromSchema->dropTable($table->getName());
@@ -77,11 +78,10 @@ class MDB2SchemaManager {
$schemaDiff = $comparator->compare($fromSchema, $toSchema);
$platform = $this->conn->getDatabasePlatform();
- $tables = $schemaDiff->newTables + $schemaDiff->changedTables + $schemaDiff->removedTables;
- foreach($tables as $tableDiff) {
+ foreach($schemaDiff->changedTables as $tableDiff) {
$tableDiff->name = $platform->quoteIdentifier($tableDiff->name);
}
-
+
if ($generateSql) {
return $this->generateChangeScript($schemaDiff);
}
@@ -110,6 +110,7 @@ class MDB2SchemaManager {
$schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
$fromSchema = $schemaReader->loadSchemaFromFile($file);
$toSchema = clone $fromSchema;
+ /** @var $table \Doctrine\DBAL\Schema\Table */
foreach($toSchema->getTables() as $table) {
$toSchema->dropTable($table->getName());
}
diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php
index 364a50d377c..fc2d965d7f9 100644
--- a/lib/private/files/cache/cache.php
+++ b/lib/private/files/cache/cache.php
@@ -69,9 +69,15 @@ class Cache {
}
if (!isset(self::$mimetypeIds[$mime])) {
- $result = \OC_DB::executeAudited('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)', array($mime));
- self::$mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes');
- self::$mimetypes[self::$mimetypeIds[$mime]] = $mime;
+ try{
+ $result = \OC_DB::executeAudited('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)', array($mime));
+ self::$mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes');
+ self::$mimetypes[self::$mimetypeIds[$mime]] = $mime;
+ }
+ catch (\Doctrine\DBAL\DBALException $e){
+ \OC_Log::write('core', 'Exception during mimetype insertion: ' . $e->getmessage(), \OC_Log::DEBUG);
+ return -1;
+ }
}
return self::$mimetypeIds[$mime];
@@ -84,8 +90,8 @@ class Cache {
return isset(self::$mimetypes[$id]) ? self::$mimetypes[$id] : null;
}
-
- protected function loadMimetypes(){
+
+ public function loadMimetypes(){
$result = \OC_DB::executeAudited('SELECT `id`, `mimetype` FROM `*PREFIX*mimetypes`', array());
if ($result) {
while ($row = $result->fetchRow()) {
diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php
index 96f84609cf2..f63abf2d4fc 100644
--- a/lib/private/files/cache/scanner.php
+++ b/lib/private/files/cache/scanner.php
@@ -190,24 +190,34 @@ class Scanner extends BasicEmitter {
}
$newChildren = array();
if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) {
+ $exceptionOccurred = false;
\OC_DB::beginTransaction();
if (is_resource($dh)) {
while (($file = readdir($dh)) !== false) {
$child = ($path) ? $path . '/' . $file : $file;
if (!Filesystem::isIgnoredDir($file)) {
$newChildren[] = $file;
- $data = $this->scanFile($child, $reuse, true);
- if ($data) {
- if ($data['size'] === -1) {
- if ($recursive === self::SCAN_RECURSIVE) {
- $childQueue[] = $child;
- } else {
- $size = -1;
+ try {
+ $data = $this->scanFile($child, $reuse, true);
+ if ($data) {
+ if ($data['size'] === -1) {
+ if ($recursive === self::SCAN_RECURSIVE) {
+ $childQueue[] = $child;
+ } else {
+ $size = -1;
+ }
+ } else if ($size !== -1) {
+ $size += $data['size'];
}
- } else if ($size !== -1) {
- $size += $data['size'];
}
}
+ catch (\Doctrine\DBAL\DBALException $ex){
+ // might happen if inserting duplicate while a scanning
+ // process is running in parallel
+ // log and ignore
+ \OC_Log::write('core', 'Exception while scanning file "' . $child . '": ' . $ex->getMessage(), \OC_Log::DEBUG);
+ $exceptionOccurred = true;
+ }
}
}
}
@@ -217,6 +227,14 @@ class Scanner extends BasicEmitter {
$this->cache->remove($child);
}
\OC_DB::commit();
+ if ($exceptionOccurred){
+ // It might happen that the parallel scan process has already
+ // inserted mimetypes but those weren't available yet inside the transaction
+ // To make sure to have the updated mime types in such cases,
+ // we reload them here
+ $this->cache->loadMimetypes();
+ }
+
foreach ($childQueue as $child) {
$childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse);
if ($childSize === -1) {
diff --git a/lib/private/group.php b/lib/private/group.php
index 9144ef683b6..444788c97f1 100644
--- a/lib/private/group.php
+++ b/lib/private/group.php
@@ -268,7 +268,7 @@ class OC_Group {
$users = $group->searchDisplayName($search, $limit, $offset);
$displayNames = array();
foreach ($users as $user) {
- $displayNames[] = $user->getDisplayName();
+ $displayNames[$user->getUID()] = $user->getDisplayName();
}
return $displayNames;
} else {
diff --git a/lib/private/helper.php b/lib/private/helper.php
index e9b129db0ca..fca08adca8b 100644
--- a/lib/private/helper.php
+++ b/lib/private/helper.php
@@ -59,6 +59,15 @@ class OC_Helper {
}
/**
+ * @param $key
+ * @return string url to the online documentation
+ */
+ public static function linkToDocs($key) {
+ $theme = new OC_Defaults();
+ return $theme->getDocBaseUrl() . '/server/5.0/go.php?to=' . $key;
+ }
+
+ /**
* @brief Creates an absolute url
* @param string $app app
* @param string $file file
diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php
index a408e3830d6..15cace88f41 100644
--- a/lib/private/log/owncloud.php
+++ b/lib/private/log/owncloud.php
@@ -35,7 +35,17 @@ class OC_Log_Owncloud {
public static function init() {
$defaultLogFile = OC_Config::getValue("datadirectory", OC::$SERVERROOT.'/data').'/owncloud.log';
self::$logFile = OC_Config::getValue("logfile", $defaultLogFile);
- if (!file_exists(self::$logFile)) {
+
+ /*
+ * Fall back to default log file if specified logfile does not exist
+ * and can not be created. Error suppression is required in order to
+ * not end up in the error handler which will try to log the error.
+ * A better solution (compared to error suppression) would be checking
+ * !is_writable(dirname(self::$logFile)) before touch(), but
+ * is_writable() on directories used to be pretty unreliable on Windows
+ * for at least some time.
+ */
+ if (!file_exists(self::$logFile) && !@touch(self::$logFile)) {
self::$logFile = $defaultLogFile;
}
}
@@ -61,6 +71,7 @@ class OC_Log_Owncloud {
$entry=array('app'=>$app, 'message'=>$message, 'level'=>$level, 'time'=> $time->format($format));
$entry = json_encode($entry);
$handle = @fopen(self::$logFile, 'a');
+ @chmod(self::$logFile, 0640);
if ($handle) {
fwrite($handle, $entry."\n");
fclose($handle);
diff --git a/lib/private/ocs/cloud.php b/lib/private/ocs/cloud.php
index 2dd99319057..cbbf3b626f5 100644
--- a/lib/private/ocs/cloud.php
+++ b/lib/private/ocs/cloud.php
@@ -64,8 +64,7 @@ class OC_OCS_Cloud {
// Check if they are viewing information on themselves
if($parameters['userid'] === OC_User::getUser()) {
// Self lookup
- $quota = array();
- $storage = OC_Helper::getStorageInfo();
+ $storage = OC_Helper::getStorageInfo('/');
$quota = array(
'free' => $storage['free'],
'used' => $storage['used'],
@@ -79,6 +78,16 @@ class OC_OCS_Cloud {
}
}
+ public static function getCurrentUser() {
+ $email=OC_Preferences::getValue(OC_User::getUser(), 'settings', 'email', '');
+ $data = array(
+ 'id' => OC_User::getUser(),
+ 'display-name' => OC_User::getDisplayName(),
+ 'email' => $email,
+ );
+ return new OC_OCS_Result($data);
+ }
+
public static function getUserPublickey($parameters) {
if(OC_User::userExists($parameters['user'])) {
diff --git a/lib/private/preview/movies.php b/lib/private/preview/movies.php
index dc50d160346..4d85e23c63c 100644
--- a/lib/private/preview/movies.php
+++ b/lib/private/preview/movies.php
@@ -11,7 +11,7 @@ namespace OC\Preview;
// movie preview is currently not supported on Windows
if (!\OC_Util::runningOnWindows()) {
$isShellExecEnabled = !in_array('shell_exec', explode(', ', ini_get('disable_functions')));
- $whichAVCONV = shell_exec('which avconv');
+ $whichAVCONV = ($isShellExecEnabled ? shell_exec('which avconv') : '');
$isAVCONVAvailable = !empty($whichAVCONV);
if($isShellExecEnabled && $isAVCONVAvailable) {
diff --git a/lib/private/preview/office.php b/lib/private/preview/office.php
index 673b16edc19..318ab51f851 100644
--- a/lib/private/preview/office.php
+++ b/lib/private/preview/office.php
@@ -9,11 +9,11 @@
if (extension_loaded('imagick')) {
$isShellExecEnabled = !in_array('shell_exec', explode(', ', ini_get('disable_functions')));
- // movie preview is currently not supported on Windows
+ // LibreOffice preview is currently not supported on Windows
if (!\OC_Util::runningOnWindows()) {
- $whichLibreOffice = shell_exec('which libreoffice');
+ $whichLibreOffice = ($isShellExecEnabled ? shell_exec('which libreoffice') : '');
$isLibreOfficeAvailable = !empty($whichLibreOffice);
- $whichOpenOffice = shell_exec('which libreoffice');
+ $whichOpenOffice = ($isShellExecEnabled ? shell_exec('which libreoffice') : '');
$isOpenOfficeAvailable = !empty($whichOpenOffice);
//let's see if there is libreoffice or openoffice on this machine
if($isShellExecEnabled && ($isLibreOfficeAvailable || $isOpenOfficeAvailable || is_string(\OC_Config::getValue('preview_libreoffice_path', null)))) {
diff --git a/lib/private/server.php b/lib/private/server.php
index e55f59f6a1c..65899f3007e 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -5,6 +5,7 @@ namespace OC;
use OC\AppFramework\Http\Request;
use OC\AppFramework\Utility\SimpleContainer;
use OC\Cache\UserCache;
+use OC\DB\ConnectionWrapper;
use OC\Files\Node\Root;
use OC\Files\View;
use OCP\IServerContainer;
@@ -127,6 +128,9 @@ class Server extends SimpleContainer implements IServerContainer {
$this->registerService('UserCache', function($c) {
return new UserCache();
});
+ $this->registerService('ActivityManager', function($c) {
+ return new ActivityManager();
+ });
}
/**
@@ -286,7 +290,15 @@ class Server extends SimpleContainer implements IServerContainer {
* @return \OCP\IDBConnection
*/
function getDatabaseConnection() {
- return \OC_DB::getConnection();
+ return new ConnectionWrapper(\OC_DB::getConnection());
}
+ /**
+ * Returns the activity manager
+ *
+ * @return \OCP\Activity\IManager
+ */
+ function getActivityManager() {
+ return $this->query('ActivityManager');
+ }
}
diff --git a/lib/private/setup.php b/lib/private/setup.php
index 6bf3c88370f..3cc1d29c6a4 100644
--- a/lib/private/setup.php
+++ b/lib/private/setup.php
@@ -183,7 +183,7 @@ class OC_Setup {
$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');
+ link_to_docs('admin-install'));
OC_Template::printErrorPage($error, $hint);
exit();
diff --git a/lib/private/template/functions.php b/lib/private/template/functions.php
index 0aa2b27b96b..ce42633b364 100644
--- a/lib/private/template/functions.php
+++ b/lib/private/template/functions.php
@@ -36,6 +36,14 @@ function link_to( $app, $file, $args = array() ) {
}
/**
+ * @param $key
+ * @return string url to the online documentation
+ */
+function link_to_docs($key) {
+ return OC_Helper::linkToDocs($key);
+}
+
+/**
* @brief make OC_Helper::imagePath available as a simple function
* @param string $app app
* @param string $image image
diff --git a/lib/private/util.php b/lib/private/util.php
index 6c0a8d7bab5..f63884c0f32 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -303,16 +303,16 @@ class OC_Util {
//common hint for all file permissions error messages
$permissionsHint = 'Permissions can usually be fixed by '
- .'<a href="' . $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html'
- .'#set-the-directory-permissions" target="_blank">giving the webserver write access to the root directory</a>.';
+ .'<a href="' . OC_Helper::linkToDocs('admin-dir_permissions')
+ .'" target="_blank">giving the webserver write access to the root directory</a>.';
// 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",
'hint' => 'This can usually be fixed by '
- .'<a href="' . $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html'
- .'#set-the-directory-permissions" target="_blank">giving the webserver write access to the config directory</a>.'
+ .'<a href="' . OC_Helper::linkToDocs('admin-dir_permissions')
+ .'" target="_blank">giving the webserver write access to the config directory</a>.'
);
}
@@ -324,8 +324,8 @@ class OC_Util {
$errors[] = array(
'error' => "Can't write into apps directory",
'hint' => 'This can usually be fixed by '
- .'<a href="' . $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html'
- .'#set-the-directory-permissions" target="_blank">giving the webserver write access to the apps directory</a> '
+ .'<a href="' . OC_Helper::linkToDocs('admin-dir_permissions')
+ .'" target="_blank">giving the webserver write access to the apps directory</a> '
.'or disabling the appstore in the config file.'
);
}
@@ -340,8 +340,8 @@ class OC_Util {
$errors[] = array(
'error' => "Can't create data directory (".$CONFIG_DATADIRECTORY.")",
'hint' => 'This can usually be fixed by '
- .'<a href="' . $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html'
- .'#set-the-directory-permissions" target="_blank">giving the webserver write access to the root directory</a>.'
+ .'<a href="' . OC_Helper::linkToDocs('admin-dir_permissions')
+ .'" target="_blank">giving the webserver write access to the root directory</a>.'
);
}
} else if(!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
@@ -754,6 +754,10 @@ class OC_Util {
* file in the data directory and trying to access via http
*/
public static function isHtAccessWorking() {
+ if (!\OC_Config::getValue("check_for_working_htaccess", true)) {
+ return true;
+ }
+
// testdata
$fileName = '/htaccesstest.txt';
$testContent = 'testcontent';
@@ -802,11 +806,16 @@ class OC_Util {
if (!function_exists('curl_init')) {
return true;
}
+ if (!\OC_Config::getValue("check_for_working_webdav", true)) {
+ return true;
+ }
$settings = array(
'baseUri' => OC_Helper::linkToRemote('webdav'),
);
- $client = new \Sabre_DAV_Client($settings);
+ $client = new \OC_DAVClient($settings);
+
+ $client->setRequestTimeout(10);
// for this self test we don't care if the ssl certificate is self signed and the peer cannot be verified.
$client->setVerifyPeer(false);