From 6da5a2fdd4e8a19ab993b4a1f7de7e45b8922a16 Mon Sep 17 00:00:00 2001
From: Brice Maron <brice@bmaron.net>
Date: Thu, 14 Jun 2012 21:00:02 +0000
Subject: [PATCH] Add possibility to choose the installation folder

---
 config/config.sample.php | 12 ++++++------
 lib/app.php              | 39 +++++++++++++++++++++++++++++----------
 lib/base.php             |  4 ++--
 lib/installer.php        |  3 +--
 lib/util.php             | 16 +++++++++-------
 5 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/config/config.sample.php b/config/config.sample.php
index bc66e9ebc0..afc04f8ec1 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -33,17 +33,17 @@ $CONFIG = array(
  * If the apps dir is not writable, you can't download&install extra apps
  * in the admin apps menu.
  */
-"writable_appsdir" => true,
 // "datadirectory" => "",
 "apps_paths" => array(
 
 /* Set an array of path for your apps directories
- key 'path' is for the fs path an the key url is for the http path to your
- applications paths
+ key 'path' is for the fs path an the key 'url' is for the http path to your
+ applications paths. 'writable' indicate if the user can install apps in this folder.
 */
-  array(
-    'path'=> '/var/www/owncloud/apps',
-    'url' => '/apps',
+	array(
+		'path'=> '/var/www/owncloud/apps',
+		'url' => '/apps',
+		'writable' => true,
   ),
  ),
 );
diff --git a/lib/app.php b/lib/app.php
index 79a0a2e053..ca7a022f89 100755
--- a/lib/app.php
+++ b/lib/app.php
@@ -322,17 +322,39 @@ class OC_App{
 		return $list;
 	}
 
+	/**
+	* Get the path where to install apps
+  */
+	public static function getInstallPath() {
+		if(OC_Config::getValue('appstoreenabled', true)==false) {
+			return false;
+		}
+
+		foreach(OC::$APPSROOTS as $dir) {
+			if(isset($dir['writable']) && $dir['writable']===true)
+				return $dir['path'];
+		}
+
+		OC_Log::write('core','No application directories are marked as writable.',OC_Log::ERROR);
+		return null;
+	}
+
+
+	protected static function findAppInDirectories($appid) {
+		foreach(OC::$APPSROOTS as $dir) {
+			if(file_exists($dir['path'].'/'.$appid)) {
+				return $dir;
+			}
+		}
+	}
 	/**
 	* Get the directory for the given app.
 	* If the app is defined in multiple directory, the first one is taken. (false if not found)
 	*/
 	public static function getAppPath($appid) {
-		foreach(OC::$APPSROOTS as $dir) {
-			if(file_exists($dir['path'].'/'.$appid)) {
-				return $dir['path'].'/'.$appid;
-			}
+		if( ($dir = self::findAppInDirectories($appid)) != false) {
+			return $dir['path'].'/'.$appid;
 		}
-		return false;
 	}
 
 	/**
@@ -340,12 +362,9 @@ class OC_App{
 	* If the app is defined in multiple directory, the first one is taken. (false if not found)
 	*/
 	public static function getAppWebPath($appid) {
-		foreach(OC::$APPSROOTS as $dir) {
-			if(file_exists($dir['path'].'/'.$appid)) {
-				return $dir['url'].'/'.$appid;
-			}
+		if( ($dir = self::findAppInDirectories($appid)) != false) {
+			return $dir['url'].'/'.$appid;
 		}
-		return false;
 	}
 
 	/**
diff --git a/lib/base.php b/lib/base.php
index 6e85f1a734..ca4052e5a1 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -169,9 +169,9 @@ class OC{
 					OC::$APPSROOTS[] = $paths;	
 			}
 		}elseif(file_exists(OC::$SERVERROOT.'/apps')){
-			OC::$APPSROOTS[] = array('path'=> OC::$SERVERROOT.'/apps', 'url' => OC::$WEBROOT.'/apps/');
+			OC::$APPSROOTS[] = array('path'=> OC::$SERVERROOT.'/apps', 'url' => OC::$WEBROOT.'/apps/', 'writable' => true);
 		}elseif(file_exists(OC::$SERVERROOT.'/../apps')){
-			OC::$APPSROOTS[] = array('path'=> rtrim(dirname(OC::$SERVERROOT), '/').'/apps', 'url' => rtrim(dirname(OC::$WEBROOT), '/').'/apps/');
+			OC::$APPSROOTS[] = array('path'=> rtrim(dirname(OC::$SERVERROOT), '/').'/apps', 'url' => rtrim(dirname(OC::$WEBROOT), '/').'/apps/', 'writable' => true);
 			OC::$APPSROOT=rtrim(dirname(OC::$SERVERROOT), '/');
 		}
 
diff --git a/lib/installer.php b/lib/installer.php
index bfa34de2a7..299674b29e 100644
--- a/lib/installer.php
+++ b/lib/installer.php
@@ -126,8 +126,6 @@ class OC_Installer{
 			return false;
 		}
 		$info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml',true);
-		$basedir=OC_App::getAppPath($info['id']);
-
                 // check the code for not allowed calls
                 if(!OC_Installer::checkCode($info['id'],$extractDir)){
 			OC_Log::write('core','App can\'t be installed because of not allowed code in the App',OC_Log::ERROR);
@@ -153,6 +151,7 @@ class OC_Installer{
 			return false;
 		}
 
+		$basedir=OC_App::getInstallPath().'/'.$info['id'];
 		//check if the destination directory already exists
 		if(is_dir($basedir)){
 			OC_Log::write('core','App directory already exists',OC_Log::WARN);
diff --git a/lib/util.php b/lib/util.php
index 20888fa71f..b344d576eb 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -29,13 +29,15 @@ class OC_Util {
 			$tmpl->printPage();
 			exit;
 		}
-		
-		// Check if apps folder is writable.
-		if(OC_Config::getValue('writable_appsdir', true) && !is_writable(OC::$SERVERROOT."/apps/")) {
-			$tmpl = new OC_Template( '', 'error', 'guest' );
-			$tmpl->assign('errors',array(1=>array('error'=>"Can't write into apps directory 'apps'",'hint'=>"You can usually fix this by giving the webserver user write access to the config directory in owncloud")));
-			$tmpl->printPage();
-			exit;
+
+		// Check if there is a writable install folder.
+		if(OC_Config::getValue('appstoreenabled', true)) {
+			if( OC_App::getInstallPath() === null  || !is_writable(OC_App::getInstallPath())) {
+				$tmpl = new OC_Template( '', 'error', 'guest' );
+				$tmpl->assign('errors',array(1=>array('error'=>"Can't write into apps directory 'apps'",'hint'=>"You can usually fix this by giving the webserver user write access to the config directory in owncloud")));
+				$tmpl->printPage();
+				exit;
+			}
 		}
 		
 		// Create root dir.
-- 
GitLab