From f4e4617be7a22a0191bf1bc21f6d8462d215108e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 28 May 2011 17:33:25 +0200 Subject: [PATCH] App installer backend. Not yet attached to the gui --- lib/app.php | 15 +++++--- lib/helper.php | 42 +++++++++++++++++++- lib/installer.php | 97 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 146 insertions(+), 8 deletions(-) diff --git a/lib/app.php b/lib/app.php index 83c80f6356e..cec7468c8e7 100644 --- a/lib/app.php +++ b/lib/app.php @@ -317,20 +317,23 @@ class OC_APP{ /** * @brief Read app metadata from the info.xml file - * @param string $appid id of the app + * @param string $appid id of the app or the path of the info.xml file * @returns array */ public static function getAppInfo($appid){ - $file='apps/'.$appid.'/appinfo/info.xml'; - if(!is_file($file)){ - return array(); + if(is_file($appid)){ + $file=$appid; + }else{ + $file='apps/'.$appid.'/appinfo/info.xml'; + if(!is_file($file)){ + return array(); + } } $data=array(); $content=file_get_contents($file); $xml = new SimpleXMLElement($content); - $info=$xml->info[0]; $data['info']=array(); - foreach($info->children() as $child){ + foreach($xml->children() as $child){ $data[$child->getName()]=(string)$child; } return $data; diff --git a/lib/helper.php b/lib/helper.php index fbca94dc7a8..281761c590b 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -164,7 +164,6 @@ class OC_HELPER { * @param $path path to file or folder * @param $filemode unix style file permissions as integer * - * Makes 2048 to 2 kB. */ static function chmodr($path, $filemode) { if (!is_dir($path)) @@ -187,6 +186,47 @@ class OC_HELPER { else return FALSE; } + + /** + * @brief Recusive copying of folders + * @param string $src source folder + * @param string $dest target folder + * + */ + static function copyr($src, $dest) { + if(is_dir($src)){ + if(!is_dir($dest)){ + mkdir($dest); + } + $files = scandir($src); + foreach ($files as $file){ + if ($file != "." && $file != ".."){ + self::copyr("$src/$file", "$dest/$file"); + } + } + }elseif(file_exists($src)){ + copy($src, $dest); + } + } + + /** + * @brief Recusive deletion of folders + * @param string $dir path to the folder + * + */ + static function rmdirr($dir) { + if(is_dir($dir)) { + $files=scandir($dir); + foreach($files as $file){ + if ($file != "." && $file != ".."){ + self::rmdirr("$dir/$file"); + } + } + rmdir($dir); + }elseif(file_exists($dir)){ + unlink($dir); + } + } /** * @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. diff --git a/lib/installer.php b/lib/installer.php index c389fe9c0cc..7ab07bf5077 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -47,6 +47,7 @@ class OC_INSTALLER{ * This function works as follows * -# fetching the file * -# unzipping it + * -# installing the database at appinfo/database.xml * -# including appinfo/install.php * -# setting the installed version * @@ -54,7 +55,101 @@ class OC_INSTALLER{ * needed to get the app working. */ public static function installApp( $data = array()){ - // TODO: write function + global $SERVERROOT; + + if(!isset($data['source'])){ + error_log("No source specified when installing app"); + return; + } + + //download the file if necesary + if($data['source']=='http'){ + $path=tempnam(sys_get_temp_dir(),'oc_installer_'); + if(!isset($data['href'])){ + error_log("No href specified when installing app from http"); + return; + } + copy($data['href'],$path); + }else{ + if(!isset($data['path'])){ + error_log("No path specified when installing app from local file"); + return; + } + $path=$data['path']; + } + + //extract the archive in a temporary folder + $extractDir=tempnam(sys_get_temp_dir(),'oc_installer_uncompressed_'); + unlink($extractDir); + mkdir($extractDir); + $zip = new ZipArchive; + if($zip->open($path)===true){ + $zip->extractTo($extractDir); + $zip->close(); + } else { + error_log("Failed to open archive when installing app"); + OC_HELPER::rmdirr($extractDir); + if($data['source']=='http'){ + unlink($path); + } + return; + } + + //load the info.xml file of the app + if(!is_file($extractDir.'/appinfo/info.xml')){ + error_log("App does not provide an info.xml file"); + OC_HELPER::rmdirr($extractDir); + if($data['source']=='http'){ + unlink($path); + } + return; + } + $info=OC_APP::getAppInfo($extractDir.'/appinfo/info.xml'); + $basedir=$SERVERROOT.'/apps/'.$info['id']; + + //check if an app with the same id is already installed + if(is_dir($basedir)){ + error_log("App already installed"); + OC_HELPER::rmdirr($extractDir); + if($data['source']=='http'){ + unlink($path); + } + return; + } + + if(isset($data['pretent']) and $data['pretent']==true){ + return; + } + + //copy the app to the correct place + if(!mkdir($basedir)){ + error_log('Can\'t create app folder ('.$basedir.')'); + OC_HELPER::rmdirr($extractDir); + if($data['source']=='http'){ + unlink($path); + } + return; + } + OC_HELPER::copyr($extractDir,$basedir); + + //remove temporary files + OC_HELPER::rmdirr($extractDir); + if($data['source']=='http'){ + unlink($path); + } + + //install the database + if(is_file($basedir.'/appinfo/database.xml')){ + OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml'); + } + + //run appinfo/install.php + if(!isset($data['noinstall']) or $data['noinstall']==false and is_file($basedir.'/appinfo/install.php')){ + include($basedir.'/appinfo/install.php'); + } + + //set the installed version + OC_APPCONFIG::setValue($info['id'],'installed_version',$info['version']); return true; }