aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSimon Birnbach <simon@simon-birnbach.de>2012-04-15 15:59:57 +0200
committerSimon Birnbach <simon@simon-birnbach.de>2012-04-15 15:59:57 +0200
commita384fcb99fc3a12d7dac937398bf827c79e86098 (patch)
tree55a631751578cd1f642e5fa0f88fd2290509b126 /lib
parent4e89a0faf652f2f100cca47cca54a3b35e720aad (diff)
parent38cb716a572a8af136f6260089bc486413c6ca9f (diff)
downloadnextcloud-server-a384fcb99fc3a12d7dac937398bf827c79e86098.tar.gz
nextcloud-server-a384fcb99fc3a12d7dac937398bf827c79e86098.zip
Merge git://gitorious.org/owncloud/owncloud
Conflicts: files/css/files.css files/js/files.js
Diffstat (limited to 'lib')
-rwxr-xr-x[-rw-r--r--]lib/app.php164
-rw-r--r--lib/appconfig.php34
-rw-r--r--lib/base.php137
-rw-r--r--lib/connect.php40
-rw-r--r--lib/db.php70
-rw-r--r--lib/eventsource.php3
-rw-r--r--lib/filecache.php87
-rw-r--r--lib/files.php132
-rw-r--r--lib/filestorage/common.php12
-rw-r--r--lib/filestorage/google.php341
-rw-r--r--lib/filestorage/local.php4
-rw-r--r--lib/filesystem.php21
-rw-r--r--lib/filesystemview.php32
-rw-r--r--lib/group.php161
-rw-r--r--lib/group/backend.php119
-rw-r--r--lib/group/database.php4
-rw-r--r--lib/group/dummy.php159
-rw-r--r--lib/group/example.php102
-rwxr-xr-x[-rw-r--r--]lib/helper.php97
-rw-r--r--lib/image.php38
-rw-r--r--lib/installer.php43
-rw-r--r--lib/json.php6
-rw-r--r--lib/l10n.php33
-rw-r--r--lib/log.php71
-rw-r--r--lib/log/owncloud.php79
-rw-r--r--lib/log/syslog.php37
-rw-r--r--lib/migrate.php715
-rw-r--r--lib/migration/content.php252
-rw-r--r--lib/migration/provider.php52
-rw-r--r--lib/mimetypes.fixlist.php9
-rw-r--r--lib/mimetypes.list.php2
-rwxr-xr-x[-rw-r--r--]lib/ocsclient.php52
-rw-r--r--lib/remote/cloud.php204
-rw-r--r--lib/search.php30
-rw-r--r--lib/search/provider.php6
-rw-r--r--lib/search/provider/file.php4
-rw-r--r--lib/template.php257
-rw-r--r--lib/updater.php5
-rw-r--r--lib/user.php6
-rw-r--r--lib/user/database.php2
-rw-r--r--lib/user/dummy.php114
-rw-r--r--lib/util.php14
-rw-r--r--lib/vcategories.php8
43 files changed, 2627 insertions, 1131 deletions
diff --git a/lib/app.php b/lib/app.php
index f841180ebad..bd432109b23 100644..100755
--- a/lib/app.php
+++ b/lib/app.php
@@ -34,16 +34,21 @@ class OC_App{
static private $settingsForms = array();
static private $adminForms = array();
static private $personalForms = array();
+ static private $appInfo = array();
+ static private $appTypes = array();
/**
* @brief loads all apps
+ * @param array $types
* @returns true/false
*
* This function walks through the owncloud directory and loads all apps
* it can find. A directory contains an app if the file /appinfo/app.php
* exists.
+ *
+ * if $types is set, only apps of those types will be loaded
*/
- public static function loadApps(){
+ public static function loadApps($types=null){
// Did we allready load everything?
if( self::$init ){
return true;
@@ -51,13 +56,15 @@ class OC_App{
// Our very own core apps are hardcoded
foreach( array('files', 'settings') as $app ){
- require( $app.'/appinfo/app.php' );
+ if(is_null($types)){
+ require( $app.'/appinfo/app.php' );
+ }
}
// The rest comes here
- $apps = OC_Appconfig::getApps();
+ $apps = self::getEnabledApps();
foreach( $apps as $app ){
- if( self::isEnabled( $app )){
+ if(is_null($types) or self::isType($app,$types)){
if(is_file(OC::$APPSROOT.'/apps/'.$app.'/appinfo/app.php')){
require( $app.'/appinfo/app.php' );
}
@@ -71,6 +78,63 @@ class OC_App{
}
/**
+ * check if an app is of a sepcific type
+ * @param string $app
+ * @param string/array $types
+ */
+ public static function isType($app,$types){
+ if(is_string($types)){
+ $types=array($types);
+ }
+ $appTypes=self::getAppTypes($app);
+ foreach($types as $type){
+ if(array_search($type,$appTypes)!==false){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * get the types of an app
+ * @param string $app
+ * @return array
+ */
+ private static function getAppTypes($app){
+ //load the cache
+ if(count(self::$appTypes)==0){
+ self::$appTypes=OC_Appconfig::getValues(false,'types');
+ }
+
+ //get it from info.xml if we haven't cached it
+ if(!isset(self::$appTypes[$app])){
+ $appData=self::getAppInfo($app);
+ if(isset($appData['types'])){
+ self::$appTypes[$app]=$appData['types'];
+ }else{
+ self::$appTypes[$app]=array();
+ }
+
+ OC_Appconfig::setValue($app,'types',implode(',',self::$appTypes[$app]));
+ }
+
+ return explode(',',self::$appTypes[$app]);
+ }
+
+ /**
+ * get all enabled apps
+ */
+ public static function getEnabledApps(){
+ $apps=array();
+ $query = OC_DB::prepare( 'SELECT appid FROM *PREFIX*appconfig WHERE configkey = \'enabled\' AND configvalue=\'yes\'' );
+ $result=$query->execute();
+ while($row=$result->fetchRow()){
+ $apps[]=$row['appid'];
+ }
+ return $apps;
+ }
+
+ /**
* @brief checks whether or not an app is enabled
* @param $app app
* @returns true/false
@@ -98,13 +162,18 @@ class OC_App{
if(!is_numeric($app)){
OC_Installer::installShippedApp($app);
}else{
- $download=OC_OCSClient::getApplicationDownload($app,1);
- if(isset($download['downloadlink']) and $download['downloadlink']<>'') {
+ $download=OC_OCSClient::getApplicationDownload($app,1);
+ if(isset($download['downloadlink']) and $download['downloadlink']!='') {
$app=OC_Installer::installApp(array('source'=>'http','href'=>$download['downloadlink']));
}
}
}
- OC_Appconfig::setValue( $app, 'enabled', 'yes' );
+ if($app!==false){
+ OC_Appconfig::setValue( $app, 'enabled', 'yes' );
+ return true;
+ }else{
+ return false;
+ }
}
/**
@@ -208,12 +277,15 @@ class OC_App{
* entries are sorted by the key 'order' ascending.
*/
public static function getSettingsNavigation(){
- $l=new OC_L10N('core');
+ $l=OC_L10N::get('core');
+ $settings = array();
// by default, settings only contain the help menu
- $settings = array(
- array( "id" => "help", "order" => 1000, "href" => OC_Helper::linkTo( "settings", "help.php" ), "name" => $l->t("Help"), "icon" => OC_Helper::imagePath( "settings", "help.svg" ))
- );
+ if(OC_Config::getValue('knowledgebaseenabled', true)==true){
+ $settings = array(
+ array( "id" => "help", "order" => 1000, "href" => OC_Helper::linkTo( "settings", "help.php" ), "name" => $l->t("Help"), "icon" => OC_Helper::imagePath( "settings", "help.svg" ))
+ );
+ }
// if the user is logged-in
if (OC_User::isLoggedIn()) {
@@ -258,28 +330,54 @@ class OC_App{
return $list;
}
+
+ /**
+ * get the last version of the app, either from appinfo/version or from appinfo/info.xml
+ */
+ public static function getAppVersion($appid){
+ $file=OC::$APPSROOT.'/apps/'.$appid.'/appinfo/version';
+ $version=@file_get_contents($file);
+ if($version){
+ return $version;
+ }else{
+ $appData=self::getAppInfo($appid);
+ return $appData['version'];
+ }
+ }
/**
* @brief Read app metadata from the info.xml file
* @param string $appid id of the app or the path of the info.xml file
+ * @param boolean path (optional)
* @returns array
*/
- public static function getAppInfo($appid){
- if(is_file($appid)){
+ public static function getAppInfo($appid,$path=false){
+ if($path){
$file=$appid;
}else{
- $file=OC::$APPSROOT.'/apps/'.$appid.'/appinfo/info.xml';
- if(!is_file($file)){
- return array();
+ if(isset(self::$appInfo[$appid])){
+ return self::$appInfo[$appid];
}
+ $file=OC::$APPSROOT.'/apps/'.$appid.'/appinfo/info.xml';
}
$data=array();
- $content=file_get_contents($file);
+ $content=@file_get_contents($file);
+ if(!$content){
+ return;
+ }
$xml = new SimpleXMLElement($content);
$data['info']=array();
foreach($xml->children() as $child){
- $data[$child->getName()]=(string)$child;
+ if($child->getName()=='types'){
+ $data['types']=array();
+ foreach($child->children() as $type){
+ $data['types'][]=$type->getName();
+ }
+ }else{
+ $data[$child->getName()]=(string)$child;
+ }
}
+ self::$appInfo[$appid]=$data;
return $data;
}
@@ -325,6 +423,7 @@ class OC_App{
$source=self::$settingsForms;
break;
case 'admin':
+ $forms[] = include 'files/admin.php'; //hardcode own apps
$source=self::$adminForms;
break;
case 'personal':
@@ -371,26 +470,37 @@ class OC_App{
}
return $apps;
}
-
+
/**
* check if any apps need updating and update those
*/
public static function updateApps(){
// The rest comes here
- $apps = OC_Appconfig::getApps();
- foreach( $apps as $app ){
- $installedVersion=OC_Appconfig::getValue($app,'installed_version');
- $appInfo=OC_App::getAppInfo($app);
- if (isset($appInfo['version'])) {
- $currentVersion=$appInfo['version'];
+ $versions = self::getAppVersions();
+ foreach( $versions as $app=>$installedVersion ){
+ $currentVersion=OC_App::getAppVersion($app);
+ if ($currentVersion) {
if (version_compare($currentVersion, $installedVersion, '>')) {
OC_App::updateApp($app);
- OC_Appconfig::setValue($app,'installed_version',$appInfo['version']);
+ OC_Appconfig::setValue($app,'installed_version',OC_App::getAppVersion($app));
}
}
}
}
-
+
+ /**
+ * get the installed version of all papps
+ */
+ public static function getAppVersions(){
+ $versions=array();
+ $query = OC_DB::prepare( 'SELECT appid, configvalue FROM *PREFIX*appconfig WHERE configkey = \'installed_version\'' );
+ $result = $query->execute();
+ while($row = $result->fetchRow()){
+ $versions[$row['appid']]=$row['configvalue'];
+ }
+ return $versions;
+ }
+
/**
* update the database for the app and call the update script
* @param string appid
diff --git a/lib/appconfig.php b/lib/appconfig.php
index 2b5cef59adc..5aaaadd9c4a 100644
--- a/lib/appconfig.php
+++ b/lib/appconfig.php
@@ -163,4 +163,38 @@ class OC_Appconfig{
return true;
}
+
+ /**
+ * get multiply values, either the app or key can be used as wildcard by setting it to false
+ * @param app
+ * @param key
+ * @return array
+ */
+ public static function getValues($app,$key){
+ if($app!==false and $key!==false){
+ return false;
+ }
+ $where='WHERE';
+ $fields='configvalue';
+ $params=array();
+ if($app!==false){
+ $where.=' appid = ?';
+ $fields.=', configkey';
+ $params[]=$app;
+ $key='configkey';
+ }else{
+ $fields.=', appid';
+ $where.=' configkey = ?';
+ $params[]=$key;
+ $key='appid';
+ }
+ $queryString='SELECT '.$fields.' FROM *PREFIX*appconfig '.$where;
+ $query=OC_DB::prepare($queryString);
+ $result=$query->execute($params);
+ $values=array();
+ while($row=$result->fetchRow()){
+ $values[$row[$key]]=$row['configvalue'];
+ }
+ return $values;
+ }
}
diff --git a/lib/base.php b/lib/base.php
index 9995544f14e..f3dacdc0f76 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -114,42 +114,7 @@ class OC{
return($mode);
}
- public static function init(){
- // register autoloader
- spl_autoload_register(array('OC','autoload'));
-
- // set some stuff
- //ob_start();
- error_reporting(E_ALL | E_STRICT);
- if (defined('DEBUG') && DEBUG){
- ini_set('display_errors', 1);
- }
-
- date_default_timezone_set('Europe/Berlin');
- ini_set('arg_separator.output','&amp;');
-
- //set http auth headers for apache+php-cgi work around
- if (isset($_SERVER['HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches))
- {
- list($name, $password) = explode(':', base64_decode($matches[1]));
- $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
- $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
- }
-
- //set http auth headers for apache+php-cgi work around if variable gets renamed by apache
- if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['REDIRECT_HTTP_AUTHORIZATION'], $matches))
- {
- list($name, $password) = explode(':', base64_decode($matches[1]));
- $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
- $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
- }
-
- // register the stream wrappers
- require_once('streamwrappers.php');
- stream_wrapper_register("fakedir", "OC_FakeDirStream");
- stream_wrapper_register('static', 'OC_StaticStreamWrapper');
- stream_wrapper_register('close', 'OC_CloseStreamWrapper');
-
+ public static function initPaths(){
// calculate the documentroot
OC::$DOCUMENTROOT=realpath($_SERVER['DOCUMENT_ROOT']);
OC::$SERVERROOT=str_replace("\\",'/',substr(__FILE__,0,-13));
@@ -174,6 +139,12 @@ class OC{
OC::$WEBROOT='/'.OC::$WEBROOT;
}
+ // ensure we can find OC_Config
+ set_include_path(
+ OC::$SERVERROOT.'/lib'.PATH_SEPARATOR.
+ get_include_path()
+ );
+
// search the 3rdparty folder
if(OC_Config::getValue('3rdpartyroot', '')<>'' and OC_Config::getValue('3rdpartyurl', '')<>''){
OC::$THIRDPARTYROOT=OC_Config::getValue('3rdpartyroot', '');
@@ -211,14 +182,18 @@ class OC{
get_include_path().PATH_SEPARATOR.
OC::$SERVERROOT
);
+ }
+ public static function checkInstalled() {
// Redirect to installer if not installed
if (!OC_Config::getValue('installed', false) && OC::$SUBURI != '/index.php') {
$url = 'http://'.$_SERVER['SERVER_NAME'].OC::$WEBROOT.'/index.php';
header("Location: $url");
exit();
}
+ }
+ public static function checkSSL() {
// redirect to https site if configured
if( OC_Config::getValue( "forcessl", false )){
ini_set("session.cookie_secure", "on");
@@ -228,7 +203,9 @@ class OC{
exit();
}
}
+ }
+ public static function checkUpgrade() {
if(OC_Config::getValue('installed', false)){
$installedVersion=OC_Config::getValue('version','0.0.0');
$currentVersion=implode('.',OC_Util::getVersion());
@@ -250,10 +227,9 @@ class OC{
OC_App::updateApps();
}
+ }
- ini_set('session.cookie_httponly','1;');
- session_start();
-
+ public static function initTemplateEngine() {
// if the formfactor is not yet autodetected do the autodetection now. For possible forfactors check the detectFormfactor documentation
if(!isset($_SESSION['formfactor'])){
$_SESSION['formfactor']=OC::detectFormfactor();
@@ -263,7 +239,6 @@ class OC{
$_SESSION['formfactor']=$_GET['formfactor'];
}
-
// Add the stuff we need always
OC_Util::addScript( "jquery-1.6.4.min" );
OC_Util::addScript( "jquery-ui-1.8.16.custom.min" );
@@ -280,6 +255,76 @@ class OC{
OC_Util::addStyle( "multiselect" );
OC_Util::addStyle( "jquery-ui-1.8.16.custom" );
OC_Util::addStyle( "jquery-tipsy" );
+ }
+
+ public static function initSession() {
+ ini_set('session.cookie_httponly','1;');
+ session_start();
+ }
+
+ public static function init(){
+ // register autoloader
+ spl_autoload_register(array('OC','autoload'));
+ setlocale(LC_ALL, 'en_US.UTF-8');
+
+ // set some stuff
+ //ob_start();
+ error_reporting(E_ALL | E_STRICT);
+ if (defined('DEBUG') && DEBUG){
+ ini_set('display_errors', 1);
+ }
+
+ date_default_timezone_set('Europe/Berlin');
+ ini_set('arg_separator.output','&amp;');
+
+ //try to configure php to enable big file uploads.
+ //this doesn´t work always depending on the webserver and php configuration.
+ //Let´s try to overwrite some defaults anyways
+
+ //try to set the maximum execution time to 60min
+ @set_time_limit(3600);
+ @ini_set('max_execution_time',3600);
+ @ini_set('max_input_time',3600);
+
+ //try to set the maximum filesize to 10G
+ @ini_set('upload_max_filesize','10G');
+ @ini_set('post_max_size','10G');
+ @ini_set('file_uploads','50');
+
+ //try to set the session lifetime to 60min
+ @ini_set('gc_maxlifetime','3600');
+
+
+ //set http auth headers for apache+php-cgi work around
+ if (isset($_SERVER['HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches))
+ {
+ list($name, $password) = explode(':', base64_decode($matches[1]));
+ $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
+ $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
+ }
+
+ //set http auth headers for apache+php-cgi work around if variable gets renamed by apache
+ if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['REDIRECT_HTTP_AUTHORIZATION'], $matches))
+ {
+ list($name, $password) = explode(':', base64_decode($matches[1]));
+ $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
+ $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
+ }
+
+ self::initPaths();
+
+ // register the stream wrappers
+ require_once('streamwrappers.php');
+ stream_wrapper_register("fakedir", "OC_FakeDirStream");
+ stream_wrapper_register('static', 'OC_StaticStreamWrapper');
+ stream_wrapper_register('close', 'OC_CloseStreamWrapper');
+
+ self::checkInstalled();
+ self::checkSSL();
+
+ self::initSession();
+ self::initTemplateEngine();
+ self::checkUpgrade();
$errors=OC_Util::checkServer();
if(count($errors)>0) {
@@ -301,7 +346,7 @@ class OC{
OC_User::useBackend( OC_Config::getValue( "userbackend", "database" ));
- OC_Group::setBackend( OC_Config::getValue( "groupbackend", "database" ));
+ OC_Group::useBackend(new OC_Group_Database());
// Set up file system unless forbidden
global $RUNTIME_NOSETUPFS;
@@ -312,9 +357,17 @@ class OC{
// Load Apps
// This includes plugins for users and filesystems as well
global $RUNTIME_NOAPPS;
+ global $RUNTIME_APPTYPES;
if(!$RUNTIME_NOAPPS ){
- OC_App::loadApps();
+ if($RUNTIME_APPTYPES){
+ OC_App::loadApps($RUNTIME_APPTYPES);
+ }else{
+ OC_App::loadApps();
+ }
}
+
+ // Check for blacklisted files
+ OC_Hook::connect('OC_Filesystem','write','OC_Filesystem','isBlacklisted');
//make sure temporary files are cleaned up
register_shutdown_function(array('OC_Helper','cleanTmp'));
diff --git a/lib/connect.php b/lib/connect.php
deleted file mode 100644
index 22e48750a62..00000000000
--- a/lib/connect.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
-* ownCloud
-*
-* @author Frank Karlitschek
-* @copyright 2010 Frank Karlitschek karlitschek@kde.org
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-/**
- * Class for connecting multiply ownCloud installations
- *
- */
-class OC_Connect{
- static private $clouds=array();
-
- static function connect($path,$user,$password){
- $cloud=new OC_REMOTE_CLOUD($path,$user,$password);
- if($cloud->connected){
- self::$clouds[$path]=$cloud;
- return $cloud;
- }else{
- return false;
- }
- }
-}
diff --git a/lib/db.php b/lib/db.php
index 9fab51edfcd..2f74cc6dd95 100644
--- a/lib/db.php
+++ b/lib/db.php
@@ -36,8 +36,26 @@ class OC_DB {
static private $affected=0;
static private $result=false;
static private $inTransaction=false;
+ static private $prefix=null;
+ static private $type=null;
/**
+ * check which backend we should use
+ * @return BACKEND_MDB2 or BACKEND_PDO
+ */
+ private static function getDBBackend(){
+ $backend=self::BACKEND_MDB2;
+ if(class_exists('PDO') && OC_Config::getValue('installed', false)){//check if we can use PDO, else use MDB2 (instalation always needs to be done my mdb2)
+ $type = OC_Config::getValue( "dbtype", "sqlite" );
+ if($type=='sqlite3') $type='sqlite';
+ $drivers=PDO::getAvailableDrivers();
+ if(array_search($type,$drivers)!==false){
+ $backend=self::BACKEND_PDO;
+ }
+ }
+ }
+
+ /**
* @brief connects to the database
* @returns true if connection can be established or nothing (die())
*
@@ -48,15 +66,7 @@ class OC_DB {
return;
}
if(is_null($backend)){
- $backend=self::BACKEND_MDB2;
- if(class_exists('PDO') && OC_Config::getValue('installed', false)){//check if we can use PDO, else use MDB2 (instalation always needs to be done my mdb2)
- $type = OC_Config::getValue( "dbtype", "sqlite" );
- if($type=='sqlite3') $type='sqlite';
- $drivers=PDO::getAvailableDrivers();
- if(array_search($type,$drivers)!==false){
- $backend=self::BACKEND_PDO;
- }
- }
+ $backend=self::getDBBackend();
}
if($backend==self::BACKEND_PDO){
self::connectPDO();
@@ -86,6 +96,7 @@ class OC_DB {
$user = OC_Config::getValue( "dbuser", "" );
$pass = OC_Config::getValue( "dbpassword", "" );
$type = OC_Config::getValue( "dbtype", "sqlite" );
+ $opts = array();
$datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
// do nothing if the connection already has been established
@@ -100,13 +111,14 @@ class OC_DB {
break;
case 'mysql':
$dsn='mysql:dbname='.$name.';host='.$host;
+ $opts[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES 'UTF8'";
break;
case 'pgsql':
$dsn='pgsql:dbname='.$name.';host='.$host;
break;
}
try{
- self::$PDO=new PDO($dsn,$user,$pass);
+ self::$PDO=new PDO($dsn,$user,$pass,$opts);
}catch(PDOException $e){
echo( '<b>can not connect to database, using '.$type.'. ('.$e->getMessage().')</center>');
die();
@@ -318,9 +330,6 @@ class OC_DB {
// Make changes and save them to an in-memory file
$file2 = 'static://db_scheme';
- if($file2 == ''){
- die('could not create tempfile in get_temp_dir() - aborting');
- }
$content = str_replace( '*dbname*', $CONFIG_DBNAME, $content );
$content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content );
if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't
@@ -424,8 +433,14 @@ class OC_DB {
private static function processQuery( $query ){
self::connect();
// We need Database type and table prefix
- $type = OC_Config::getValue( "dbtype", "sqlite" );
- $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
+ if(is_null(self::$type)){
+ self::$type=OC_Config::getValue( "dbtype", "sqlite" );
+ }
+ $type = self::$type;
+ if(is_null(self::$prefix)){
+ self::$prefix=OC_Config::getValue( "dbtableprefix", "oc_" );
+ }
+ $prefix = self::$prefix;
// differences in escaping of table names ('`' for mysql) and getting the current timestamp
if( $type == 'sqlite' || $type == 'sqlite3' ){
@@ -486,6 +501,30 @@ class OC_DB {
}
/**
+ * @brief replaces the owncloud tables with a new set
+ * @param $file string path to the MDB2 xml db export file
+ */
+ public static function replaceDB( $file ){
+
+ $apps = OC_App::getAllApps();
+ self::beginTransaction();
+ // Delete the old tables
+ self::removeDBStructure( OC::$SERVERROOT . '/db_structure.xml' );
+
+ foreach($apps as $app){
+ $path = OC::$SERVERROOT.'/apps/'.$app.'/appinfo/database.xml';
+ if(file_exists($path)){
+ self::removeDBStructure( $path );
+ }
+ }
+
+ // Create new tables
+ self::createDBFromStructure( $file );
+ self::commit();
+
+ }
+
+ /**
* Start a transaction
*/
public static function beginTransaction(){
@@ -589,3 +628,4 @@ class PDOStatementWrapper{
return $this->statement->fetchColumn($colnum);
}
}
+
diff --git a/lib/eventsource.php b/lib/eventsource.php
index 523f72403c3..cf10660b94c 100644
--- a/lib/eventsource.php
+++ b/lib/eventsource.php
@@ -32,6 +32,7 @@ class OC_EventSource{
private $fallBackId=0;
public function __construct(){
+ @ob_end_clean();
header('Cache-Control: no-cache');
$this->fallback=isset($_GET['fallback']) and $_GET['fallback']=='true';
if($this->fallback){
@@ -58,7 +59,7 @@ class OC_EventSource{
$type=null;
}
if($this->fallback){
- $response='<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack('.$this->fallBackId.',"'.$type.'","'.json_encode($data).'")</script>'.PHP_EOL;
+ $response='<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack('.$this->fallBackId.',"'.$type.'",'.json_encode($data).')</script>'.PHP_EOL;
echo $response;
}else{
if($type){
diff --git a/lib/filecache.php b/lib/filecache.php
index 280a9929db0..24984c2ccff 100644
--- a/lib/filecache.php
+++ b/lib/filecache.php
@@ -59,8 +59,8 @@ class OC_FileCache{
$root='';
}
$path=$root.$path;
- $query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path=?');
- $result=$query->execute(array($path))->fetchRow();
+ $query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path_hash=?');
+ $result=$query->execute(array(md5($path)))->fetchRow();
if(is_array($result)){
return $result;
}else{
@@ -111,8 +111,8 @@ class OC_FileCache{
}
$mimePart=dirname($data['mimetype']);
$user=OC_User::getUser();
- $query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, size, mtime, ctime, mimetype, mimepart,user,writable,encrypted,versioned) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)');
- $result=$query->execute(array($parent,basename($path),$path,$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned']));
+ $query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, path_hash, size, mtime, ctime, mimetype, mimepart,user,writable,encrypted,versioned) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)');
+ $result=$query->execute(array($parent,basename($path),$path,md5($path),$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned']));
if(OC_DB::isError($result)){
OC_Log::write('files','error while writing file('.$path.') to cache',OC_Log::ERROR);
}
@@ -162,8 +162,8 @@ class OC_FileCache{
$oldPath=$root.$oldPath;
$newPath=$root.$newPath;
$newParent=self::getParentId($newPath);
- $query=OC_DB::prepare('UPDATE *PREFIX*fscache SET parent=? ,name=?, path=? WHERE path=?');
- $query->execute(array($newParent,basename($newPath),$newPath,$oldPath));
+ $query=OC_DB::prepare('UPDATE *PREFIX*fscache SET parent=? ,name=?, path=?, path_hash=? WHERE path_hash=?');
+ $query->execute(array($newParent,basename($newPath),$newPath,md5($newPath),md5($oldPath)));
}
/**
@@ -240,7 +240,7 @@ class OC_FileCache{
* - encrypted
* - versioned
*/
- public static function getFolderContent($path,$root=''){
+ public static function getFolderContent($path,$root='',$mimetype_filter=''){
if(self::isUpdated($path,$root)){
self::updateFolder($path,$root);
}
@@ -252,8 +252,8 @@ class OC_FileCache{
}
$path=$root.$path;
$parent=self::getFileId($path);
- $query=OC_DB::prepare('SELECT name,ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE parent=?');
- $result=$query->execute(array($parent))->fetchAll();
+ $query=OC_DB::prepare('SELECT name,ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE parent=? AND (mimetype LIKE ? OR mimetype = ?)');
+ $result=$query->execute(array($parent, $mimetype_filter.'%', 'httpd/unix-directory'))->fetchAll();
if(is_array($result)){
return $result;
}else{
@@ -281,16 +281,17 @@ class OC_FileCache{
/**
* get the file id as used in the cache
+ * unlike the public getId, full paths are used here (/usename/files/foo instead of /foo)
* @param string $path
* @return int
*/
private static function getFileId($path){
- $query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path=?');
+ $query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path_hash=?');
if(OC_DB::isError($query)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
}
- $result=$query->execute(array($path));
+ $result=$query->execute(array(md5($path)));
if(OC_DB::isError($result)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
@@ -303,6 +304,39 @@ class OC_FileCache{
return -1;
}
}
+
+ /**
+ * get the file id as used in the cache
+ * @param string path
+ * @param string root (optional)
+ * @return int
+ */
+ public static function getId($path,$root=''){
+ if(!$root){
+ $root=OC_Filesystem::getRoot();
+ }
+ if($root=='/'){
+ $root='';
+ }
+ $path=$root.$path;
+ return self::getFileId($path);
+ }
+
+ /**
+ * get the file path from the id, relative to the home folder of the user
+ * @param int id
+ * @param string user (optional)
+ * @return string
+ */
+ public static function getPath($id,$user=''){
+ if(!$user){
+ $user=OC_User::getUser();
+ }
+ $query=OC_DB::prepare('SELECT path FROM *PREFIX*fscache WHERE id=? AND user=?');
+ $result=$query->execute(array($id,$user));
+ $row=$result->fetchRow();
+ return $row['path'];
+ }
/**
* get the file id of the parent folder, taking into account '/' has no parent
@@ -367,8 +401,8 @@ class OC_FileCache{
}
}
$path=$root.$path;
- $query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path=?');
- $result=$query->execute(array($path))->fetchRow();
+ $query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path_hash=?');
+ $result=$query->execute(array(md5($path)))->fetchRow();
if(is_array($result)){
if(isset(self::$savedData[$path])){
$result=array_merge($result,self::$savedData[$path]);
@@ -389,8 +423,8 @@ class OC_FileCache{
}
}
$path=$root.$path;
- $query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE path=?');
- $result=$query->execute(array($path));
+ $query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE path_hash=?');
+ $result=$query->execute(array(md5($path)));
if($row=$result->fetchRow()){
return $row['size'];
}else{//file not in cache
@@ -469,6 +503,10 @@ class OC_FileCache{
* @param string root (optionak)
*/
public static function scan($path,$eventSource=false,&$count=0,$root=''){
+ if($eventSource){
+ $eventSource->send('scanning',array('file'=>$path,'count'=>$count));
+ }
+ $lastSend=$count;
if(!$root){
$view=OC_Filesystem::getView();
}else{
@@ -482,13 +520,14 @@ class OC_FileCache{
if($filename != '.' and $filename != '..'){
$file=$path.'/'.$filename;
if($view->is_dir($file.'/')){
- if($eventSource){
- $eventSource->send('scanning',array('file'=>$file,'count'=>$count));
- }
self::scan($file,$eventSource,$count,$root);
}else{
$totalSize+=self::scanFile($file,$root);
$count++;
+ if($count>$lastSend+25 and $eventSource){
+ $lastSend=$count;
+ $eventSource->send('scanning',array('file'=>$path,'count'=>$count));
+ }
}
}
}
@@ -579,8 +618,8 @@ class OC_FileCache{
$mtime=$view->filemtime($path);
$isDir=$view->is_dir($path);
$path=$root.$path;
- $query=OC_DB::prepare('SELECT mtime FROM *PREFIX*fscache WHERE path=?');
- $result=$query->execute(array($path));
+ $query=OC_DB::prepare('SELECT mtime FROM *PREFIX*fscache WHERE path_hash=?');
+ $result=$query->execute(array(md5($path)));
if($row=$result->fetchRow()){
$cachedMTime=$row['mtime'];
return ($mtime>$cachedMTime);
@@ -637,6 +676,14 @@ class OC_FileCache{
self::fileSystemWatcherWrite(array('path'=>$path),$root);
}
}
+
+ /**
+ * clean old pre-path_hash entries
+ */
+ public static function clean(){
+ $query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE LENGTH(path_hash)<30');
+ $query->execute();
+ }
}
//watch for changes and try to keep the cache up to date
diff --git a/lib/files.php b/lib/files.php
index 1f8331afb21..a7b83149574 100644
--- a/lib/files.php
+++ b/lib/files.php
@@ -32,11 +32,11 @@ class OC_Files {
* get the content of a directory
* @param dir $directory
*/
- public static function getDirectoryContent($directory){
+ public static function getDirectoryContent($directory, $mimetype_filter = ''){
if(strpos($directory,OC::$CONFIG_DATADIRECTORY)===0){
$directory=substr($directory,strlen(OC::$CONFIG_DATADIRECTORY));
}
- $files=OC_FileCache::getFolderContent($directory);
+ $files=OC_FileCache::getFolderContent($directory, '', $mimetype_filter);
foreach($files as &$file){
$file['directory']=$directory;
$file['type']=($file['mimetype']=='httpd/unix-directory')?'dir':'file';
@@ -59,9 +59,12 @@ class OC_Files {
}
if(is_array($files)){
+ self::validateZipDownload($dir,$files);
+ $executionTime = intval(ini_get('max_execution_time'));
+ set_time_limit(0);
$zip = new ZipArchive();
- $filename = get_temp_dir()."/ownCloud.zip";
- if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
+ $filename = OC_Helper::tmpFile('.zip');
+ if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) {
exit("cannot open <$filename>\n");
}
foreach($files as $file){
@@ -75,15 +78,20 @@ class OC_Files {
}
}
$zip->close();
+ set_time_limit($executionTime);
}elseif(OC_Filesystem::is_dir($dir.'/'.$files)){
+ self::validateZipDownload($dir,$files);
+ $executionTime = intval(ini_get('max_execution_time'));
+ set_time_limit(0);
$zip = new ZipArchive();
- $filename = get_temp_dir()."/ownCloud.zip";
- if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
+ $filename = OC_Helper::tmpFile('.zip');
+ if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) {
exit("cannot open <$filename>\n");
}
$file=$dir.'/'.$files;
self::zipAddDir($file,$zip);
$zip->close();
+ set_time_limit($executionTime);
}else{
$zip=false;
$filename=$dir.'/'.$files;
@@ -96,15 +104,15 @@ class OC_Files {
header('Content-Type: application/zip');
header('Content-Length: ' . filesize($filename));
}else{
- header('Content-Type: ' . OC_Filesystem::getMimeType($filename));
- header('Content-Length: ' . OC_Filesystem::filesize($filename));
+ $fileData=OC_FileCache::get($filename);
+ header('Content-Type: ' . $fileData['mimetype']);
+ header('Content-Length: ' . $fileData['size']);
}
}elseif($zip or !OC_Filesystem::file_exists($filename)){
header("HTTP/1.0 404 Not Found");
$tmpl = new OC_Template( '', '404', 'guest' );
$tmpl->assign('file',$filename);
$tmpl->printPage();
-// die('404 Not Found');
}else{
header("HTTP/1.0 403 Forbidden");
die('403 Forbidden');
@@ -210,6 +218,55 @@ class OC_Files {
}
/**
+ * checks if the selected files are within the size constraint. If not, outputs an error page.
+ *
+ * @param dir $dir
+ * @param files $files
+ */
+ static function validateZipDownload($dir, $files) {
+ if(!OC_Config::getValue('allowZipDownload', true)) {
+ $l = OC_L10N::get('files');
+ header("HTTP/1.0 409 Conflict");
+ $tmpl = new OC_Template( '', 'error', 'user' );
+ $errors = array(
+ array(
+ 'error' => $l->t('ZIP download is turned off.'),
+ 'hint' => $l->t('Files need to be downloaded one by one.') . '<br/><a href="javascript:history.back()">' . $l->t('Back to Files') . '</a>',
+ )
+ );
+ $tmpl->assign('errors', $errors);
+ $tmpl->printPage();
+ exit;
+ }
+
+ $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_Filesystem::filesize($dir.'/'.$file);
+ }
+ }else{
+ $totalsize += OC_Filesystem::filesize($dir.'/'.$files);
+ }
+ if($totalsize > $zipLimit) {
+ $l = OC_L10N::get('files');
+ header("HTTP/1.0 409 Conflict");
+ $tmpl = new OC_Template( '', 'error', 'user' );
+ $errors = array(
+ array(
+ 'error' => $l->t('Selected files too large to generate zip file.'),
+ 'hint' => 'Download the files in smaller chunks, seperately or kindly ask your administrator.<br/><a href="javascript:history.back()">' . $l->t('Back to Files') . '</a>',
+ )
+ );
+ $tmpl->assign('errors', $errors);
+ $tmpl->printPage();
+ exit;
+ }
+ }
+ }
+
+ /**
* try to detect the mime type of a file
*
* @param string path
@@ -256,21 +313,58 @@ class OC_Files {
return false;
}
}
-
+
/**
* set the maximum upload size limit for apache hosts using .htaccess
* @param int size filesisze in bytes
+ * @return false on failure, size on success
*/
static function setUploadLimit($size){
- $size=OC_Helper::humanFileSize($size);
- $size=substr($size,0,-1);//strip the B
- $size=str_replace(' ','',$size); //remove the space between the size and the postfix
- $content = "ErrorDocument 404 /".OC::$WEBROOT."/core/templates/404.php\n";//custom 404 error page
- $content.= "php_value upload_max_filesize $size\n";//upload limit
- $content.= "php_value post_max_size $size\n";
- $content.= "SetEnv htaccessWorking true\n";
- $content.= "Options -Indexes\n";
- @file_put_contents(OC::$SERVERROOT.'/.htaccess', $content); //supress errors in case we don't have permissions for it
+ //don't allow user to break his config -- upper boundary
+ if($size > PHP_INT_MAX) {
+ //max size is always 1 byte lower than computerFileSize returns
+ if($size > PHP_INT_MAX+1)
+ return false;
+ $size -=1;
+ } else {
+ $size=OC_Helper::humanFileSize($size);
+ $size=substr($size,0,-1);//strip the B
+ $size=str_replace(' ','',$size); //remove the space between the size and the postfix
+ }
+
+ //don't allow user to break his config -- broken or malicious size input
+ if(intval($size) == 0) {
+ return false;
+ }
+
+ $htaccess = @file_get_contents(OC::$SERVERROOT.'/.htaccess'); //supress errors in case we don't have permissions for
+ if(!$htaccess) {
+ return false;
+ }
+
+ $phpValueKeys = array(
+ 'upload_max_filesize',
+ 'post_max_size'
+ );
+
+ foreach($phpValueKeys as $key) {
+ $pattern = '/php_value '.$key.' (\S)*/';
+ $setting = 'php_value '.$key.' '.$size;
+ $hasReplaced = 0;
+ $content = preg_replace($pattern, $setting, $htaccess, 1, $hasReplaced);
+ if($content !== NULL) {
+ $htaccess = $content;
+ }
+ if($hasReplaced == 0) {
+ $htaccess .= "\n" . $setting;
+ }
+ }
+
+ //supress errors in case we don't have permissions for it
+ if(@file_put_contents(OC::$SERVERROOT.'/.htaccess', $htaccess)) {
+ return OC_Helper::computerFileSize($size);
+ }
+ return false;
}
/**
diff --git a/lib/filestorage/common.php b/lib/filestorage/common.php
index f632474df01..f0bfc064cb5 100644
--- a/lib/filestorage/common.php
+++ b/lib/filestorage/common.php
@@ -100,11 +100,11 @@ abstract class OC_Filestorage_Common extends OC_Filestorage {
}
$head=fread($source,8192);//8kb should suffice to determine a mimetype
if($pos=strrpos($path,'.')){
- $extention=substr($path,$pos);
+ $extension=substr($path,$pos);
}else{
- $extention='';
+ $extension='';
}
- $tmpFile=OC_Helper::tmpFile($extention);
+ $tmpFile=OC_Helper::tmpFile($extension);
file_put_contents($tmpFile,$head);
$mime=OC_Helper::getMimeType($tmpFile);
unlink($tmpFile);
@@ -129,11 +129,11 @@ abstract class OC_Filestorage_Common extends OC_Filestorage {
return false;
}
if($pos=strrpos($path,'.')){
- $extention=substr($path,$pos);
+ $extension=substr($path,$pos);
}else{
- $extention='';
+ $extension='';
}
- $tmpFile=OC_Helper::tmpFile($extention);
+ $tmpFile=OC_Helper::tmpFile($extension);
$target=fopen($tmpFile,'w');
$count=OC_Helper::streamCopy($source,$target);
return $tmpFile;
diff --git a/lib/filestorage/google.php b/lib/filestorage/google.php
deleted file mode 100644
index 49985548382..00000000000
--- a/lib/filestorage/google.php
+++ /dev/null
@@ -1,341 +0,0 @@
-<?php
-
-/**
-* ownCloud
-*
-* @author Michael Gapczynski
-* @copyright 2012 Michael Gapczynski mtgap@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/>.
-*/
-
-require_once 'common.inc.php';
-
-class OC_Filestorage_Google extends OC_Filestorage_Common {
-
- private $datadir;
- private $consumer;
- private $oauth_token;
- private $sig_method;
- private $entries;
-
- public function __construct($arguments) {
- $this->datadir = $arguments['datadir'];
- $consumer_key = isset($arguments['consumer_key']) ? $arguments['consumer_key'] : 'anonymous';
- $consumer_secret = isset($arguments['consumer_secret']) ? $arguments['consumer_secret'] : 'anonymous';
- $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
- $this->oauth_token = new OAuthToken($arguments['token'], $arguments['token_secret']);
- $this->sig_method = new OAuthSignatureMethod_HMAC_SHA1();
- $this->entries = array();
- }
-
- private function sendRequest($feedUri, $http_method, $postData = null) {
- $feedUri = trim($feedUri);
- // create an associative array from each key/value url query param pair.
- $params = array();
- $pieces = explode('?', $feedUri);
- if (isset($pieces[1])) {
- $params = explode_assoc('=', '&', $pieces[1]);
- }
- // urlencode each url parameter key/value pair
- $tempStr = $pieces[0];
- foreach ($params as $key => $value) {
- $tempStr .= '&' . urlencode($key) . '=' . urlencode($value);
- }
- $feedUri = preg_replace('/&/', '?', $tempStr, 1);
- $req = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $http_method, $feedUri, $params);
- $req->sign_request($this->sig_method, $this->consumer, $this->oauth_token);
- $auth_header = $req->to_header();
- $result = send_signed_request($http_method, $feedUri, array($auth_header, 'Content-Type: application/atom+xml', 'GData-Version: 3.0'), $postData);
- // TODO Return false if error is received
- if (!$result) {
- return false;
- }
- $result = explode('<', $result, 2);
- $result = isset($result[1]) ? '<'.$result[1] : $result[0];
- $dom = new DOMDocument();
- $dom->loadXML($result);
- return $dom;
- }
-
- private function getResource($path) {
- if (array_key_exists($path, $this->entries)) {
- return $this->entries[$path];
- } else {
- $title = basename($path);
- $dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$title, 'GET');
- // Check if request was successful and entry exists
- if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) {
- $this->entries[$path] = $entry;
- return $entry;
- }
- return false;
- }
- }
-
- private function getExtension($entry) {
- $mimetype = $this->getMimeType('', $entry);
- switch($mimetype) {
- case 'httpd/unix-directory':
- return '';
- case 'application/vnd.oasis.opendocument.text':
- return 'odt';
- case 'application/vnd.oasis.opendocument.spreadsheet':
- return 'ods';
- case 'application/vnd.oasis.opendocument.presentation':
- return 'pptx';
- case 'text/html':
- return 'html';
- default:
- return 'html';
- }
- }
-
-
- public function mkdir($path) {
- $dir = dirname($path);
- // Check if path parent is root directory
- if ($dir == '/' || $dir == '\.' || $dir == '.') {
- $feedUri = 'https://docs.google.com/feeds/default/private/full';
- // Get parent content link
- } else if ($dom = $this->getResource(basename($dir))) {
- $feedUri = $dom->getElementsByTagName('content')->item(0)->getAttribute('src');
- }
- if (isset($feedUri)) {
- $title = basename($path);
- // Construct post data
- $postData = '<?xml version="1.0" encoding="UTF-8"?>';
- $postData .= '<entry xmlns="http://www.w3.org/2005/Atom">';
- $postData .= '<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#folder"/>';
- $postData .= '<title>'.$title.'</title>';
- $postData .= '</entry>';
- if ($dom = $this->sendRequest($feedUri, 'POST', $postData)) {
- return true;
- }
- }
- return false;
- }
-
- public function rmdir($path) {
- return $this->unlink($path);
- }
-
- public function opendir($path) {
- if ($path == '' || $path == '/') {
- $next = 'https://docs.google.com/feeds/default/private/full/folder%3Aroot/contents';
- } else {
- if ($entry = $this->getResource($path)) {
- $next = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
- } else {
- return false;
- }
- }
- $files = array();
- while ($next) {
- $dom = $this->sendRequest($next, 'GET');
- $links = $dom->getElementsByTagName('link');
- foreach ($links as $link) {
- if ($link->getAttribute('rel') == 'next') {
- $next = $link->getAttribute('src');
- break;
- } else {
- $next = false;
- }
- }
- $entries = $dom->getElementsByTagName('entry');
- foreach ($entries as $entry) {
- $name = $entry->getElementsByTagName('title')->item(0)->nodeValue;
- // Google Docs resources don't always include extensions in title
- if (!strpos($name, '.')) {
- $name .= '.'.$this->getExtension($entry);
- }
- $files[] = $name;
- // Cache entry for future use
- $this->entries[$name] = $entry;
- }
- }
- OC_FakeDirStream::$dirs['google'] = $files;
- return opendir('fakedir://google');
- }
-
- public function stat($path) {
- if ($path == '' || $path == '/') {
- $stat['size'] = $this->free_space($path);
- $stat['atime'] = time();
- $stat['mtime'] = time();
- $stat['ctime'] = time();
- } else if ($entry = $this->getResource($path)) {
- // NOTE: Native resources don't have a file size
- $stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue;
- $stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue);
- $stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue);
- $stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue);
- }
- return $stat;
- }
-
- public function filetype($path) {
- if ($path == '' || $path == '/') {
- return 'dir';
- } else if ($entry = $this->getResource($path)) {
- $categories = $entry->getElementsByTagName('category');
- foreach ($categories as $category) {
- if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') {
- $type = $category->getAttribute('label');
- if (strlen(strstr($type, 'folder')) > 0) {
- return 'dir';
- } else {
- return 'file';
- }
- }
- }
- }
- return false;
- }
-
- public function is_readable($path) {
- return true;
- }
-
- public function is_writable($path) {
- if ($path == '' || $path == '/') {
- return true;
- } else if ($entry = $this->getResource($path)) {
- // Check if edit or edit-media links exist
- $links = $entry->getElementsByTagName('link');
- foreach ($links as $link) {
- if ($link->getAttribute('rel') == 'edit') {
- return true;
- } else if ($link->getAttribute('rel') == 'edit-media') {
- return true;
- }
- }
- }
- return false;
- }
-
- public function file_exists($path) {
- if ($path == '' || $path == '/') {
- return true;
- } else if ($this->getResource($path)) {
- return true;
- }
- return false;
- }
-
- public function unlink($path) {
- // Get resource self link to trash resource
- if ($entry = $this->getResource($path)) {
- $links = $entry->getElementsByTagName('link');
- foreach ($links as $link) {
- if ($link->getAttribute('rel') == 'self') {
- $feedUri = $link->getAttribute('href');
- }
- }
- }
- if (isset($feedUri)) {
- $this->sendRequest($feedUri, 'DELETE');
- return true;
- }
- return false;
- }
-
- public function rename($path1, $path2) {
- // TODO Add support for moving to different collections
- // Get resource edit link to rename resource
- if ($entry = $this->getResource($path1)) {
- $etag = $entry->getElementsByTagName('entry')->item(0)->getAttribute('gd:etag');
- $links = $entry->getElementsByTagName('link');
- foreach ($links as $link) {
- if ($link->getAttribute('rel') == 'edit') {
- $feedUri = $link->getAttribute('href');
- }
- }
- }
- if (isset($etag) && isset($feedUri)) {
- $title = basename($path2);
- // Construct post data
- $postData = '<?xml version="1.0" encoding="UTF-8"?>';
- $postData .= '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007" xmlns:gd="http://schemas.google.com/g/2005" gd:etag='.$etag.'>';
- $postData .= '<title>'.$title.'</title>';
- $postData .= '</entry>';
- $this->sendRequest($feedUri, 'PUT', $postData);
- return true;
- }
- return false;
- }
-
- public function fopen($path, $mode) {
- if ($entry = $this->getResource($path)) {
- $extension = $this->getExtension($path);
- $downloadUri = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
- // TODO Non-native documents don't need these additional parameters
- $downloadUri .= '&exportFormat='.$extension.'&format='.$extension;
- }
- }
-
- public function getMimeType($path, $entry = null) {
- if ($entry == null) {
- if ($path == '' || $path == '/') {
- return 'httpd/unix-directory';
- } else {
- $entry = $this->getResource($path);
- }
- }
- if ($entry) {
- $mimetype = $entry->getElementsByTagName('content')->item(0)->getAttribute('type');
- // Native Google Docs resources often default to text/html, but it may be more useful to default to a corresponding ODF mimetype
- // Collections get reported as application/atom+xml, make sure it actually is a folder and fix the mimetype
- if ($mimetype == 'text/html' || $mimetype == 'application/atom+xml') {
- $categories = $entry->getElementsByTagName('category');
- foreach ($categories as $category) {
- if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') {
- $type = $category->getAttribute('label');
- if (strlen(strstr($type, 'folder')) > 0) {
- return 'httpd/unix-directory';
- } else if (strlen(strstr($type, 'document')) > 0) {
- return 'application/vnd.oasis.opendocument.text';
- } else if (strlen(strstr($type, 'spreadsheet')) > 0) {
- return 'application/vnd.oasis.opendocument.spreadsheet';
- } else if (strlen(strstr($type, 'presentation')) > 0) {
- return 'application/vnd.oasis.opendocument.presentation';
- } else if (strlen(strstr($type, 'drawing')) > 0) {
- return 'application/vnd.oasis.opendocument.graphics';
- } else {
- // If nothing matches return text/html, all native Google Docs resources can be exported as text/html
- return 'text/html';
- }
- }
- }
- }
- return $mimetype;
- }
- return false;
- }
-
- public function free_space($path) {
- if ($dom = $this->sendRequest('https://docs.google.com/feeds/metadata/default', 'GET')) {
- // NOTE: Native Google Docs resources don't count towards quota
- $total = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesTotal')->item(0)->nodeValue;
- $used = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue;
- return $total - $used;
- }
- return false;
- }
-
- public function search($query) {
-
- }
-
-} \ No newline at end of file
diff --git a/lib/filestorage/local.php b/lib/filestorage/local.php
index 688501aee90..bd757f52ce7 100644
--- a/lib/filestorage/local.php
+++ b/lib/filestorage/local.php
@@ -86,6 +86,10 @@ class OC_Filestorage_Local extends OC_Filestorage{
return $this->delTree($path);
}
public function rename($path1,$path2){
+ if (!$this->is_writable($path1)) {
+ OC_Log::write('core','unable to rename, file is not writable : '.$path1,OC_Log::ERROR);
+ return false;
+ }
if(! $this->file_exists($path1)){
OC_Log::write('core','unable to rename, file does not exists : '.$path1,OC_Log::ERROR);
return false;
diff --git a/lib/filesystem.php b/lib/filesystem.php
index 12905d189f9..dc678fba74c 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -249,6 +249,14 @@ class OC_Filesystem{
}
/**
+ * clear all mounts and storage backends
+ */
+ public static function clearMounts(){
+ self::$mounts=array();
+ self::$storages=array();
+ }
+
+ /**
* mount an OC_Filestorage in our virtual filesystem
* @param OC_Filestorage storage
* @param string mountpoint
@@ -298,6 +306,19 @@ class OC_Filesystem{
}
return true;
}
+
+ /**
+ * checks if a file is blacklsited for storage in the filesystem
+ * @param array $data from hook
+ */
+ static public function isBlacklisted($data){
+ $blacklist = array('.htaccess');
+ $filename = strtolower(basename($data['path']));
+ if(in_array($filename,$blacklist)){
+ $data['run'] = false;
+ }
+ }
+
/**
* following functions are equivilent to their php buildin equivilents for arguments/return values.
*/
diff --git a/lib/filesystemview.php b/lib/filesystemview.php
index 89e0385fe9c..95873bd87cf 100644
--- a/lib/filesystemview.php
+++ b/lib/filesystemview.php
@@ -23,11 +23,11 @@
class OC_FilesystemView {
private $fakeRoot='';
-
+
public function __construct($root){
$this->fakeRoot=$root;
}
-
+
public function getAbsolutePath($path){
if(!$path){
$path='/';
@@ -137,13 +137,16 @@ class OC_FilesystemView {
}
public function readfile($path){
$handle=$this->fopen($path,'r');
- $chunkSize = 1024*1024;// 1 MB chunks
- while (!feof($handle)) {
- echo fread($handle, $chunkSize);
- @ob_flush();
- flush();
+ if ($handle) {
+ $chunkSize = 1024*1024;// 1 MB chunks
+ while (!feof($handle)) {
+ echo fread($handle, $chunkSize);
+ @ob_flush();
+ flush();
+ }
+ return $this->filesize($path);
}
- return $this->filesize($path);
+ return false;
}
public function is_readable($path){
return $this->basicOperation('is_readable',$path);
@@ -189,7 +192,7 @@ class OC_FilesystemView {
return $this->basicOperation('unlink',$path,array('delete'));
}
public function rename($path1,$path2){
- if(OC_FileProxy::runPreProxies('rename',$path1,$path2) and $this->is_writable($path1) and OC_Filesystem::isValidPath($path2)){
+ if(OC_FileProxy::runPreProxies('rename',$path1,$path2) and OC_Filesystem::isValidPath($path2)){
$run=true;
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2, OC_Filesystem::signal_param_run => &$run));
if($run){
@@ -280,9 +283,14 @@ class OC_FilesystemView {
if(OC_Filesystem::isValidPath($path)){
$source=$this->fopen($path,'r');
if($source){
- $extention=substr($path,strrpos($path,'.'));
- $tmpFile=OC_Helper::tmpFile($extention);
- return file_put_contents($tmpFile,$source);
+ $extension='';
+ $extOffset=strpos($path,'.');
+ if($extOffset !== false) {
+ $extension=substr($path,strrpos($path,'.'));
+ }
+ $tmpFile=OC_Helper::tmpFile($extension);
+ file_put_contents($tmpFile,$source);
+ return $tmpFile;
}
}
}
diff --git a/lib/group.php b/lib/group.php
index fbff41e30e9..4ae9302f78b 100644
--- a/lib/group.php
+++ b/lib/group.php
@@ -34,57 +34,25 @@
* post_removeFromGroup(uid, gid)
*/
class OC_Group {
- // The backend used for user management
- private static $_backend;
-
- // Backends available (except database)
- private static $_backends = array();
-
- /**
- * @brief registers backend
- * @param $name name of the backend
- * @returns true/false
- *
- * Makes a list of backends that can be used by other modules
- */
- public static function registerBackend( $name ){
- self::$_backends[] = $name;
- return true;
- }
-
- /**
- * @brief gets available backends
- * @returns array of backends
- *
- * Returns the names of all backends.
- */
- public static function getBackends(){
- return self::$_backends;
- }
+ // The backend used for group management
+ private static $_usedBackends = array();
/**
* @brief set the group backend
* @param string $backend The backend to use for user managment
* @returns true/false
*/
- public static function setBackend( $backend = 'database' ){
- // You'll never know what happens
- if( null === $backend OR !is_string( $backend )){
- $backend = 'database';
+ public static function useBackend( $backend ){
+ if($backend instanceof OC_Group_Backend){
+ self::$_usedBackends[]=$backend;
}
+ }
- // Load backend
- switch( $backend ){
- case 'database':
- case 'mysql':
- case 'sqlite':
- self::$_backend = new OC_Group_Database();
- break;
- default:
- $className = 'OC_GROUP_' . strToUpper($backend);
- self::$_backend = new $className();
- break;
- }
+ /**
+ * remove all used backends
+ */
+ public static function clearBackends(){
+ self::$_usedBackends=array();
}
/**
@@ -115,11 +83,18 @@ class OC_Group {
$run = true;
OC_Hook::emit( "OC_Group", "pre_createGroup", array( "run" => &$run, "gid" => $gid ));
- if( $run && self::$_backend->createGroup( $gid )){
- OC_Hook::emit( "OC_Group", "post_createGroup", array( "gid" => $gid ));
- return true;
- }
- else{
+ if($run){
+ //create the user in the first backend that supports creating users
+ foreach(self::$_usedBackends as $backend){
+ if(!$backend->implementsActions(OC_GROUP_BACKEND_CREATE_GROUP))
+ continue;
+
+ $backend->createGroup($gid);
+ OC_Hook::emit( "OC_User", "post_createGroup", array( "gid" => $gid ));
+
+ return true;
+ }
+ }else{
return false;
}
}
@@ -140,11 +115,18 @@ class OC_Group {
$run = true;
OC_Hook::emit( "OC_Group", "pre_deleteGroup", array( "run" => &$run, "gid" => $gid ));
- if( $run && self::$_backend->deleteGroup( $gid )){
- OC_Hook::emit( "OC_Group", "post_deleteGroup", array( "gid" => $gid ));
- return true;
- }
- else{
+ if($run){
+ //delete the group from all backends
+ foreach(self::$_usedBackends as $backend){
+ if(!$backend->implementsActions(OC_GROUP_BACKEND_DELETE_GROUP))
+ continue;
+
+ $backend->deleteGroup($gid);
+ OC_Hook::emit( "OC_User", "post_deleteGroup", array( "gid" => $gid ));
+
+ return true;
+ }
+ }else{
return false;
}
}
@@ -158,7 +140,15 @@ class OC_Group {
* Checks whether the user is member of a group or not.
*/
public static function inGroup( $uid, $gid ){
- return self::$_backend->inGroup($uid, $gid);
+ foreach(self::$_usedBackends as $backend){
+ if(!$backend->implementsActions(OC_GROUP_BACKEND_IN_GROUP))
+ continue;
+
+ if($backend->inGroup($uid,$gid)){
+ return true;
+ }
+ }
+ return false;
}
/**
@@ -170,10 +160,6 @@ class OC_Group {
* Adds a user to a group.
*/
public static function addToGroup( $uid, $gid ){
- // Does the user exist?
- if( !OC_User::userExists($uid)){
- return false;
- }
// Does the group exist?
if( !OC_Group::groupExists($gid)){
return false;
@@ -183,11 +169,19 @@ class OC_Group {
$run = true;
OC_Hook::emit( "OC_Group", "pre_addToGroup", array( "run" => &$run, "uid" => $uid, "gid" => $gid ));
- if( $run && self::$_backend->addToGroup( $uid, $gid )){
- OC_Hook::emit( "OC_Group", "post_addToGroup", array( "uid" => $uid, "gid" => $gid ));
- return true;
- }
- else{
+ if($run){
+ $succes=false;
+
+ //add the user to the all backends that have the group
+ foreach(self::$_usedBackends as $backend){
+ if(!$backend->implementsActions(OC_GROUP_BACKEND_ADD_TO_GROUP))
+ continue;
+
+ $succes|=$backend->addToGroup($uid, $gid);
+ OC_Hook::emit( "OC_User", "post_addToGroup", array( "uid" => $uid, "gid" => $gid ));
+ }
+ return $succes;
+ }else{
return false;
}
}
@@ -204,11 +198,17 @@ class OC_Group {
$run = true;
OC_Hook::emit( "OC_Group", "pre_removeFromGroup", array( "run" => &$run, "uid" => $uid, "gid" => $gid ));
- if( $run && self::$_backend->removeFromGroup( $uid, $gid )){
- OC_Hook::emit( "OC_Group", "post_removeFromGroup", array( "uid" => $uid, "gid" => $gid ));
+ if($run){
+ //remove the user from the all backends that have the group
+ foreach(self::$_usedBackends as $backend){
+ if(!$backend->implementsActions(OC_GROUP_BACKEND_REMOVE_FROM_GOUP))
+ continue;
+
+ $backend->removeFromGroup($uid, $gid);
+ OC_Hook::emit( "OC_User", "post_removeFromGroup", array( "uid" => $uid, "gid" => $gid ));
+ }
return true;
- }
- else{
+ }else{
return false;
}
}
@@ -222,7 +222,14 @@ class OC_Group {
* if the user exists at all.
*/
public static function getUserGroups( $uid ){
- return self::$_backend->getUserGroups($uid);
+ $groups=array();
+ foreach(self::$_usedBackends as $backend){
+ if(!$backend->implementsActions(OC_GROUP_BACKEND_GET_USER_GROUPS))
+ continue;
+
+ $groups=array_merge($backend->getUserGroups($uid),$groups);
+ }
+ return $groups;
}
/**
@@ -232,7 +239,14 @@ class OC_Group {
* Returns a list with all groups
*/
public static function getGroups(){
- return self::$_backend->getGroups();
+ $groups=array();
+ foreach(self::$_usedBackends as $backend){
+ if(!$backend->implementsActions(OC_GROUP_BACKEND_GET_GROUPS))
+ continue;
+
+ $groups=array_merge($backend->getGroups(),$groups);
+ }
+ return $groups;
}
/**
@@ -249,6 +263,13 @@ class OC_Group {
* @returns array with user ids
*/
public static function usersInGroup($gid){
- return self::$_backend->usersInGroup($gid);
+ $users=array();
+ foreach(self::$_usedBackends as $backend){
+ if(!$backend->implementsActions(OC_GROUP_BACKEND_GET_USERS))
+ continue;
+
+ $users=array_merge($backend->usersInGroup($gid),$users);
+ }
+ return $users;
}
}
diff --git a/lib/group/backend.php b/lib/group/backend.php
index 43f94e7ea1a..b3fc06ac9a8 100644
--- a/lib/group/backend.php
+++ b/lib/group/backend.php
@@ -21,82 +21,65 @@
*
*/
+/**
+ * error code for functions not provided by the group backend
+ */
+define('OC_GROUP_BACKEND_NOT_IMPLEMENTED', -501);
+/**
+ * actions that user backends can define
+ */
+define('OC_GROUP_BACKEND_CREATE_GROUP', 0x00000001);
+define('OC_GROUP_BACKEND_DELETE_GROUP', 0x00000010);
+define('OC_GROUP_BACKEND_IN_GROUP', 0x00000100);
+define('OC_GROUP_BACKEND_ADD_TO_GROUP', 0x00001000);
+define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00010000);
+define('OC_GROUP_BACKEND_GET_USER_GROUPS', 0x00100000);
+define('OC_GROUP_BACKEND_GET_USERS', 0x01000000);
+define('OC_GROUP_BACKEND_GET_GROUPS', 0x10000000);
/**
* Abstract base class for user management
*/
abstract class OC_Group_Backend {
+ protected $possibleActions = array(
+ OC_GROUP_BACKEND_CREATE_GROUP => 'createGroup',
+ OC_GROUP_BACKEND_DELETE_GROUP => 'deleteGroup',
+ OC_GROUP_BACKEND_IN_GROUP => 'inGroup',
+ OC_GROUP_BACKEND_ADD_TO_GROUP => 'addToGroup',
+ OC_GROUP_BACKEND_REMOVE_FROM_GOUP => 'removeFromGroup',
+ OC_GROUP_BACKEND_GET_USER_GROUPS => 'getUserGroups',
+ OC_GROUP_BACKEND_GET_USERS => 'usersInGroup',
+ OC_GROUP_BACKEND_GET_GROUPS => 'getGroups'
+ );
+
/**
- * @brief Try to create a new group
- * @param $gid The name of the group to create
- * @returns true/false
- *
- * Trys to create a new group. If the group name already exists, false will
- * be returned.
- */
- public static function createGroup($gid){}
-
- /**
- * @brief delete a group
- * @param $gid gid of the group to delete
- * @returns true/false
- *
- * Deletes a group and removes it from the group_user-table
- */
- public static function removeGroup($gid){}
-
- /**
- * @brief is user in group?
- * @param $uid uid of the user
- * @param $gid gid of the group
- * @returns true/false
- *
- * Checks whether the user is member of a group or not.
- */
- public static function inGroup($uid, $gid){}
-
- /**
- * @brief Add a user to a group
- * @param $uid Name of the user to add to group
- * @param $gid Name of the group in which add the user
- * @returns true/false
- *
- * Adds a user to a group.
- */
- public static function addToGroup($uid, $gid){}
-
- /**
- * @brief Removes a user from a group
- * @param $uid Name of the user to remove from group
- * @param $gid Name of the group from which remove the user
- * @returns true/false
- *
- * removes the user from a group.
- */
- public static function removeFromGroup($uid,$gid){}
-
- /**
- * @brief Get all groups a user belongs to
- * @param $uid Name of the user
- * @returns array with group names
- *
- * This function fetches all groups a user belongs to. It does not check
- * if the user exists at all.
- */
- public static function getUserGroups($uid){}
+ * @brief Get all supported actions
+ * @returns bitwise-or'ed actions
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_USER_BACKEND_CREATE_USER etc.
+ */
+ public function getSupportedActions(){
+ $actions = 0;
+ foreach($this->possibleActions AS $action => $methodName){
+ if(method_exists($this, $methodName)) {
+ $actions |= $action;
+ }
+ }
- /**
- * @brief get a list of all groups
- * @returns array with group names
- *
- * Returns a list with all groups
- */
- public static function getGroups(){}
+ return $actions;
+ }
/**
- * @brief get a list of all users in a group
- * @returns array with user ids
- */
- public static function usersInGroup($gid){}
+ * @brief Check if backend implements actions
+ * @param $actions bitwise-or'ed actions
+ * @returns boolean
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_GROUP_BACKEND_CREATE_GROUP etc.
+ */
+ public function implementsActions($actions){
+ return (bool)($this->getSupportedActions() & $actions);
+ }
}
diff --git a/lib/group/database.php b/lib/group/database.php
index 1afd4b5fe4c..d401acf43b3 100644
--- a/lib/group/database.php
+++ b/lib/group/database.php
@@ -117,8 +117,10 @@ class OC_Group_Database extends OC_Group_Backend {
if( !self::inGroup( $uid, $gid )){
$query = OC_DB::prepare( "INSERT INTO `*PREFIX*group_user` ( `uid`, `gid` ) VALUES( ?, ? )" );
$result = $query->execute( array( $uid, $gid ));
+ return true;
+ }else{
+ return false;
}
- return true;
}
/**
diff --git a/lib/group/dummy.php b/lib/group/dummy.php
new file mode 100644
index 00000000000..5220237ecbf
--- /dev/null
+++ b/lib/group/dummy.php
@@ -0,0 +1,159 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * dummy group backend, does not keep state, only for testing use
+ */
+class OC_Group_Dummy extends OC_Group_Backend {
+ private $groups=array();
+ /**
+ * @brief Try to create a new group
+ * @param $gid The name of the group to create
+ * @returns true/false
+ *
+ * Trys to create a new group. If the group name already exists, false will
+ * be returned.
+ */
+ public function createGroup($gid){
+ if(!isset($this->groups[$gid])){
+ $this->groups[$gid]=array();
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * @brief delete a group
+ * @param $gid gid of the group to delete
+ * @returns true/false
+ *
+ * Deletes a group and removes it from the group_user-table
+ */
+ public function deleteGroup($gid){
+ if(isset($this->groups[$gid])){
+ unset($this->groups[$gid]);
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * @brief is user in group?
+ * @param $uid uid of the user
+ * @param $gid gid of the group
+ * @returns true/false
+ *
+ * Checks whether the user is member of a group or not.
+ */
+ public function inGroup($uid, $gid){
+ if(isset($this->groups[$gid])){
+ return (array_search($uid,$this->groups[$gid])!==false);
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * @brief Add a user to a group
+ * @param $uid Name of the user to add to group
+ * @param $gid Name of the group in which add the user
+ * @returns true/false
+ *
+ * Adds a user to a group.
+ */
+ public function addToGroup($uid, $gid){
+ if(isset($this->groups[$gid])){
+ if(array_search($uid,$this->groups[$gid])===false){
+ $this->groups[$gid][]=$uid;
+ return true;
+ }else{
+ return false;
+ }
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * @brief Removes a user from a group
+ * @param $uid NameUSER of the user to remove from group
+ * @param $gid Name of the group from which remove the user
+ * @returns true/false
+ *
+ * removes the user from a group.
+ */
+ public function removeFromGroup($uid,$gid){
+ if(isset($this->groups[$gid])){
+ if(($index=array_search($uid,$this->groups[$gid]))!==false){
+ unset($this->groups[$gid][$index]);
+ }else{
+ return false;
+ }
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * @brief Get all groups a user belongs to
+ * @param $uid Name of the user
+ * @returns array with group names
+ *
+ * This function fetches all groups a user belongs to. It does not check
+ * if the user exists at all.
+ */
+ public function getUserGroups($uid){
+ $groups=array();
+ foreach($this->groups as $group=>$user){
+ if($this->inGroup($uid,$group)){
+ $groups[]=$group;
+ }
+ }
+ return $groups;
+ }
+
+ /**
+ * @brief get a list of all groups
+ * @returns array with group names
+ *
+ * Returns a list with all groups
+ */
+ public function getGroups(){
+ return array_keys($this->groups);
+ }
+
+ /**
+ * @brief get a list of all users in a group
+ * @returns array with user ids
+ */
+ public function usersInGroup($gid){
+ if(isset($this->groups[$gid])){
+ return $this->groups[$gid];
+ }else{
+ return array();
+ }
+ }
+
+}
diff --git a/lib/group/example.php b/lib/group/example.php
new file mode 100644
index 00000000000..a88159f91be
--- /dev/null
+++ b/lib/group/example.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * abstract reference class for group management
+ * this class should only be used as a reference for method signatures and their descriptions
+ */
+abstract class OC_Group_Example {
+ /**
+ * @brief Try to create a new group
+ * @param $gid The name of the group to create
+ * @returns true/false
+ *
+ * Trys to create a new group. If the group name already exists, false will
+ * be returned.
+ */
+ public static function createGroup($gid){}
+
+ /**
+ * @brief delete a group
+ * @param $gid gid of the group to delete
+ * @returns true/false
+ *
+ * Deletes a group and removes it from the group_user-table
+ */
+ public static function deleteGroup($gid){}
+
+ /**
+ * @brief is user in group?
+ * @param $uid uid of the user
+ * @param $gid gid of the group
+ * @returns true/false
+ *
+ * Checks whether the user is member of a group or not.
+ */
+ public static function inGroup($uid, $gid){}
+
+ /**
+ * @brief Add a user to a group
+ * @param $uid Name of the user to add to group
+ * @param $gid Name of the group in which add the user
+ * @returns true/false
+ *
+ * Adds a user to a group.
+ */
+ public static function addToGroup($uid, $gid){}
+
+ /**
+ * @brief Removes a user from a group
+ * @param $uid NameUSER of the user to remove from group
+ * @param $gid Name of the group from which remove the user
+ * @returns true/false
+ *
+ * removes the user from a group.
+ */
+ public static function removeFromGroup($uid,$gid){}
+
+ /**
+ * @brief Get all groups a user belongs to
+ * @param $uid Name of the user
+ * @returns array with group names
+ *
+ * This function fetches all groups a user belongs to. It does not check
+ * if the user exists at all.
+ */
+ public static function getUserGroups($uid){}
+
+ /**
+ * @brief get a list of all groups
+ * @returns array with group names
+ *
+ * Returns a list with all groups
+ */
+ public static function getGroups(){}
+
+ /**
+ * @brief get a list of all users in a group
+ * @returns array with user ids
+ */
+ public static function usersInGroup($gid){}
+
+}
diff --git a/lib/helper.php b/lib/helper.php
index 0c6c73aa76b..c33db5f10fe 100644..100755
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -27,7 +27,7 @@
class OC_Helper {
private static $mimetypes=array();
private static $tmpFiles=array();
-
+
/**
* @brief Creates an url
* @param $app app
@@ -60,6 +60,28 @@ class OC_Helper {
}
/**
+ * @brief Returns the server host
+ * @returns the server host
+ *
+ * Returns the server host, even if the website uses one or more
+ * reverse proxies
+ */
+ public static function serverHost() {
+ if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
+ if (strpos($_SERVER['HTTP_X_FORWARDED_HOST'], ",") !== false) {
+ $host = trim(array_pop(explode(",", $_SERVER['HTTP_X_FORWARDED_HOST'])));
+ }
+ else{
+ $host=$_SERVER['HTTP_X_FORWARDED_HOST'];
+ }
+ }
+ else{
+ $host = $_SERVER['HTTP_HOST'];
+ }
+ return $host;
+ }
+
+ /**
* @brief Creates an absolute url
* @param $app app
* @param $file file
@@ -71,7 +93,7 @@ class OC_Helper {
$urlLinkTo = self::linkTo( $app, $file );
// Checking if the request was made through HTTPS. The last in line is for IIS
$protocol = isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS']!='off');
- $urlLinkTo = ($protocol?'https':'http') . '://' . $_SERVER['HTTP_HOST'] . $urlLinkTo;
+ $urlLinkTo = ($protocol?'https':'http') . '://' . self::serverHost() . $urlLinkTo;
return $urlLinkTo;
}
@@ -101,7 +123,7 @@ class OC_Helper {
}elseif( file_exists( OC::$SERVERROOT."/core/img/$image" )){
return OC::$WEBROOT."/core/img/$image";
}else{
- echo('image not found: image:'.$image.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
+ echo('image not found: image:'.$image.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
die();
}
}
@@ -166,7 +188,7 @@ class OC_Helper {
$bytes = round( $bytes / 1024, 1 );
return "$bytes GB";
}
-
+
/**
* @brief Make a computer file size
* @param $str file size in a fancy format
@@ -202,9 +224,9 @@ class OC_Helper {
$bytes = round($bytes, 2);
- return $bytes;
+ return $bytes;
}
-
+
/**
* @brief Recusive editing of file permissions
* @param $path path to file or folder
@@ -220,7 +242,7 @@ class OC_Helper {
$fullpath = $path.'/'.$file;
if(is_link($fullpath))
return FALSE;
- elseif(!is_dir($fullpath) && !chmod($fullpath, $filemode))
+ elseif(!is_dir($fullpath) && !@chmod($fullpath, $filemode))
return FALSE;
elseif(!self::chmodr($fullpath, $filemode))
return FALSE;
@@ -254,7 +276,7 @@ class OC_Helper {
copy($src, $dest);
}
}
-
+
/**
* @brief Recusive deletion of folders
* @param string $dir path to the folder
@@ -272,6 +294,9 @@ class OC_Helper {
}elseif(file_exists($dir)){
unlink($dir);
}
+ if(file_exists($dir)) {
+ return false;
+ }
}
/**
@@ -284,12 +309,10 @@ class OC_Helper {
$isWrapped=(strpos($path,'://')!==false) and (substr($path,0,7)=='file://');
$mimeType='application/octet-stream';
if ($mimeType=='application/octet-stream') {
- if(count(self::$mimetypes)>0){
- self::$mimetypes = include('mimetypes.fixlist.php');
- }
- $extention=strtolower(strrchr(basename($path), "."));
- $extention=substr($extention,1);//remove leading .
- $mimeType=(isset(self::$mimetypes[$extention]))?self::$mimetypes[$extention]:'application/octet-stream';
+ self::$mimetypes = include('mimetypes.fixlist.php');
+ $extension=strtolower(strrchr(basename($path), "."));
+ $extension=substr($extension,1);//remove leading .
+ $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
}
if (@is_dir($path)) {
@@ -323,13 +346,13 @@ class OC_Helper {
if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){
self::$mimetypes=include('mimetypes.list.php');
}
- $extention=strtolower(strrchr(basename($path), "."));
- $extention=substr($extention,1);//remove leading .
- $mimeType=(isset(self::$mimetypes[$extention]))?self::$mimetypes[$extention]:'application/octet-stream';
+ $extension=strtolower(strrchr(basename($path), "."));
+ $extension=substr($extension,1);//remove leading .
+ $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
}
return $mimeType;
}
-
+
/**
* @brief Checks $_REQUEST contains a var for the $s key. If so, returns the html-escaped value of this var; otherwise returns the default value provided by $d.
* @param $s name of the var to escape, if set.
@@ -337,16 +360,16 @@ class OC_Helper {
* @returns the print-safe value.
*
*/
-
+
//FIXME: should also check for value validation (i.e. the email is an email).
public static function init_var($s, $d="") {
$r = $d;
if(isset($_REQUEST[$s]) && !empty($_REQUEST[$s]))
$r = stripslashes(htmlspecialchars($_REQUEST[$s]));
-
+
return $r;
}
-
+
/**
* returns "checked"-attribut if request contains selected radio element OR if radio element is the default one -- maybe?
* @param string $s Name of radio-button element name
@@ -402,7 +425,7 @@ class OC_Helper {
}
return false;
}
-
+
/**
* copy the contents of one stream to another
* @param resource source
@@ -419,7 +442,7 @@ class OC_Helper {
}
return $count;
}
-
+
/**
* create a temporary file with an unique filename
* @param string postfix
@@ -434,14 +457,38 @@ class OC_Helper {
self::$tmpFiles[]=$file;
return $file;
}
-
+
+ /**
+ * create a temporary folder with an unique filename
+ * @return string
+ *
+ * temporary files are automatically cleaned up after the script is finished
+ */
+ public static function tmpFolder(){
+ $path=get_temp_dir().'/'.md5(time().rand());
+ mkdir($path);
+ self::$tmpFiles[]=$path;
+ return $path.'/';
+ }
+
/**
* remove all files created by self::tmpFile
*/
public static function cleanTmp(){
+ $leftoversFile='/tmp/oc-not-deleted';
+ if(file_exists($leftoversFile)){
+ $leftovers=file($leftoversFile);
+ foreach($leftovers as $file) {
+ self::rmdirr($file);
+ }
+ unlink($leftoversFile);
+ }
+
foreach(self::$tmpFiles as $file){
if(file_exists($file)){
- unlink($file);
+ if(!self::rmdirr($file)) {
+ file_put_contents($leftoversFile, $file."\n", FILE_APPEND);
+ }
}
}
}
diff --git a/lib/image.php b/lib/image.php
index 60a714880d0..4c53dc32f58 100644
--- a/lib/image.php
+++ b/lib/image.php
@@ -216,7 +216,7 @@ class OC_Image {
OC_Log::write('core','OC_Image->fixOrientation() No readable file path set.', OC_Log::DEBUG);
return false;
}
- $exif = @exif_read_data($this->filepath, 'IFD0');
+ $exif = @exif_read_data($this->filepath, 'IFD0');
if(!$exif) {
return false;
}
@@ -267,6 +267,7 @@ class OC_Image {
if($res) {
if(imagealphablending($res, true)) {
if(imagesavealpha($res, true)) {
+ imagedestroy($this->resource);
$this->resource = $res;
return true;
} else {
@@ -317,10 +318,7 @@ class OC_Image {
*/
public function loadFromFileHandle($handle) {
OC_Log::write('core',__METHOD__.'(): Trying', OC_Log::DEBUG);
- $contents = '';
- while (!feof($handle)) {
- $contents .= fread($handle, 8192);
- }
+ $contents = stream_get_contents($handle);
if($this->loadFromData($contents)) {
return $this->resource;
}
@@ -486,22 +484,24 @@ class OC_Image {
imagedestroy($process);
return false;
}
+ imagedestroy($this->resource);
$this->resource = $process;
return true;
}
/**
* @brief Crops the image to the middle square. If the image is already square it just returns.
+ * @param int maximum size for the result (optional)
* @returns bool for success or failure
*/
- public function centerCrop() {
+ public function centerCrop($size=0) {
if(!$this->valid()) {
OC_Log::write('core','OC_Image->centerCrop, No image loaded', OC_Log::ERROR);
return false;
}
$width_orig=imageSX($this->resource);
$height_orig=imageSY($this->resource);
- if($width_orig === $height_orig) {
+ if($width_orig === $height_orig and $size==0) {
return true;
}
$ratio_orig = $width_orig/$height_orig;
@@ -514,18 +514,26 @@ class OC_Image {
$y = ($height_orig/2) - ($height/2);
$x = 0;
}
- $process = imagecreatetruecolor($width, $height);
+ if($size>0){
+ $targetWidth=$size;
+ $targetHeight=$size;
+ }else{
+ $targetWidth=$width;
+ $targetHeight=$height;
+ }
+ $process = imagecreatetruecolor($targetWidth, $targetHeight);
if ($process == false) {
OC_Log::write('core','OC_Image->centerCrop. Error creating true color image',OC_Log::ERROR);
imagedestroy($process);
return false;
}
- imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $width, $height, $width, $height);
+ imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height);
if ($process == false) {
OC_Log::write('core','OC_Image->centerCrop. Error resampling process image '.$width.'x'.$height,OC_Log::ERROR);
imagedestroy($process);
return false;
}
+ imagedestroy($this->resource);
$this->resource = $process;
return true;
}
@@ -558,7 +566,19 @@ class OC_Image {
imagedestroy($process);
return false;
}
+ imagedestroy($this->resource);
$this->resource = $process;
return true;
}
+
+ public function destroy(){
+ if($this->valid()){
+ imagedestroy($this->resource);
+ }
+ $this->resource=null;
+ }
+
+ public function __destruct(){
+ $this->destroy();
+ }
}
diff --git a/lib/installer.php b/lib/installer.php
index 2a9676998f6..6edf4ce1b74 100644
--- a/lib/installer.php
+++ b/lib/installer.php
@@ -62,7 +62,7 @@ class OC_Installer{
//download the file if necesary
if($data['source']=='http'){
- $path=OC_Helper::tmpFile('.zip');
+ $path=OC_Helper::tmpFile();
if(!isset($data['href'])){
OC_Log::write('core','No href specified when installing app from http',OC_Log::ERROR);
return false;
@@ -76,14 +76,24 @@ class OC_Installer{
$path=$data['path'];
}
+ //detect the archive type
+ $mime=OC_Helper::getMimeType($path);
+ if($mime=='application/zip'){
+ rename($path,$path.'.zip');
+ $path.='.zip';
+ }elseif($mime=='application/x-gzip'){
+ rename($path,$path.'.tgz');
+ $path.='.tgz';
+ }else{
+ OC_Log::write('core','Archives of type '.$mime.' are not supported',OC_Log::ERROR);
+ return false;
+ }
+
//extract the archive in a temporary folder
- $extractDir=tempnam(get_temp_dir(),'oc_installer_uncompressed_');
- unlink($extractDir);
+ $extractDir=OC_Helper::tmpFolder();
mkdir($extractDir);
- $zip = new ZipArchive;
- if($zip->open($path)===true){
- $zip->extractTo($extractDir);
- $zip->close();
+ if($archive=OC_Archive::open($path)){
+ $archive->extract($extractDir);
} else {
OC_Log::write('core','Failed to open archive when installing app',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
@@ -95,6 +105,17 @@ class OC_Installer{
//load the info.xml file of the app
if(!is_file($extractDir.'/appinfo/info.xml')){
+ //try to find it in a subdir
+ $dh=opendir($extractDir);
+ while($folder=readdir($dh)){
+ if(substr($folder,0,1)!='.' and is_dir($extractDir.'/'.$folder)){
+ if(is_file($extractDir.'/'.$folder.'/appinfo/info.xml')){
+ $extractDir.='/'.$folder;
+ }
+ }
+ }
+ }
+ if(!is_file($extractDir.'/appinfo/info.xml')){
OC_Log::write('core','App does not provide an info.xml file',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
if($data['source']=='http'){
@@ -102,7 +123,7 @@ class OC_Installer{
}
return false;
}
- $info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml');
+ $info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml',true);
$basedir=OC::$APPSROOT.'/apps/'.$info['id'];
//check if an app with the same id is already installed
@@ -154,7 +175,7 @@ class OC_Installer{
}
//set the installed version
- OC_Appconfig::setValue($info['id'],'installed_version',$info['version']);
+ OC_Appconfig::setValue($info['id'],'installed_version',OC_App::getAppVersion($info['id']));
OC_Appconfig::setValue($info['id'],'enabled','no');
return $info['id'];
}
@@ -275,8 +296,8 @@ class OC_Installer{
if(is_file(OC::$APPSROOT."/apps/$app/appinfo/install.php")){
include(OC::$APPSROOT."/apps/$app/appinfo/install.php");
}
- $info=OC_App::getAppInfo(OC::$APPSROOT."/apps/$app/appinfo/info.xml");
- OC_Appconfig::setValue($app,'installed_version',$info['version']);
+ $info=OC_App::getAppInfo($app);
+ OC_Appconfig::setValue($app,'installed_version',OC_App::getAppVersion($app));
return $info;
}
}
diff --git a/lib/json.php b/lib/json.php
index cedf79fd7c3..0d208ce12a2 100644
--- a/lib/json.php
+++ b/lib/json.php
@@ -24,7 +24,7 @@ class OC_JSON{
*/
public static function checkAppEnabled($app){
if( !OC_App::isEnabled($app)){
- $l = new OC_L10N('core');
+ $l = OC_L10N::get('core');
self::error(array( 'data' => array( 'message' => $l->t('Application is not enabled') )));
exit();
}
@@ -35,7 +35,7 @@ class OC_JSON{
*/
public static function checkLoggedIn(){
if( !OC_User::isLoggedIn()){
- $l = new OC_L10N('core');
+ $l = OC_L10N::get('core');
self::error(array( 'data' => array( 'message' => $l->t('Authentication error') )));
exit();
}
@@ -47,7 +47,7 @@ class OC_JSON{
public static function checkAdminUser(){
self::checkLoggedIn();
if( !OC_Group::inGroup( OC_User::getUser(), 'admin' )){
- $l = new OC_L10N('core');
+ $l = OC_L10N::get('core');
self::error(array( 'data' => array( 'message' => $l->t('Authentication error') )));
exit();
}
diff --git a/lib/l10n.php b/lib/l10n.php
index 636326f9864..c0ecdbd1b70 100644
--- a/lib/l10n.php
+++ b/lib/l10n.php
@@ -25,6 +25,11 @@
*/
class OC_L10N{
/**
+ * cached instances
+ */
+ protected static $instances=array();
+
+ /**
* cache
*/
protected static $cache = array();
@@ -46,6 +51,21 @@ class OC_L10N{
'date' => 'd.m.Y',
'datetime' => 'd.m.Y H:i:s',
'time' => 'H:i:s');
+
+ /**
+ * get an L10N instance
+ * @return OC_L10N
+ */
+ public static function get($app,$lang=null){
+ if(is_null($lang)){
+ if(!isset(self::$instances[$app])){
+ self::$instances[$app]=new OC_L10N($app);
+ }
+ return self::$instances[$app];
+ }else{
+ return new OC_L10N($app,$lang);
+ }
+ }
/**
* @brief The constructor
@@ -261,17 +281,14 @@ class OC_L10N{
public static function findAvailableLanguages($app=null){
$available=array('en');//english is always available
$dir = self::findI18nDir($app);
- if(file_exists($dir)){
- $dh = opendir($dir);
- while(($file = readdir($dh)) !== false){
- if(substr($file, -4, 4) == '.php' and (strlen($file) == 6 || strlen($file) == 9)){
+ if(is_dir($dir)){
+ $files=scandir($dir);
+ foreach($files as $file){
+ if(substr($file, -4, 4) == '.php'){
$i = substr($file, 0, -4);
- if($i != ''){
- $available[] = $i;
- }
+ $available[] = $i;
}
}
- closedir($dh);
}
return $available;
}
diff --git a/lib/log.php b/lib/log.php
index 4e450a027f5..8bb2839be66 100644
--- a/lib/log.php
+++ b/lib/log.php
@@ -1,78 +1,39 @@
<?php
/**
- * ownCloud
- *
- * @author Robin Appelman
- * @copyright 2012 Robin Appelman icewind1991@gmail.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/>.
- *
+ * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
*/
/**
- *logging utilities
+ * logging utilities
*
- * Log is saved at data/owncloud.log (on default)
+ * Log is saved by default at data/owncloud.log using OC_Log_Owncloud.
+ * Selecting other backend is done with a config option 'log_type'.
*/
-class OC_Log{
+class OC_Log {
const DEBUG=0;
const INFO=1;
const WARN=2;
const ERROR=3;
const FATAL=4;
+ static protected $class = null;
+
/**
* write a message in the log
* @param string $app
* @param string $message
* @param int level
*/
- public static function write($app,$message,$level){
- $minLevel=OC_Config::getValue( "loglevel", 2 );
- if($level>=$minLevel){
- $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
- $logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
- $entry=array('app'=>$app,'message'=>$message,'level'=>$level,'time'=>time());
- $fh=fopen($logFile,'a');
- fwrite($fh,json_encode($entry)."\n");
- fclose($fh);
- }
- }
-
- /**
- * get entries from the log in reverse chronological order
- * @param int limit
- * @param int offset
- * @return array
- */
- public static function getEntries($limit=50,$offset=0){
- $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
- $logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
- $entries=array();
- if(!file_exists($logFile)){
- return array();
- }
- $contents=file($logFile);
- if(!$contents){//error while reading log
- return array();
- }
- $end=max(count($contents)-$offset-1,0);
- $start=max($end-$limit,0);
- for($i=$end;$i>$start;$i--){
- $entries[]=json_decode($contents[$i]);
+ public static function write($app, $message, $level) {
+ if (!self::$class) {
+ self::$class = 'OC_Log_'.ucfirst(OC_Config::getValue('log_type', 'owncloud'));
+ call_user_func(array(self::$class, 'init'));
}
- return $entries;
+ $log_class=self::$class;
+ $log_class::write($app, $message, $level);
}
}
diff --git a/lib/log/owncloud.php b/lib/log/owncloud.php
new file mode 100644
index 00000000000..0ed30510134
--- /dev/null
+++ b/lib/log/owncloud.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Robin Appelman
+ * @copyright 2012 Robin Appelman icewind1991@gmail.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/>.
+ *
+ */
+
+/**
+ * logging utilities
+ *
+ * Log is saved at data/owncloud.log (on default)
+ */
+
+class OC_Log_Owncloud {
+ static protected $logFile;
+
+ /**
+ * Init class data
+ */
+ public static function init() {
+ $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
+ self::$logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
+ }
+
+ /**
+ * write a message in the log
+ * @param string $app
+ * @param string $message
+ * @param int level
+ */
+ public static function write($app, $message, $level) {
+ $minLevel=OC_Config::getValue( "loglevel", 2 );
+ if($level>=$minLevel){
+ $entry=array('app'=>$app, 'message'=>$message, 'level'=>$level,'time'=>time());
+ $fh=fopen(self::$logFile, 'a');
+ fwrite($fh, json_encode($entry)."\n");
+ fclose($fh);
+ }
+ }
+
+ /**
+ * get entries from the log in reverse chronological order
+ * @param int limit
+ * @param int offset
+ * @return array
+ */
+ public static function getEntries($limit=50, $offset=0){
+ self::init();
+ $entries=array();
+ if(!file_exists(self::$logFile)) {
+ return array();
+ }
+ $contents=file(self::$logFile);
+ if(!$contents) {//error while reading log
+ return array();
+ }
+ $end=max(count($contents)-$offset-1, 0);
+ $start=max($end-$limit,0);
+ for($i=$end;$i>$start;$i--) {
+ $entries[]=json_decode($contents[$i]);
+ }
+ return $entries;
+ }
+}
diff --git a/lib/log/syslog.php b/lib/log/syslog.php
new file mode 100644
index 00000000000..d1fb28d8b0a
--- /dev/null
+++ b/lib/log/syslog.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class OC_Log_Syslog {
+ static protected $levels = array(
+ OC_Log::DEBUG => LOG_DEBUG,
+ OC_Log::INFO => LOG_INFO,
+ OC_Log::WARN => LOG_WARNING,
+ OC_Log::ERROR => LOG_ERR,
+ OC_Log::FATAL => LOG_CRIT,
+ );
+
+ /**
+ * Init class data
+ */
+ public static function init() {
+ openlog('ownCloud', LOG_PID | LOG_CONS, LOG_USER);
+ // Close at shutdown
+ register_shutdown_function('closelog');
+ }
+
+ /**
+ * write a message in the log
+ * @param string $app
+ * @param string $message
+ * @param int level
+ */
+ public static function write($app, $message, $level) {
+ $syslog_level = self::$levels[$level];
+ syslog($syslog_level, '{'.$app.'} '.$message);
+ }
+}
diff --git a/lib/migrate.php b/lib/migrate.php
new file mode 100644
index 00000000000..f46d860e806
--- /dev/null
+++ b/lib/migrate.php
@@ -0,0 +1,715 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Tom Needham
+ * @copyright 2012 Tom Needham tom@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/>.
+ *
+ */
+
+
+/**
+ * provides an interface to migrate users and whole ownclouds
+ */
+class OC_Migrate{
+
+
+ // Array of OC_Migration_Provider objects
+ static private $providers=array();
+ // User id of the user to import/export
+ static private $uid=false;
+ // Holds the ZipArchive object
+ static private $zip=false;
+ // Stores the type of export
+ static private $exporttype=false;
+ // Array of temp files to be deleted after zip creation
+ static private $tmpfiles=array();
+ // Holds the db object
+ static private $MDB2=false;
+ // Schema db object
+ static private $schema=false;
+ // Path to the sqlite db
+ static private $dbpath=false;
+ // Holds the path to the zip file
+ static private $zippath=false;
+ // Holds the OC_Migration_Content object
+ static private $content=false;
+
+ /**
+ * register a new migration provider
+ * @param OC_Migrate_Provider $provider
+ */
+ public static function registerProvider($provider){
+ self::$providers[]=$provider;
+ }
+
+ /**
+ * @brief finds and loads the providers
+ */
+ static private function findProviders(){
+ // Find the providers
+ $apps = OC_App::getAllApps();
+
+ foreach($apps as $app){
+ $path = OC::$SERVERROOT . '/apps/' . $app . '/appinfo/migrate.php';
+ if( file_exists( $path ) ){
+ include( $path );
+ }
+ }
+ }
+
+ /**
+ * @brief exports a user, or owncloud instance
+ * @param optional $uid string user id of user to export if export type is user, defaults to current
+ * @param ootional $type string type of export, defualts to user
+ * @param otional $path string path to zip output folder
+ * @return false on error, path to zip on success
+ */
+ public static function export( $uid=null, $type='user', $path=null ){
+ $datadir = OC_Config::getValue( 'datadirectory' );
+ // Validate export type
+ $types = array( 'user', 'instance', 'system', 'userfiles' );
+ if( !in_array( $type, $types ) ){
+ OC_Log::write( 'migration', 'Invalid export type', OC_Log::ERROR );
+ return json_encode( array( array( 'success' => false ) ) );
+ }
+ self::$exporttype = $type;
+ // Userid?
+ if( self::$exporttype == 'user' ){
+ // Check user exists
+ if( !is_null($uid) ){
+ $db = new OC_User_Database;
+ if( !$db->userExists( $uid ) ){
+ OC_Log::write('migration', 'User: '.$uid.' is not in the database and so cannot be exported.', OC_Log::ERROR);
+ return json_encode( array( 'success' => false ) );
+ }
+ self::$uid = $uid;
+ } else {
+ self::$uid = OC_User::getUser();
+ }
+ }
+ // Calculate zipname
+ if( self::$exporttype == 'user' ){
+ $zipname = 'oc_export_' . self::$uid . '_' . date("y-m-d_H-i-s") . '.zip';
+ } else {
+ $zipname = 'oc_export_' . self::$exporttype . '_' . date("y-m-d_H-i-s") . '.zip';
+ }
+ // Calculate path
+ if( self::$exporttype == 'user' ){
+ self::$zippath = $datadir . '/' . self::$uid . '/' . $zipname;
+ } else {
+ if( !is_null( $path ) ){
+ // Validate custom path
+ if( !file_exists( $path ) || !is_writeable( $path ) ){
+ OC_Log::write( 'migration', 'Path supplied is invalid.', OC_Log::ERROR );
+ return json_encode( array( 'success' => false ) );
+ }
+ self::$zippath = $path . $zipname;
+ } else {
+ // Default path
+ self::$zippath = get_temp_dir() . '/' . $zipname;
+ }
+ }
+ // Create the zip object
+ if( !self::createZip() ){
+ return json_encode( array( 'success' => false ) );
+ }
+ // Do the export
+ self::findProviders();
+ $exportdata = array();
+ switch( self::$exporttype ){
+ case 'user':
+ // Connect to the db
+ self::$dbpath = $datadir . '/' . self::$uid . '/migration.db';
+ if( !self::connectDB() ){
+ return json_encode( array( 'success' => false ) );
+ }
+ self::$content = new OC_Migration_Content( self::$zip, self::$MDB2 );
+ // Export the app info
+ $exportdata = self::exportAppData();
+ // Add the data dir to the zip
+ self::$content->addDir( $datadir . '/' . self::$uid, true, '/' );
+ break;
+ case 'instance':
+ self::$content = new OC_Migration_Content( self::$zip );
+ // Creates a zip that is compatable with the import function
+ $dbfile = tempnam( "/tmp", "owncloud_export_data_" );
+ OC_DB::getDbStructure( $dbfile, 'MDB2_SCHEMA_DUMP_ALL');
+
+ // Now add in *dbname* and *dbprefix*
+ $dbexport = file_get_contents( $dbfile );
+ $dbnamestring = "<database>\n\n <name>" . OC_Config::getValue( "dbname", "owncloud" );
+ $dbtableprefixstring = "<table>\n\n <name>" . OC_Config::getValue( "dbtableprefix", "oc_" );
+ $dbexport = str_replace( $dbnamestring, "<database>\n\n <name>*dbname*", $dbexport );
+ $dbexport = str_replace( $dbtableprefixstring, "<table>\n\n <name>*dbprefix*", $dbexport );
+ // Add the export to the zip
+ self::$content->addFromString( $dbexport, "dbexport.xml" );
+ // Add user data
+ foreach(OC_User::getUsers() as $user){
+ self::$content->addDir( $datadir . '/' . $user . '/', true, "/userdata/" );
+ }
+ break;
+ case 'userfiles':
+ self::$content = new OC_Migration_Content( self::$zip );
+ // Creates a zip with all of the users files
+ foreach(OC_User::getUsers() as $user){
+ self::$content->addDir( $datadir . '/' . $user . '/', true, "/" );
+ }
+ break;
+ case 'system':
+ self::$content = new OC_Migration_Content( self::$zip );
+ // Creates a zip with the owncloud system files
+ self::$content->addDir( OC::$SERVERROOT . '/', false, '/');
+ foreach (array(".git", "3rdparty", "apps", "core", "files", "l10n", "lib", "ocs", "search", "settings", "tests") as $dir) {
+ self::$content->addDir( OC::$SERVERROOT . '/' . $dir, true, "/");
+ }
+ break;
+ }
+ if( !$info = self::getExportInfo( $exportdata ) ){
+ return json_encode( array( 'success' => false ) );
+ }
+ // Add the export info json to the export zip
+ self::$content->addFromString( $info, 'export_info.json' );
+ if( !self::$content->finish() ){
+ return json_encode( array( 'success' => false ) );
+ }
+ return json_encode( array( 'success' => true, 'data' => self::$zippath ) );
+ }
+
+ /**
+ * @brief imports a user, or owncloud instance
+ * @param $path string path to zip
+ * @param optional $type type of import (user or instance)
+ * @param optional $uid userid of new user
+ */
+ public static function import( $path, $type='user', $uid=null ){
+ OC_Util::checkAdminUser();
+ $datadir = OC_Config::getValue( 'datadirectory' );
+ // Extract the zip
+ if( !$extractpath = self::extractZip( $path ) ){
+ return json_encode( array( 'success' => false ) );
+ }
+ // Get export_info.json
+ $scan = scandir( $extractpath );
+ // Check for export_info.json
+ if( !in_array( 'export_info.json', $scan ) ){
+ OC_Log::write( 'migration', 'Invalid import file, export_info.json note found', OC_Log::ERROR );
+ return json_encode( array( 'success' => false ) );
+ }
+ $json = json_decode( file_get_contents( $extractpath . 'export_info.json' ) );
+ if( $json->exporttype != $type ){
+ OC_Log::write( 'migration', 'Invalid import file', OC_Log::ERROR );
+ return json_encode( array( 'success' => false ) );
+ }
+ self::$exporttype = $type;
+
+ // Have we got a user if type is user
+ if( self::$exporttype == 'user' ){
+ if( !$uid ){
+ self::$uid = $json->exporteduser;
+ } else {
+ self::$uid = $uid;
+ }
+ }
+
+ // Handle export types
+ switch( self::$exporttype ){
+ case 'user':
+ // Check user availability
+ if( OC_User::userExists( self::$uid ) ){
+ OC_Log::write( 'migration', 'User already exists', OC_Log::ERROR );
+ return json_encode( array( 'success' => false ) );
+ }
+ $run = true;
+ OC_Hook::emit( "OC_User", "pre_createUser", array( "run" => &$run, "uid" => self::$uid, "password" => $json->hash ));
+ if( !$run ){
+ // Something stopped the user creation
+ OC_Log::write( 'migration', 'User creation failed', OC_Log::ERROR );
+ return json_encode( array( 'success' => false ) );
+ }
+ // Create the user
+ if( !self::createUser( self::$uid, $json->hash ) ){
+ return json_encode( array( 'success' => false ) );
+ }
+ // Emit the post_createUser hook (password is already hashed, will cause problems
+ OC_Hook::emit( "OC_User", "post_createUser", array( "uid" => self::$uid, "password" => $json->hash ));
+ // Make the new users data dir
+ $path = $datadir . '/' . self::$uid;
+ if( !mkdir( $path, 0755, true ) ){
+ OC_Log::write( 'migration', 'Failed to create users data dir: '.$path, OC_Log::ERROR );
+ return json_encode( array( 'success' => false ) );
+ }
+ // Copy data
+ if( !self::copy_r( $extractpath . $json->exporteduser, $datadir . '/' . self::$uid ) ){
+ return json_encode( array( 'success' => false ) );
+ }
+ // Import user app data
+ if( !$appsimported = self::importAppData( $extractpath . $json->exporteduser . '/migration.db', $json, self::$uid ) ){
+ return json_encode( array( 'success' => false ) );
+ }
+ // All done!
+ if( !self::unlink_r( $extractpath ) ){
+ OC_Log::write( 'migration', 'Failed to delete the extracted zip', OC_Log::ERROR );
+ }
+ return json_encode( array( 'success' => true, 'data' => $appsimported ) );
+ break;
+ case 'instance':
+ /*
+ * EXPERIMENTAL
+ // Check for new data dir and dbexport before doing anything
+ // TODO
+
+ // Delete current data folder.
+ OC_Log::write( 'migration', "Deleting current data dir", OC_Log::INFO );
+ if( !self::unlink_r( $datadir, false ) ){
+ OC_Log::write( 'migration', 'Failed to delete the current data dir', OC_Log::ERROR );
+ return json_encode( array( 'success' => false ) );
+ }
+
+ // Copy over data
+ if( !self::copy_r( $extractpath . 'userdata', $datadir ) ){
+ OC_Log::write( 'migration', 'Failed to copy over data directory', OC_Log::ERROR );
+ return json_encode( array( 'success' => false ) );
+ }
+
+ // Import the db
+ if( !OC_DB::replaceDB( $extractpath . 'dbexport.xml' ) ){
+ return json_encode( array( 'success' => false ) );
+ }
+ // Done
+ return json_encode( 'success' => true );
+ */
+ break;
+ }
+
+ }
+
+ /**
+ * @brief recursively deletes a directory
+ * @param $dir string path of dir to delete
+ * $param optional $deleteRootToo bool delete the root directory
+ * @return bool
+ */
+ private static function unlink_r( $dir, $deleteRootToo=true ){
+ if( !$dh = @opendir( $dir ) ){
+ return false;
+ }
+ while (false !== ($obj = readdir($dh))){
+ if($obj == '.' || $obj == '..') {
+ continue;
+ }
+ if (!@unlink($dir . '/' . $obj)){
+ self::unlink_r($dir.'/'.$obj, true);
+ }
+ }
+ closedir($dh);
+ if ( $deleteRootToo ) {
+ @rmdir($dir);
+ }
+ return true;
+ }
+
+ /**
+ * @brief copies recursively
+ * @param $path string path to source folder
+ * @param $dest string path to destination
+ * @return bool
+ */
+ private static function copy_r( $path, $dest ){
+ if( is_dir($path) ){
+ @mkdir( $dest );
+ $objects = scandir( $path );
+ if( sizeof( $objects ) > 0 ){
+ foreach( $objects as $file ){
+ if( $file == "." || $file == ".." )
+ continue;
+ // go on
+ if( is_dir( $path . '/' . $file ) ){
+ self::copy_r( $path .'/' . $file, $dest . '/' . $file );
+ } else {
+ copy( $path . '/' . $file, $dest . '/' . $file );
+ }
+ }
+ }
+ return true;
+ }
+ elseif( is_file( $path ) ){
+ return copy( $path, $dest );
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @brief tries to extract the import zip
+ * @param $path string path to the zip
+ * @return string path to extract location (with a trailing slash) or false on failure
+ */
+ static private function extractZip( $path ){
+ self::$zip = new ZipArchive;
+ // Validate path
+ if( !file_exists( $path ) ){
+ OC_Log::write( 'migration', 'Zip not found', OC_Log::ERROR );
+ return false;
+ }
+ if ( self::$zip->open( $path ) != TRUE ) {
+ OC_Log::write( 'migration', "Failed to open zip file", OC_Log::ERROR );
+ return false;
+ }
+ $to = get_temp_dir() . '/oc_import_' . self::$exporttype . '_' . date("y-m-d_H-i-s") . '/';
+ if( !self::$zip->extractTo( $to ) ){
+ return false;
+ }
+ self::$zip->close();
+ return $to;
+ }
+
+ /**
+ * @brief connects to a MDB2 database scheme
+ * @returns bool
+ */
+ static private function connectScheme(){
+ // We need a mdb2 database connection
+ self::$MDB2->loadModule( 'Manager' );
+ self::$MDB2->loadModule( 'Reverse' );
+
+ // Connect if this did not happen before
+ if( !self::$schema ){
+ require_once('MDB2/Schema.php');
+ self::$schema=MDB2_Schema::factory( self::$MDB2 );
+ }
+
+ return true;
+ }
+
+ /**
+ * @brief creates a migration.db in the users data dir with their app data in
+ * @return bool whether operation was successfull
+ */
+ private static function exportAppData( ){
+
+ $success = true;
+ $return = array();
+
+ // Foreach provider
+ foreach( self::$providers as $provider ){
+ $success = true;
+ // Does this app use the database?
+ if( file_exists( OC::$SERVERROOT.'/apps/'.$provider->getID().'/appinfo/database.xml' ) ){
+ // Create some app tables
+ $tables = self::createAppTables( $provider->getID() );
+ if( is_array( $tables ) ){
+ // Save the table names
+ foreach($tables as $table){
+ $return['apps'][$provider->getID()]['tables'][] = $table;
+ }
+ } else {
+ // It failed to create the tables
+ $success = false;
+ }
+ }
+
+ // Run the export function?
+ if( $success ){
+ // Set the provider properties
+ $provider->setData( self::$uid, self::$content );
+ $return['apps'][$provider->getID()]['success'] = $provider->export();
+ } else {
+ $return['apps'][$provider->getID()]['success'] = false;
+ $return['apps'][$provider->getID()]['message'] = 'failed to create the app tables';
+ }
+
+ // Now add some app info the the return array
+ $appinfo = OC_App::getAppInfo( $provider->getID() );
+ $return['apps'][$provider->getID()]['version'] = OC_App::getAppVersion($provider->getID());
+
+ }
+
+ return $return;
+
+ }
+
+
+ /**
+ * @brief generates json containing export info, and merges any data supplied
+ * @param optional $array array of data to include in the returned json
+ * @return bool
+ */
+ static private function getExportInfo( $array=array() ){
+ $info = array(
+ 'ocversion' => OC_Util::getVersion(),
+ 'exporttime' => time(),
+ 'exportedby' => OC_User::getUser(),
+ 'exporttype' => self::$exporttype
+ );
+ // Add hash if user export
+ if( self::$exporttype == 'user' ){
+ $query = OC_DB::prepare( "SELECT password FROM *PREFIX*users WHERE uid LIKE ?" );
+ $result = $query->execute( array( self::$uid ) );
+ $row = $result->fetchRow();
+ $hash = $row ? $row['password'] : false;
+ if( !$hash ){
+ OC_Log::write( 'migration', 'Failed to get the users password hash', OC_log::ERROR);
+ return false;
+ }
+ $info['hash'] = $hash;
+ $info['exporteduser'] = self::$uid;
+ }
+ if( !is_array( $array ) ){
+ OC_Log::write( 'migration', 'Supplied $array was not an array in getExportInfo()', OC_Log::ERROR );
+ }
+ // Merge in other data
+ $info = array_merge( $info, (array)$array );
+ // Create json
+ $json = json_encode( $info );
+ return $json;
+ }
+
+ /**
+ * @brief connects to migration.db, or creates if not found
+ * @param $db optional path to migration.db, defaults to user data dir
+ * @return bool whether the operation was successful
+ */
+ static private function connectDB( $path=null ){
+ // Has the dbpath been set?
+ self::$dbpath = !is_null( $path ) ? $path : self::$dbpath;
+ if( !self::$dbpath ){
+ OC_Log::write( 'migration', 'connectDB() was called without dbpath being set', OC_Log::ERROR );
+ return false;
+ }
+ // Already connected
+ if(!self::$MDB2){
+ require_once('MDB2.php');
+
+ $datadir = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" );
+
+ // DB type
+ if( class_exists( 'SQLite3' ) ){
+ $dbtype = 'sqlite3';
+ } else if( is_callable( 'sqlite_open' ) ){
+ $dbtype = 'sqlite';
+ } else {
+ OC_Log::write( 'migration', 'SQLite not found', OC_Log::ERROR );
+ return false;
+ }
+
+ // Prepare options array
+ $options = array(
+ 'portability' => MDB2_PORTABILITY_ALL & (!MDB2_PORTABILITY_FIX_CASE),
+ 'log_line_break' => '<br>',
+ 'idxname_format' => '%s',
+ 'debug' => true,
+ 'quote_identifier' => true
+ );
+ $dsn = array(
+ 'phptype' => $dbtype,
+ 'database' => self::$dbpath,
+ 'mode' => '0644'
+ );
+
+ // Try to establish connection
+ self::$MDB2 = MDB2::factory( $dsn, $options );
+ // Die if we could not connect
+ if( PEAR::isError( self::$MDB2 ) ){
+ die( self::$MDB2->getMessage() );
+ OC_Log::write( 'migration', 'Failed to create/connect to migration.db', OC_Log::FATAL );
+ OC_Log::write( 'migration', self::$MDB2->getUserInfo(), OC_Log::FATAL );
+ OC_Log::write( 'migration', self::$MDB2->getMessage(), OC_Log::FATAL );
+ return false;
+ }
+ // We always, really always want associative arrays
+ self::$MDB2->setFetchMode(MDB2_FETCHMODE_ASSOC);
+ }
+ return true;
+
+ }
+
+ /**
+ * @brief creates the tables in migration.db from an apps database.xml
+ * @param $appid string id of the app
+ * @return bool whether the operation was successful
+ */
+ static private function createAppTables( $appid ){
+
+ if( !self::connectScheme() ){
+ return false;
+ }
+
+ // There is a database.xml file
+ $content = file_get_contents( OC::$SERVERROOT . '/apps/' . $appid . '/appinfo/database.xml' );
+
+ $file2 = 'static://db_scheme';
+ // TODO get the relative path to migration.db from the data dir
+ // For now just cheat
+ $path = pathinfo( self::$dbpath );
+ $content = str_replace( '*dbname*', self::$uid.'/migration', $content );
+ $content = str_replace( '*dbprefix*', '', $content );
+
+ $xml = new SimpleXMLElement($content);
+ foreach($xml->table as $table){
+ $tables[] = (string)$table->name;
+ }
+
+ file_put_contents( $file2, $content );
+
+ // Try to create tables
+ $definition = self::$schema->parseDatabaseDefinitionFile( $file2 );
+
+ unlink( $file2 );
+
+ // Die in case something went wrong
+ if( $definition instanceof MDB2_Schema_Error ){
+ OC_Log::write( 'migration', 'Failed to parse database.xml for: '.$appid, OC_Log::FATAL );
+ OC_Log::write( 'migration', $definition->getMessage().': '.$definition->getUserInfo(), OC_Log::FATAL );
+ return false;
+ }
+
+ $definition['overwrite'] = true;
+
+ $ret = self::$schema->createDatabase( $definition );
+
+ // Die in case something went wrong
+ if( $ret instanceof MDB2_Error ){
+ OC_Log::write( 'migration', 'Failed to create tables for: '.$appid, OC_Log::FATAL );
+ OC_Log::write( 'migration', $ret->getMessage().': '.$ret->getUserInfo(), OC_Log::FATAL );
+ return false;
+ }
+ return $tables;
+
+ }
+
+ /**
+ * @brief tries to create the zip
+ * @param $path string path to zip destination
+ * @return bool
+ */
+ static private function createZip(){
+ self::$zip = new ZipArchive;
+ // Check if properties are set
+ if( !self::$zippath ){
+ OC_Log::write('migration', 'createZip() called but $zip and/or $zippath have not been set', OC_Log::ERROR);
+ return false;
+ }
+ if ( self::$zip->open( self::$zippath, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE ) !== TRUE ) {
+ OC_Log::write('migration', 'Failed to create the zip with error: '.self::$zip->getStatusString(), OC_Log::ERROR);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * @brief returns an array of apps that support migration
+ * @return array
+ */
+ static public function getApps(){
+ $allapps = OC_App::getAllApps();
+ foreach($allapps as $app){
+ $path = OC::$SERVERROOT . '/apps/' . $app . '/lib/migrate.php';
+ if( file_exists( $path ) ){
+ $supportsmigration[] = $app;
+ }
+ }
+ return $supportsmigration;
+ }
+
+ /**
+ * @brief imports a new user
+ * @param $db string path to migration.db
+ * @param $info object of migration info
+ * @param $uid optional uid to use
+ * @return array of apps with import statuses, or false on failure.
+ */
+ public static function importAppData( $db, $info, $uid=null ){
+ // Check if the db exists
+ if( file_exists( $db ) ){
+ // Connect to the db
+ if(!self::connectDB( $db )){
+ OC_Log::write('migration','Failed to connect to migration.db',OC_Log::ERROR);
+ return false;
+ }
+ } else {
+ OC_Log::write('migration','Migration.db not found at: '.$db, OC_Log::FATAL );
+ return false;
+ }
+
+ // Find providers
+ self::findProviders();
+
+ // Generate importinfo array
+ $importinfo = array(
+ 'olduid' => $info->exporteduser,
+ 'newuid' => self::$uid
+ );
+
+ foreach( self::$providers as $provider){
+ // Is the app in the export?
+ $id = $provider->getID();
+ if( isset( $info->apps->$id ) ){
+ // Is the app installed
+ if( !OC_App::isEnabled( $id ) ){
+ OC_Log::write( 'migration', 'App: ' . $id . ' is not installed, can\'t import data.', OC_Log::INFO );
+ $appsstatus[$id] = 'notsupported';
+ } else {
+ // Did it succeed on export?
+ if( $info->apps->$id->success ){
+ // Give the provider the content object
+ if( !self::connectDB( $db ) ){
+ return false;
+ }
+ $content = new OC_Migration_Content( self::$zip, self::$MDB2 );
+ $provider->setData( self::$uid, $content, $info );
+ // Then do the import
+ if( !$appsstatus[$id] = $provider->import( $info->apps->$id, $importinfo ) ){
+ // Failed to import app
+ OC_Log::write( 'migration', 'Failed to import app data for user: ' . self::$uid . ' for app: ' . $id, OC_Log::ERROR );
+ }
+ } else {
+ // Add to failed list
+ $appsstatus[$id] = false;
+ }
+ }
+ }
+ }
+
+ return $appsstatus;
+
+ }
+
+ /*
+ * @brief creates a new user in the database
+ * @param $uid string user_id of the user to be created
+ * @param $hash string hash of the user to be created
+ * @return bool result of user creation
+ */
+ public static function createUser( $uid, $hash ){
+
+ // Check if userid exists
+ if(OC_User::userExists( $uid )){
+ return false;
+ }
+
+ // Create the user
+ $query = OC_DB::prepare( "INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )" );
+ $result = $query->execute( array( $uid, $hash));
+ if( !$result ){
+ OC_Log::write('migration', 'Failed to create the new user "'.$uid."");
+ }
+ return $result ? true : false;
+
+ }
+
+}
diff --git a/lib/migration/content.php b/lib/migration/content.php
new file mode 100644
index 00000000000..7ef88f36e43
--- /dev/null
+++ b/lib/migration/content.php
@@ -0,0 +1,252 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Tom Needham
+ * @copyright 2012 Tom Needham tom@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/>.
+ *
+ */
+
+
+/**
+ * provides methods to add and access data from the migration
+ */
+class OC_Migration_Content{
+
+ private $zip=false;
+ // Holds the MDB2 object
+ private $db=null;
+ // Holds an array of tmpfiles to delete after zip creation
+ private $tmpfiles=false;
+
+ /**
+ * @brief sets up the
+ * @param $zip ZipArchive object
+ * @param optional $db a MDB2 database object (required for exporttype user)
+ * @return bool
+ */
+ public function __construct( $zip, $db=null ){
+
+ $this->zip = $zip;
+ $this->db = $db;
+
+ if( !is_null( $db ) ){
+ // Get db path
+ $db = $this->db->getDatabase();
+ $this->tmpfiles[] = $db;
+ }
+
+ }
+
+ // @brief prepares the db
+ // @param $query the sql query to prepare
+ public function prepare( $query ){
+
+ // Optimize the query
+ $query = $this->processQuery( $query );
+
+ // Optimize the query
+ $query = $this->db->prepare( $query );
+
+ // Die if we have an error (error means: bad query, not 0 results!)
+ if( PEAR::isError( $query ) ) {
+ $entry = 'DB Error: "'.$result->getMessage().'"<br />';
+ $entry .= 'Offending command was: '.$query.'<br />';
+ OC_Log::write( 'migration', $entry, OC_Log::FATAL );
+ return false;
+ } else {
+ return $query;
+ }
+
+ }
+
+ /**
+ * @brief processes the db query
+ * @param $query the query to process
+ * @return string of processed query
+ */
+ private function processQuery( $query ){
+ $query = str_replace( '`', '\'', $query );
+ $query = str_replace( 'NOW()', 'datetime(\'now\')', $query );
+ $query = str_replace( 'now()', 'datetime(\'now\')', $query );
+ // remove table prefixes
+ $query = str_replace( '*PREFIX*', '', $query );
+ return $query;
+ }
+
+ /**
+ * @brief copys rows to migration.db from the main database
+ * @param $options array of options.
+ * @return bool
+ */
+ public function copyRows( $options ){
+ if( !array_key_exists( 'table', $options ) ){
+ return false;
+ }
+
+ $return = array();
+
+ // Need to include 'where' in the query?
+ if( array_key_exists( 'matchval', $options ) && array_key_exists( 'matchcol', $options ) ){
+
+ // If only one matchval, create an array
+ if(!is_array($options['matchval'])){
+ $options['matchval'] = array( $options['matchval'] );
+ }
+
+ foreach( $options['matchval'] as $matchval ){
+ // Run the query for this match value (where x = y value)
+ $sql = "SELECT * FROM *PREFIX*" . $options['table'] . " WHERE " . $options['matchcol'] . " LIKE ?";
+ $query = OC_DB::prepare( $sql );
+ $results = $query->execute( array( $matchval ) );
+ $newreturns = $this->insertData( $results, $options );
+ $return = array_merge( $return, $newreturns );
+ }
+
+ } else {
+ // Just get everything
+ $sql = "SELECT * FROM *PREFIX*" . $options['table'];
+ $query = OC_DB::prepare( $sql );
+ $results = $query->execute();
+ $return = $this->insertData( $results, $options );
+
+ }
+
+ return $return;
+
+ }
+
+ /**
+ * @brief saves a sql data set into migration.db
+ * @param $data a sql data set returned from self::prepare()->query()
+ * @param $options array of copyRows options
+ * @return void
+ */
+ private function insertData( $data, $options ){
+ $return = array();
+ // Foreach row of data to insert
+ while( $row = $data->fetchRow() ){
+ // Now save all this to the migration.db
+ foreach($row as $field=>$value){
+ $fields[] = $field;
+ $values[] = $value;
+ }
+
+ // Generate some sql
+ $sql = "INSERT INTO `" . $options['table'] . '` ( `';
+ $fieldssql = implode( '`, `', $fields );
+ $sql .= $fieldssql . "` ) VALUES( ";
+ $valuessql = substr( str_repeat( '?, ', count( $fields ) ),0,-2 );
+ $sql .= $valuessql . " )";
+ // Make the query
+ $query = $this->prepare( $sql );
+ if( !$query ){
+ OC_Log::write( 'migration', 'Invalid sql produced: '.$sql, OC_Log::FATAL );
+ return false;
+ exit();
+ } else {
+ $query->execute( $values );
+ // Do we need to return some values?
+ if( array_key_exists( 'idcol', $options ) ){
+ // Yes we do
+ $return[] = $row[$options['idcol']];
+ } else {
+ // Take a guess and return the first field :)
+ $return[] = reset($row);
+ }
+ }
+ $fields = '';
+ $values = '';
+ }
+ return $return;
+ }
+
+ /**
+ * @brief adds a directory to the zip object
+ * @param $dir string path of the directory to add
+ * @param $recursive bool
+ * @param $internaldir string path of folder to add dir to in zip
+ * @return bool
+ */
+ public function addDir( $dir, $recursive=true, $internaldir='' ) {
+ $dirname = basename($dir);
+ $this->zip->addEmptyDir($internaldir . $dirname);
+ $internaldir.=$dirname.='/';
+ if( !file_exists( $dir ) ){
+ return false;
+ }
+ if ($dirhandle = opendir($dir)) {
+ while (false !== ( $file = readdir($dirhandle))) {
+
+ if (( $file != '.' ) && ( $file != '..' )) {
+
+ if (is_dir($dir . '/' . $file) && $recursive) {
+ $this->addDir($dir . '/' . $file, $recursive, $internaldir);
+ } elseif (is_file($dir . '/' . $file)) {
+ $this->zip->addFile($dir . '/' . $file, $internaldir . $file);
+ }
+ }
+ }
+ closedir($dirhandle);
+ } else {
+ OC_Log::write('admin_export',"Was not able to open directory: " . $dir,OC_Log::ERROR);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @brief adds a file to the zip from a given string
+ * @param $data string of data to add
+ * @param $path the relative path inside of the zip to save the file to
+ * @return bool
+ */
+ public function addFromString( $data, $path ){
+ // Create a temp file
+ $file = tempnam( get_temp_dir(). '/', 'oc_export_tmp_' );
+ $this->tmpfiles[] = $file;
+ if( !file_put_contents( $file, $data ) ){
+ OC_Log::write( 'migation', 'Failed to save data to a temporary file', OC_Log::ERROR );
+ return false;
+ }
+ // Add file to the zip
+ $this->zip->addFile( $file, $path );
+ return true;
+ }
+
+ /**
+ * @brief closes the zip, removes temp files
+ * @return bool
+ */
+ public function finish(){
+ if( !$this->zip->close() ){
+ OC_Log::write( 'migration', 'Failed to write the zip file with error: '.$this->zip->getStatusString(), OC_Log::ERROR );
+ return false;
+ }
+ $this->cleanup();
+ return true;
+ }
+
+ /**
+ * @brief cleans up after the zip
+ */
+ private function cleanup(){
+ // Delete tmp files
+ foreach($this->tmpfiles as $i){
+ unlink( $i );
+ }
+ }
+}
diff --git a/lib/migration/provider.php b/lib/migration/provider.php
new file mode 100644
index 00000000000..91336f3019d
--- /dev/null
+++ b/lib/migration/provider.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * provides search functionalty
+ */
+abstract class OC_Migration_Provider{
+
+ protected $id=false;
+ protected $content=false;
+ protected $uid=false;
+ protected $olduid=false;
+ protected $appinfo=false;
+
+ public function __construct( $appid ){
+ // Set the id
+ $this->id = $appid;
+ OC_Migrate::registerProvider( $this );
+ }
+
+ /**
+ * @brief exports data for apps
+ * @return array appdata to be exported
+ */
+ abstract function export( );
+
+ /**
+ * @brief imports data for the app
+ * @return void
+ */
+ abstract function import( );
+
+ /**
+ * @brief sets the OC_Migration_Content object to $this->content
+ * @param $content a OC_Migration_Content object
+ */
+ public function setData( $uid, $content, $info=null ){
+ $this->content = $content;
+ $this->uid = $uid;
+ $id = $this->id;
+ if( !is_null( $info ) ){
+ $this->olduid = $info->exporteduser;
+ $this->appinfo = $info->apps->$id;
+ }
+ }
+
+ /**
+ * @brief returns the appid of the provider
+ * @return string
+ */
+ public function getID(){
+ return $this->id;
+ }
+}
diff --git a/lib/mimetypes.fixlist.php b/lib/mimetypes.fixlist.php
index 1c6acbc4438..a40fbd9e228 100644
--- a/lib/mimetypes.fixlist.php
+++ b/lib/mimetypes.fixlist.php
@@ -10,5 +10,12 @@ return array(
'pl'=>'text/x-script.perl',
'py'=>'text/x-script.phyton',
'vcf' => 'text/vcard',
- 'vcard' => 'text/vcard'
+ 'vcard' => 'text/vcard',
+ 'doc'=>'application/msword',
+ 'docx'=>'application/msword',
+ 'xls'=>'application/msexcel',
+ 'xlsx'=>'application/msexcel',
+ 'ppt'=>'application/mspowerpoint',
+ 'pptx'=>'application/mspowerpoint',
+ 'sgf' => 'application/sgf'
);
diff --git a/lib/mimetypes.list.php b/lib/mimetypes.list.php
index e0570e84ea5..ccf47999b1c 100644
--- a/lib/mimetypes.list.php
+++ b/lib/mimetypes.list.php
@@ -21,7 +21,7 @@
*/
/**
- * list of mimetypes by extention
+ * list of mimetypes by extension
*/
return array(
diff --git a/lib/ocsclient.php b/lib/ocsclient.php
index 9d5932fb720..d830a4f3e7e 100644..100755
--- a/lib/ocsclient.php
+++ b/lib/ocsclient.php
@@ -29,13 +29,45 @@
class OC_OCSClient{
/**
+ * @brief Get the url of the OCS AppStore server.
+ * @returns string of the AppStore server
+ *
+ * This function returns the url of the OCS AppStore server. It´s possible to set it in the config file or it will fallback to the default
+ */
+ private static function getAppStoreURL(){
+ $configurl=OC_Config::getValue('appstoreurl', '');
+ if($configurl<>'') {
+ $url=$configurl;
+ }else{
+ $url='http://api.apps.owncloud.com/v1';
+ }
+ return($url);
+ }
+
+ /**
+ * @brief Get the url of the OCS KB server.
+ * @returns string of the KB server
+ * This function returns the url of the OCS knowledge base server. It´s possible to set it in the config file or it will fallback to the default
+ */
+ private static function getKBURL(){
+ $configurl=OC_Config::getValue('knowledgebaseurl', '');
+ if($configurl<>'') {
+ $url=$configurl;
+ }else{
+ $url='http://api.apps.owncloud.com/v1';
+ }
+ return($url);
+ }
+
+
+ /**
* @brief Get all the categories from the OCS server
* @returns array with category ids
*
* This function returns a list of all the application categories on the OCS server
*/
public static function getCategories(){
- $url='http://api.apps.owncloud.com/v1/content/categories';
+ $url=OC_OCSClient::getAppStoreURL().'/content/categories';
$xml=@file_get_contents($url);
if($xml==FALSE){
@@ -64,12 +96,16 @@ class OC_OCSClient{
* This function returns a list of all the applications on the OCS server
*/
public static function getApplications($categories){
+ if(OC_Config::getValue('appstoreenabled', true)==false){
+ return(array());
+ }
+
if(is_array($categories)) {
$categoriesstring=implode('x',$categories);
}else{
$categoriesstring=$categories;
}
- $url='http://api.apps.owncloud.com/v1/content/data?categories='.urlencode($categoriesstring).'&sortmode=new&page=0&pagesize=10';
+ $url=OC_OCSClient::getAppStoreURL().'/content/data?categories='.urlencode($categoriesstring).'&sortmode=new&page=0&pagesize=10';
$apps=array();
$xml=@file_get_contents($url);
if($xml==FALSE){
@@ -104,7 +140,7 @@ class OC_OCSClient{
* This function returns an applications from the OCS server
*/
public static function getApplication($id){
- $url='http://api.apps.owncloud.com/v1/content/data/'.urlencode($id);
+ $url=OC_OCSClient::getAppStoreURL().'/content/data/'.urlencode($id);
$xml=@file_get_contents($url);
if($xml==FALSE){
@@ -137,7 +173,7 @@ class OC_OCSClient{
* This function returns an download url for an applications from the OCS server
*/
public static function getApplicationDownload($id,$item){
- $url='http://api.apps.owncloud.com/v1/content/download/'.urlencode($id).'/'.urlencode($item);
+ $url=OC_OCSClient::getAppStoreURL().'/content/download/'.urlencode($id).'/'.urlencode($item);
$xml=@file_get_contents($url);
if($xml==FALSE){
@@ -164,9 +200,15 @@ class OC_OCSClient{
* This function returns a list of all the knowledgebase entries from the OCS server
*/
public static function getKnownledgebaseEntries($page,$pagesize){
+ if(OC_Config::getValue('knowledgebaseenabled', true)==false){
+ $kbe=array();
+ $kbe['totalitems']=0;
+ return $kbe;
+ }
+
$p= (int) $page;
$s= (int) $pagesize;
- $url='http://api.apps.owncloud.com/v1/knowledgebase/data?type=150&page='.$p.'&pagesize='.$s;
+ $url=OC_OCSClient::getKBURL().'/knowledgebase/data?type=150&page='.$p.'&pagesize='.$s;
$kbe=array();
$xml=@file_get_contents($url);
diff --git a/lib/remote/cloud.php b/lib/remote/cloud.php
deleted file mode 100644
index a9c74e8bf5f..00000000000
--- a/lib/remote/cloud.php
+++ /dev/null
@@ -1,204 +0,0 @@
-<?php
-/**
- * Class for connection to a remote owncloud installation
- *
- */
-class OC_REMOTE_CLOUD{
- private $path;
- private $connected=false;
- private $cookiefile=false;
-
- /**
- * make an api call to the remote cloud
- * @param string $action
- * @param array parameters
- * @param bool assoc when set to true, the result will be parsed as associative array
- *
- */
- private function apiCall($action,$parameters=false,$assoc=false){
- if(!$this->cookiefile){
- $this->cookiefile=get_temp_dir().'/remoteCloudCookie'.uniqid();
- }
- $url=$this->path.='/files/api.php';
- $fields_string="action=$action&";
- if(is_array($parameters)){
- foreach($parameters as $key=>$value){
- $fields_string.=$key.'='.$value.'&';
- }
- rtrim($fields_string,'&');
- }
- $ch=curl_init();
- curl_setopt($ch,CURLOPT_URL,$url);
- curl_setopt($ch,CURLOPT_POST,count($parameters));
- curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
- curl_setopt($ch, CURLOPT_COOKIEFILE,$this->cookiefile);
- curl_setopt($ch, CURLOPT_COOKIEJAR,$this->cookiefile);
- curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
- $result=curl_exec($ch);
- $result=trim($result);
- $info=curl_getinfo($ch);
- $httpCode=$info['http_code'];
- curl_close($ch);
- if($httpCode==200 or $httpCode==0){
- return json_decode($result,$assoc);
- }else{
- return false;
- }
- }
-
- public function __construct($path,$user,$password){
- $this->path=$path;
- $this->connected=$this->apiCall('login',array('username'=>$user,'password'=>$password));
- }
-
- /**
- * check if we are stull logged in on the remote cloud
- *
- */
- public function isLoggedIn(){
- if(!$this->connected){
- return false;
- }
- return $this->apiCall('checklogin');
- }
-
- public function __get($name){
- switch($name){
- case 'connected':
- return $this->connected;
- }
- }
-
- /**
- * disconnect from the remote cloud
- *
- */
- public function disconnect(){
- $this->connected=false;
- if(is_file($this->cookiefile)){
- unlink($this->cookiefile);
- }
- $this->cookiefile=false;
- }
-
- /**
- * create a new file or directory
- * @param string $dir
- * @param string $name
- * @param string $type
- */
- public function newFile($dir,$name,$type){
- if(!$this->connected){
- return false;
- }
- return $this->apiCall('new',array('dir'=>$dir,'name'=>$name,'type'=>$type),true);
- }
-
- /**
- * deletes a file or directory
- * @param string $dir
- * @param string $file
- */
- public function delete($dir,$name){
- if(!$this->connected){
- return false;
- }
- return $this->apiCall('delete',array('dir'=>$dir,'file'=>$name),true);
- }
-
- /**
- * moves a file or directory
- * @param string $sorceDir
- * @param string $sorceFile
- * @param string $targetDir
- * @param string $targetFile
- */
- public function move($sourceDir,$sourceFile,$targetDir,$targetFile){
- if(!$this->connected){
- return false;
- }
- return $this->apiCall('move',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true);
- }
-
- /**
- * copies a file or directory
- * @param string $sorceDir
- * @param string $sorceFile
- * @param string $targetDir
- * @param string $targetFile
- */
- public function copy($sourceDir,$sourceFile,$targetDir,$targetFile){
- if(!$this->connected){
- return false;
- }
- return $this->apiCall('copy',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true);
- }
-
- /**
- * get a file tree
- * @param string $dir
- */
- public function getTree($dir){
- if(!$this->connected){
- return false;
- }
- return $this->apiCall('gettree',array('dir'=>$dir),true);
- }
-
- /**
- * get the files inside a directory of the remote cloud
- * @param string $dir
- */
- public function getFiles($dir){
- if(!$this->connected){
- return false;
- }
- return $this->apiCall('getfiles',array('dir'=>$dir),true);
- }
-
- /**
- * get a remove file and save it in a temporary file and return the path of the temporary file
- * @param string $dir
- * @param string $file
- * @return string
- */
- public function getFile($dir, $file){
- if(!$this->connected){
- return false;
- }
- $ch=curl_init();
- if(!$this->cookiefile){
- $this->cookiefile=get_temp_dir().'/remoteCloudCookie'.uniqid();
- }
- $tmpfile=tempnam(get_temp_dir(),'remoteCloudFile');
- $fp=fopen($tmpfile,'w+');
- $url=$this->path.="/files/api.php?action=get&dir=$dir&file=$file";
- curl_setopt($ch,CURLOPT_URL,$url);
- curl_setopt($ch, CURLOPT_COOKIEFILE,$this->cookiefile);
- curl_setopt($ch, CURLOPT_COOKIEJAR,$this->cookiefile);
- curl_setopt($ch, CURLOPT_FILE, $fp);
- curl_exec($ch);
- fclose($fp);
- curl_close($ch);
- return $tmpfile;
- }
-
- public function sendFile($sourceDir,$sourceFile,$targetDir,$targetFile){
- $source=$sourceDir.'/'.$sourceFile;
- $tmp=OC_Filesystem::toTmpFile($source);
- return $this->sendTmpFile($tmp,$targetDir,$targetFile);
- }
-
- public function sendTmpFile($tmp,$targetDir,$targetFile){
- $token=sha1(uniqid().$tmp);
- $file=get_temp_dir().'/'.'remoteCloudFile'.$token;
- rename($tmp,$file);
- if( OC_Config::getValue( "forcessl", false ) or isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') {
- $url = "https://". $_SERVER['SERVER_NAME'] . OC::$WEBROOT;
- }else{
- $url = "http://". $_SERVER['SERVER_NAME'] . OC::$WEBROOT;
- }
- return $this->apiCall('pull',array('dir'=>$targetDir,'file'=>$targetFile,'token'=>$token,'source'=>$url),true);
- }
-}
-
diff --git a/lib/search.php b/lib/search.php
index 6b33fa38140..12055418687 100644
--- a/lib/search.php
+++ b/lib/search.php
@@ -26,13 +26,22 @@
*/
class OC_Search{
static private $providers=array();
+ static private $registeredProviders=array();
+
+ /**
+ * remove all registered search providers
+ */
+ public static function clearProviders(){
+ self::$providers=array();
+ self::$registeredProviders=array();
+ }
/**
* register a new search provider to be used
* @param string $provider class name of a OC_Search_Provider
*/
- public static function registerProvider($provider){
- self::$providers[]=$provider;
+ public static function registerProvider($class,$options=array()){
+ self::$registeredProviders[]=array('class'=>$class,'options'=>$options);
}
/**
@@ -41,10 +50,25 @@ class OC_Search{
* @return array An array of OC_Search_Result's
*/
public static function search($query){
+ self::initProviders();
$results=array();
foreach(self::$providers as $provider){
- $results=array_merge($results, $provider::search($query));
+ $results=array_merge($results, $provider->search($query));
}
return $results;
}
+
+ /**
+ * create instances of all the registered search providers
+ */
+ private static function initProviders(){
+ if(count(self::$providers)>0){
+ return;
+ }
+ foreach(self::$registeredProviders as $provider){
+ $class=$provider['class'];
+ $options=$provider['options'];
+ self::$providers[]=new $class($options);
+ }
+ }
}
diff --git a/lib/search/provider.php b/lib/search/provider.php
index 9487ca51f2b..838ab696d04 100644
--- a/lib/search/provider.php
+++ b/lib/search/provider.php
@@ -2,11 +2,13 @@
/**
* provides search functionalty
*/
-interface OC_Search_Provider {
+class OC_Search_Provider {
+ public function __construct($options){}
+
/**
* search for $query
* @param string $query
* @return array An array of OC_Search_Result's
*/
- static function search($query);
+ public function search($query){}
}
diff --git a/lib/search/provider/file.php b/lib/search/provider/file.php
index 3bdb3bcd2af..a37af495599 100644
--- a/lib/search/provider/file.php
+++ b/lib/search/provider/file.php
@@ -1,7 +1,7 @@
<?php
-class OC_Search_Provider_File implements OC_Search_Provider{
- static function search($query){
+class OC_Search_Provider_File extends OC_Search_Provider{
+ function search($query){
$files=OC_FileCache::search($query,true);
$results=array();
foreach($files as $fileData){
diff --git a/lib/template.php b/lib/template.php
index eea2925975c..eeba2410b68 100644
--- a/lib/template.php
+++ b/lib/template.php
@@ -76,7 +76,7 @@ function simple_file_size($bytes) {
}
function relative_modified_date($timestamp) {
- $l=new OC_L10N('template');
+ $l=OC_L10N::get('template');
$timediff = time() - $timestamp;
$diffminutes = round($timediff/60);
$diffhours = round($diffminutes/60);
@@ -140,7 +140,7 @@ class OC_Template{
/**
* @brief Constructor
* @param $app app providing the template
- * @param $file name of the tempalte file (without suffix)
+ * @param $file name of the template file (without suffix)
* @param $renderas = ""; produce a full page
* @returns OC_Template object
*
@@ -151,10 +151,20 @@ class OC_Template{
* "admin".
*/
public function __construct( $app, $name, $renderas = "" ){
- // Read the selected theme from the config file
- $theme=OC_Config::getValue( "theme" );
+ // Set the private data
+ $this->renderas = $renderas;
+ $this->application = $app;
+ $this->vars = array();
+ $this->l10n = OC_L10N::get($app);
- // Read the detected formfactor and use the right file name.
+ $this->findTemplate($name);
+ }
+
+ /**
+ * @brief Returns the formfactor extension for current formfactor
+ */
+ protected function getFormFactorExtension()
+ {
$formfactor=$_SESSION['formfactor'];
if($formfactor=='default') {
$fext='';
@@ -167,70 +177,79 @@ class OC_Template{
}else{
$fext='';
}
+ return $fext;
+ }
+ /**
+ * @brief find the template with the given name
+ * @param $name of the template file (without suffix)
+ *
+ * Will select the template file for the selected theme and formfactor.
+ * Checking all the possible locations.
+ */
+ protected function findTemplate($name)
+ {
+ // Read the selected theme from the config file
+ $theme=OC_Config::getValue( "theme" );
+
+ // Read the detected formfactor and use the right file name.
+ $fext = $this->getFormFactorExtension();
+
+ $app = $this->application;
// Check if it is a app template or not.
if( $app != "" ){
// Check if the app is in the app folder or in the root
if( file_exists( OC::$APPSROOT."/apps/$app/templates/" )){
// Check if the template is overwritten by the selected theme
- if( file_exists( OC::$SERVERROOT."/themes/$theme/apps/$app/templates/"."$name$fext.php" )){
- $template = OC::$SERVERROOT."/themes/$theme/apps/$app/templates/"."$name$fext.php";
- $path = OC::$SERVERROOT."/themes/$theme/apps/$app/templates/";
- }elseif( file_exists( OC::$SERVERROOT."/themes/$theme/apps/$app/templates/"."$name.php" )){
- $template = OC::$SERVERROOT."/themes/$theme/apps/$app/templates/"."$name.php";
- $path = OC::$SERVERROOT."/themes/$theme/apps/$app/templates/";
- }elseif( OC::$APPSROOT."/apps/$app/templates/"."$name$fext.php" ){
- $template = OC::$APPSROOT."/apps/$app/templates/"."$name$fext.php";
- $path = OC::$APPSROOT."/apps/$app/templates/";
- }else{
- $template = OC::$APPSROOT."/apps/$app/templates/"."$name.php";
- $path = OC::$APPSROOT."/apps/$app/templates/";
+ if ($this->checkPathForTemplate(OC::$SERVERROOT."/themes/$theme/apps/$app/templates/", $name, $fext)) {
+ }elseif ($this->checkPathForTemplate(OC::$APPSROOT."/apps/$app/templates/", $name, $fext)) {
}
}else{
// Check if the template is overwritten by the selected theme
- if( file_exists( OC::$SERVERROOT."/themes/$theme/$app/templates/"."$name$fext.php" )){
- $template = OC::$SERVERROOT."/themes/$theme/$app/templates/"."$name$fext.php";
- $path = OC::$SERVERROOT."/themes/$theme/$app/templates/";
- }elseif( file_exists( OC::$SERVERROOT."/themes/$theme/$app/templates/"."$name.php" )){
- $template = OC::$SERVERROOT."/themes/$theme/$app/templates/"."$name.php";
- $path = OC::$SERVERROOT."/themes/$theme/$app/templates/";
- }elseif( file_exists( OC::$SERVERROOT."/$app/templates/"."$name$fext.php" )){
- $template = OC::$SERVERROOT."/$app/templates/"."$name$fext.php";
- $path = OC::$SERVERROOT."/$app/templates/";
- }elseif( file_exists( OC::$SERVERROOT."/$app/templates/"."$name.php" )){
- $template = OC::$SERVERROOT."/$app/templates/"."$name.php";
- $path = OC::$SERVERROOT."/$app/templates/";
+ if ($this->checkPathForTemplate(OC::$SERVERROOT."/themes/$theme/$app/templates/", $name, $fext)) {
+ }elseif ($this->checkPathForTemplate(OC::$SERVERROOT."/$app/templates/", $name, $fext)) {
}else{
- echo('template not found: template:'.$name.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
+ echo('template not found: template:'.$name.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
die();
}
- }
+ }
}else{
// Check if the template is overwritten by the selected theme
- if( file_exists( OC::$SERVERROOT."/themes/$theme/core/templates/"."$name$fext.php" )){
- $template = OC::$SERVERROOT."/themes/$theme/core/templates/"."$name$fext.php";
- $path = OC::$SERVERROOT."/themes/$theme/core/templates/";
- }elseif( file_exists( OC::$SERVERROOT."/themes/$theme/core/templates/"."$name.php" )){
- $template = OC::$SERVERROOT."/themes/$theme/core/templates/"."$name.php";
- $path = OC::$SERVERROOT."/themes/$theme/core/templates/";
- }elseif( file_exists( OC::$SERVERROOT."/core/templates/"."$name$fext.php" )){
- $template = OC::$SERVERROOT."/core/templates/"."$name$fext.php";
- $path = OC::$SERVERROOT."/core/templates/";
+ if ($this->checkPathForTemplate(OC::$SERVERROOT."/themes/$theme/core/templates/", $name, $fext)) {
+ } elseif ($this->checkPathForTemplate(OC::$SERVERROOT."/core/templates/", $name, $fext)) {
}else{
- $template = OC::$SERVERROOT."/core/templates/"."$name.php";
- $path = OC::$SERVERROOT."/core/templates/";
+ echo('template not found: template:'.$name.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
+ die();
}
}
+ }
-
- // Set the private data
- $this->renderas = $renderas;
- $this->application = $app;
- $this->template = $template;
- $this->path = $path;
- $this->vars = array();
- $this->l10n = new OC_L10N($app);
+ /**
+ * @brief check Path For Template with and without $fext
+ * @param $path to check
+ * @param $name of the template file (without suffix)
+ * @param $fext formfactor extension
+ * @return bool true when found
+ *
+ * Will set $this->template and $this->path if there is a template at
+ * the specifief $path
+ */
+ protected function checkPathForTemplate($path, $name, $fext)
+ {
+ if ($name =='') return false;
+ $template = null;
+ if( is_file( $path.$name.$fext.'.php' )){
+ $template = $path.$name.$fext.'.php';
+ }elseif( is_file( $path.$name.'.php' )){
+ $template = $path.$name.'.php';
+ }
+ if ($template) {
+ $this->template = $template;
+ $this->path = $path;
+ return true;
+ }
+ return false;
}
/**
@@ -267,7 +286,7 @@ class OC_Template{
$this->vars[$key] = array( $value );
}
}
-
+
/**
* @brief Add a custom element to the header
* @param string tag tag name of the element
@@ -295,11 +314,25 @@ class OC_Template{
}
}
+ /*
+ * @brief append the $file-url if exist at $root
+ * @param $type of collection to use when appending
+ * @param $root path to check
+ * @param $web base for path
+ * @param $file the filename
+ */
+ public function appendIfExist($type, $root, $web, $file) {
+ if (is_file($root.'/'.$file)) {
+ $this->append( $type, $web.'/'.$file);
+ return true;
+ }
+ return false;
+ }
/**
* @brief Proceeds the template
* @returns content
*
- * This function proceeds the template. If $this->renderas is set, it will
+ * This function proceeds the template. If $this->renderas is set, it
* will produce a full page.
*/
public function fetchPage(){
@@ -329,68 +362,44 @@ class OC_Template{
}else{
$page = new OC_Template( "core", "layout.guest" );
}
-
+
// Read the selected theme from the config file
$theme=OC_Config::getValue( "theme" );
// Read the detected formfactor and use the right file name.
- $formfactor=$_SESSION['formfactor'];
- if($formfactor=='default') {
- $fext='';
- }elseif($formfactor=='mobile') {
- $fext='.mobile';
- }elseif($formfactor=='tablet') {
- $fext='.tablet';
- }elseif($formfactor=='standalone') {
- $fext='.standalone';
- }else{
- $fext='';
- }
+ $fext = $this->getFormFactorExtension();
// Add the core js files or the js files provided by the selected theme
foreach(OC_Util::$scripts as $script){
// Is it in 3rd party?
- if(is_file(OC::$THIRDPARTYROOT."/$script.js" )){
- $page->append( "jsfiles", OC::$THIRDPARTYWEBROOT."/$script.js" );
+ if($page->appendIfExist('jsfiles', OC::$THIRDPARTYROOT, OC::$THIRDPARTYWEBROOT, $script.'.js')) {
// Is it in apps and overwritten by the theme?
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/apps/$script$fext.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/apps/$script$fext.js" );
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/apps/$script.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/apps/$script.js" );
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/apps/$script$fext.js" )) {
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/apps/$script.js" )) {
// Is it part of an app?
- }elseif(is_file(OC::$APPSROOT."/apps/$script$fext.js" )){
- $page->append( "jsfiles", OC::$APPSWEBROOT."/apps/$script$fext.js" );
- }elseif(is_file(OC::$APPSROOT."/apps/$script.js" )){
- $page->append( "jsfiles", OC::$APPSWEBROOT."/apps/$script.js" );
+ }elseif($page->appendIfExist('jsfiles', OC::$APPSROOT, OC::$APPSWEBROOT, "apps/$script$fext.js" )) {
+ }elseif($page->appendIfExist('jsfiles', OC::$APPSROOT, OC::$APPSWEBROOT, "apps/$script.js" )) {
// Is it in the owncloud root but overwritten by the theme?
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/$script$fext.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/$script$fext.js" );
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/$script.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/$script.js" );
-
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/$script$fext.js" )) {
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/$script.js" )) {
+
// Is it in the owncloud root ?
- }elseif(is_file(OC::$SERVERROOT."/$script$fext.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/$script$fext.js" );
- }elseif(is_file(OC::$SERVERROOT."/$script.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/$script.js" );
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "$script$fext.js" )) {
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "$script.js" )) {
// Is in core but overwritten by a theme?
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/core/$script$fext.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/core/$script$fext.js" );
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/core/$script.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/core/$script.js" );
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/core/$script$fext.js" )) {
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/core/$script.js" )) {
// Is it in core?
- }elseif(is_file(OC::$SERVERROOT."/core/$script$fext.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/core/$script$fext.js" );
- }elseif(is_file(OC::$SERVERROOT."/core/$script.js" )){
- $page->append( "jsfiles", OC::$WEBROOT."/core/$script.js" );
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "core/$script$fext.js" )) {
+ }elseif($page->appendIfExist('jsfiles', OC::$SERVERROOT, OC::$WEBROOT, "core/$script.js" )) {
}else{
- echo('js file not found: script:'.$script.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
+ echo('js file not found: script:'.$script.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
die();
}
@@ -398,54 +407,46 @@ class OC_Template{
// Add the css files
foreach(OC_Util::$styles as $style){
// is it in 3rdparty?
- if(is_file(OC::$THIRDPARTYROOT."/$style.css" )){
- $page->append( "cssfiles", OC::$THIRDPARTYWEBROOT."/$style.css" );
+ if($page->appendIfExist('cssfiles', OC::$THIRDPARTYROOT, OC::$THIRDPARTYWEBROOT, $style.'.css')) {
+
// or in apps?
- }elseif(is_file(OC::$APPSROOT."/apps/$style$fext.css" )){
- $page->append( "cssfiles", OC::$APPSWEBROOT."/apps/$style$fext.css" );
- }elseif(is_file(OC::$APPSROOT."/apps/$style.css" )){
- $page->append( "cssfiles", OC::$APPSWEBROOT."/apps/$style.css" );
+ }elseif($page->appendIfExist('cssfiles', OC::$APPSROOT, OC::$APPSWEBROOT, "apps/$style$fext.css" )) {
+ }elseif($page->appendIfExist('cssfiles', OC::$APPSROOT, OC::$APPSWEBROOT, "apps/$style.css" )) {
+
// or in the owncloud root?
- }elseif(is_file(OC::$SERVERROOT."/$style$fext.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/$style$fext.css" );
- }elseif(is_file(OC::$SERVERROOT."/$style.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/$style.css" );
- // or in core ?
- }elseif(is_file(OC::$SERVERROOT."/core/$style$fext.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/core/$style$fext.css" );
- }elseif(is_file(OC::$SERVERROOT."/core/$style.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/core/$style.css" );
+ }elseif($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "$style$fext.css" )) {
+ }elseif($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "$style.css" )) {
+
+ // or in core ?
+ }elseif($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "core/$style$fext.css" )) {
+ }elseif($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "core/$style.css" )) {
}else{
- echo('css file not found: style:'.$script.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
+ echo('css file not found: style:'.$script.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
die();
}
}
- // Add the theme css files. you can override the default values here
+ // Add the theme css files. you can override the default values here
if(!empty($theme)) {
- foreach(OC_Util::$styles as $style){
- if(is_file(OC::$SERVERROOT."/themes/$theme/apps/$style$fext.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/themes/$theme/apps/$style$fext.css" );
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/apps/$style.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/themes/$theme/apps/$style.css" );
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/$style$fext.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/themes/$theme/$style$fext.css" );
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/$style.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/themes/$theme/$style.css" );
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/core/$style$fext.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/themes/$theme/core/$style$fext.css" );
- }elseif(is_file(OC::$SERVERROOT."/themes/$theme/core/$style.css" )){
- $page->append( "cssfiles", OC::$WEBROOT."/themes/$theme/core/$style.css" );
- }
- }
- }
-
+ foreach(OC_Util::$styles as $style){
+ if($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/apps/$style$fext.css" )) {
+ }elseif($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/apps/$style.css" )) {
+
+ }elseif($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/$style$fext.css" )) {
+ }elseif($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/$style.css" )) {
+
+ }elseif($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/core/$style$fext.css" )) {
+ }elseif($page->appendIfExist('cssfiles', OC::$SERVERROOT, OC::$WEBROOT, "themes/$theme/core/$style.css" )) {
+ }
+ }
+ }
+
// Add custom headers
$page->assign('headers',$this->headers);
foreach(OC_Util::$headers as $header){
$page->append('headers',$header);
}
-
+
// Add css files and js files
$page->assign( "content", $data );
return $page->fetchPage();
diff --git a/lib/updater.php b/lib/updater.php
index 57623797ae5..deb0f05945e 100644
--- a/lib/updater.php
+++ b/lib/updater.php
@@ -36,6 +36,7 @@ class OC_Updater{
$version['installed']=OC_Config::getValue('installedat');
$version['updated']=OC_Appconfig::getValue('core', 'lastupdatedat', OC_Config::getValue( 'lastupdatedat'));
$version['updatechannel']='stable';
+ $version['edition']=OC_Util::getEditionString();
$versionstring=implode('x',$version);
//fetch xml data from updater
@@ -58,9 +59,9 @@ class OC_Updater{
public static function ShowUpdatingHint(){
$data=OC_Updater::check();
if(isset($data['version']) and $data['version']<>'') {
- $txt='<span style="color:#AA0000; font-weight:bold;">'.$data['versionstring'].' is available. Please click <a href="'.$data['web'].'">here</a> for more information</span>';
+ $txt='<span style="color:#AA0000; font-weight:bold;">'.$data['versionstring'].' is available. Get <a href="'.$data['web'].'">more information</a></span>';
}else{
- $txt='Your ownCloud is up to date';
+ $txt='up to date';
}
return($txt);
}
diff --git a/lib/user.php b/lib/user.php
index fda19a33154..8c27ec30cc2 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -186,7 +186,7 @@ class OC_User {
* @param $password The password of the user
* @returns true/false
*
- * Log in a user - if the password is ok
+ * Log in a user and regenerate a new session - if the password is ok
*/
public static function login( $uid, $password ){
$run = true;
@@ -195,6 +195,7 @@ class OC_User {
if( $run ){
$uid=self::checkPassword( $uid, $password );
if($uid){
+ session_regenerate_id();
self::setUserId($uid);
OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>$password ));
return true;
@@ -221,7 +222,8 @@ class OC_User {
*/
public static function logout(){
OC_Hook::emit( "OC_User", "logout", array());
- $_SESSION['user_id'] = false;
+ session_unset();
+ session_destroy();
OC_User::unsetMagicInCookie();
return true;
}
diff --git a/lib/user/database.php b/lib/user/database.php
index 3eade276dd9..c1bac1bb0b5 100644
--- a/lib/user/database.php
+++ b/lib/user/database.php
@@ -172,7 +172,7 @@ class OC_User_Database extends OC_User_Backend {
* @return boolean
*/
public function userExists($uid){
- $query = OC_DB::prepare( "SELECT * FROM `*PREFIX*users` WHERE uid = ?" );
+ $query = OC_DB::prepare( "SELECT * FROM `*PREFIX*users` WHERE uid LIKE ?" );
$result = $query->execute( array( $uid ));
return $result->numRows() > 0;
diff --git a/lib/user/dummy.php b/lib/user/dummy.php
new file mode 100644
index 00000000000..cfc96c5c52d
--- /dev/null
+++ b/lib/user/dummy.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * dummy user backend, does not keep state, only for testing use
+ */
+class OC_User_Dummy extends OC_User_Backend {
+ private $users=array();
+ /**
+ * @brief Create a new user
+ * @param $uid The username of the user to create
+ * @param $password The password of the new user
+ * @returns true/false
+ *
+ * Creates a new user. Basic checking of username is done in OC_User
+ * itself, not in its subclasses.
+ */
+ public function createUser($uid, $password){
+ if(isset($this->users[$uid])){
+ return false;
+ }else{
+ $this->users[$uid]=$password;
+ return true;
+ }
+ }
+
+ /**
+ * @brief delete a user
+ * @param $uid The username of the user to delete
+ * @returns true/false
+ *
+ * Deletes a user
+ */
+ public function deleteUser( $uid ){
+ if(isset($this->users[$uid])){
+ unset($this->users[$uid]);
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * @brief Set password
+ * @param $uid The username
+ * @param $password The new password
+ * @returns true/false
+ *
+ * Change the password of a user
+ */
+ public function setPassword($uid, $password){
+ if(isset($this->users[$uid])){
+ $this->users[$uid]=$password;
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * @brief Check if the password is correct
+ * @param $uid The username
+ * @param $password The password
+ * @returns true/false
+ *
+ * Check if the password is correct without logging in the user
+ */
+ public function checkPassword($uid, $password){
+ if(isset($this->users[$uid])){
+ return ($this->users[$uid]==$password);
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * @brief Get a list of all users
+ * @returns array with all uids
+ *
+ * Get a list of all users.
+ */
+ public function getUsers(){
+ return array_keys($this->users);
+ }
+
+ /**
+ * @brief check if a user exists
+ * @param string $uid the username
+ * @return boolean
+ */
+ public function userExists($uid){
+ return isset($this->users[$uid]);
+ }
+}
diff --git a/lib/util.php b/lib/util.php
index fa5b3daaab6..2ea392ec31d 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -25,7 +25,7 @@ class OC_Util {
$success=@mkdir($CONFIG_DATADIRECTORY_ROOT);
if(!$success) {
$tmpl = new OC_Template( '', 'error', 'guest' );
- $tmpl->assign('errors',array(1=>array('error'=>"Can't create data directory (".$CONFIG_DATADIRECTORY_ROOT.")",'hint'=>"You can usually fix this by giving the webserver write access to the ownCloud directory '".OC::$SERVERROOT."' ")));
+ $tmpl->assign('errors',array(1=>array('error'=>"Can't create data directory (".$CONFIG_DATADIRECTORY_ROOT.")",'hint'=>"You can usually fix this by giving the webserver write access to the ownCloud directory '".OC::$SERVERROOT."' (in a terminal, use the command 'chown -R www-data:www-data /path/to/your/owncloud/install/data' ")));
$tmpl->printPage();
exit;
}
@@ -66,7 +66,7 @@ class OC_Util {
* @return array
*/
public static function getVersion(){
- return array(3,00,3);
+ return array(3,80,0);
}
/**
@@ -74,9 +74,17 @@ class OC_Util {
* @return string
*/
public static function getVersionString(){
- return '3';
+ return '4 alpha';
}
+ /**
+ * get the current installed edition of ownCloud. There is the community edition that just returns an empty string and the enterprise edition that returns "Enterprise".
+ * @return string
+ */
+ public static function getEditionString(){
+ return '';
+ }
+
/**
* add a javascript file
*
diff --git a/lib/vcategories.php b/lib/vcategories.php
index 5a7bacd2025..b3b6a493c8d 100644
--- a/lib/vcategories.php
+++ b/lib/vcategories.php
@@ -50,13 +50,12 @@ class OC_VCategories {
* parameter should normally be omitted but to make an app able to
* update categories for all users it is made possible to provide it.
* @param $defcategories An array of default categories to be used if none is stored.
- * NOTE: Not implemented.
*/
- public function __construct($app, $user=null, $defcategories=null) {
+ public function __construct($app, $user=null, $defcategories=array()) {
$this->app = $app;
$this->user = is_null($user) ? OC_User::getUser() : $user;
$categories = trim(OC_Preferences::getValue($this->user, $app, self::PREF_CATEGORIES_LABEL, ''));
- $this->categories = $categories != '' ? unserialize($categories) : array();
+ $this->categories = $categories != '' ? unserialize($categories) : $defcategories;
}
/**
@@ -65,6 +64,7 @@ class OC_VCategories {
*/
public function categories() {
OC_Log::write('core','OC_VCategories::categories: '.print_r($this->categories, true), OC_Log::DEBUG);
+ usort($this->categories, 'strnatcasecmp'); // usort to also renumber the keys
return $this->categories;
}
@@ -97,7 +97,6 @@ class OC_VCategories {
}
if(count($newones) > 0) {
$this->categories = array_merge($this->categories, $newones);
- natcasesort($this->categories); // Dunno if this is necessary
if($sync === true) {
$this->save();
}
@@ -147,6 +146,7 @@ class OC_VCategories {
* @brief Save the list with categories
*/
private function save() {
+ usort($this->categories, 'strnatcasecmp'); // usort to also renumber the keys
$escaped_categories = serialize($this->categories);
OC_Log::write('core','OC_VCategories::save: '.print_r($this->categories, true), OC_Log::DEBUG);
OC_Preferences::setValue($this->user, $this->app, self::PREF_CATEGORIES_LABEL, $escaped_categories);