You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

installer.php 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <?php
  2. /**
  3. * ownCloud
  4. *
  5. * @author Robin Appelman
  6. * @copyright 2010 Frank Karlitschek karlitschek@kde.org
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public
  19. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * This class provides the functionality needed to install, update and remove plugins/apps
  24. */
  25. class OC_Installer{
  26. /**
  27. * @brief Installs an app
  28. * @param $data array with all information
  29. * @returns integer
  30. *
  31. * This function installs an app. All information needed are passed in the
  32. * associative array $data.
  33. * The following keys are required:
  34. * - source: string, can be "path" or "http"
  35. *
  36. * One of the following keys is required:
  37. * - path: path to the file containing the app
  38. * - href: link to the downloadable file containing the app
  39. *
  40. * The following keys are optional:
  41. * - pretend: boolean, if set true the system won't do anything
  42. * - noinstall: boolean, if true appinfo/install.php won't be loaded
  43. * - inactive: boolean, if set true the appconfig/app.sample.php won't be
  44. * renamed
  45. *
  46. * This function works as follows
  47. * -# fetching the file
  48. * -# unzipping it
  49. * -# installing the database at appinfo/database.xml
  50. * -# including appinfo/install.php
  51. * -# setting the installed version
  52. *
  53. * It is the task of oc_app_install to create the tables and do whatever is
  54. * needed to get the app working.
  55. */
  56. public static function installApp( $data = array()){
  57. global $SERVERROOT;
  58. if(!isset($data['source'])){
  59. error_log("No source specified when installing app");
  60. return false;
  61. }
  62. //download the file if necesary
  63. if($data['source']=='http'){
  64. $path=tempnam(sys_get_temp_dir(),'oc_installer_');
  65. if(!isset($data['href'])){
  66. error_log("No href specified when installing app from http");
  67. return false;
  68. }
  69. copy($data['href'],$path);
  70. }else{
  71. if(!isset($data['path'])){
  72. error_log("No path specified when installing app from local file");
  73. return false;
  74. }
  75. $path=$data['path'];
  76. }
  77. //extract the archive in a temporary folder
  78. $extractDir=tempnam(sys_get_temp_dir(),'oc_installer_uncompressed_');
  79. unlink($extractDir);
  80. mkdir($extractDir);
  81. $zip = new ZipArchive;
  82. if($zip->open($path)===true){
  83. $zip->extractTo($extractDir);
  84. $zip->close();
  85. } else {
  86. error_log("Failed to open archive when installing app");
  87. OC_Helper::rmdirr($extractDir);
  88. if($data['source']=='http'){
  89. unlink($path);
  90. }
  91. return false;
  92. }
  93. //load the info.xml file of the app
  94. if(!is_file($extractDir.'/appinfo/info.xml')){
  95. error_log("App does not provide an info.xml file");
  96. OC_Helper::rmdirr($extractDir);
  97. if($data['source']=='http'){
  98. unlink($path);
  99. }
  100. return false;
  101. }
  102. $info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml');
  103. $basedir=$SERVERROOT.'/apps/'.$info['id'];
  104. //check if an app with the same id is already installed
  105. if(self::isInstalled( $info['id'] )){
  106. error_log("App already installed");
  107. OC_Helper::rmdirr($extractDir);
  108. if($data['source']=='http'){
  109. unlink($path);
  110. }
  111. return false;
  112. }
  113. //check if the destination directory already exists
  114. if(is_dir($basedir)){
  115. error_log("App's directory already exists");
  116. OC_Helper::rmdirr($extractDir);
  117. if($data['source']=='http'){
  118. unlink($path);
  119. }
  120. return false;
  121. }
  122. if(isset($data['pretent']) and $data['pretent']==true){
  123. return false;
  124. }
  125. //copy the app to the correct place
  126. if(!mkdir($basedir)){
  127. error_log('Can\'t create app folder ('.$basedir.')');
  128. OC_Helper::rmdirr($extractDir);
  129. if($data['source']=='http'){
  130. unlink($path);
  131. }
  132. return false;
  133. }
  134. OC_Helper::copyr($extractDir,$basedir);
  135. //remove temporary files
  136. OC_Helper::rmdirr($extractDir);
  137. if($data['source']=='http'){
  138. unlink($path);
  139. }
  140. //install the database
  141. if(is_file($basedir.'/appinfo/database.xml')){
  142. OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml');
  143. }
  144. //run appinfo/install.php
  145. if(!isset($data['noinstall']) or $data['noinstall']==false and is_file($basedir.'/appinfo/install.php')){
  146. include($basedir.'/appinfo/install.php');
  147. }
  148. //set the installed version
  149. OC_Appconfig::setValue($info['id'],'installed_version',$info['version']);
  150. OC_Appconfig::setValue($info['id'],'enabled','no');
  151. return true;
  152. }
  153. /**
  154. * @brief checks whether or not an app is installed
  155. * @param $app app
  156. * @returns true/false
  157. *
  158. * Checks whether or not an app is installed, i.e. registered in apps table.
  159. */
  160. public static function isInstalled( $app ){
  161. if( null == OC_Appconfig::getValue( $app, "installed_version" )){
  162. return false;
  163. }
  164. return true;
  165. }
  166. /**
  167. * @brief Update an application
  168. * @param $data array with all information
  169. * @returns integer
  170. *
  171. * This function installs an app. All information needed are passed in the
  172. * associative array $data.
  173. * The following keys are required:
  174. * - source: string, can be "path" or "http"
  175. *
  176. * One of the following keys is required:
  177. * - path: path to the file containing the app
  178. * - href: link to the downloadable file containing the app
  179. *
  180. * The following keys are optional:
  181. * - pretend: boolean, if set true the system won't do anything
  182. * - noupgrade: boolean, if true appinfo/upgrade.php won't be loaded
  183. *
  184. * This function works as follows
  185. * -# fetching the file
  186. * -# removing the old files
  187. * -# unzipping new file
  188. * -# including appinfo/upgrade.php
  189. * -# setting the installed version
  190. *
  191. * upgrade.php can determine the current installed version of the app using "OC_Appconfig::getValue($appid,'installed_version')"
  192. */
  193. public static function upgradeApp( $data = array()){
  194. // TODO: write function
  195. return true;
  196. }
  197. /**
  198. * @brief Removes an app
  199. * @param $name name of the application to remove
  200. * @param $options array with options
  201. * @returns true/false
  202. *
  203. * This function removes an app. $options is an associative array. The
  204. * following keys are optional:ja
  205. * - keeppreferences: boolean, if true the user preferences won't be deleted
  206. * - keepappconfig: boolean, if true the config will be kept
  207. * - keeptables: boolean, if true the database will be kept
  208. * - keepfiles: boolean, if true the user files will be kept
  209. *
  210. * This function works as follows
  211. * -# including appinfo/remove.php
  212. * -# removing the files
  213. *
  214. * The function will not delete preferences, tables and the configuration,
  215. * this has to be done by the function oc_app_uninstall().
  216. */
  217. public static function removeApp( $name, $options = array()){
  218. // TODO: write function
  219. return true;
  220. }
  221. /**
  222. * @brief Installs shipped apps
  223. * @param $enabled
  224. *
  225. * This function installs all apps found in the 'apps' directory;
  226. * If $enabled is true, apps are installed as enabled.
  227. * If $enabled is false, apps are installed as disabled.
  228. */
  229. public static function installShippedApps( $enabled ){
  230. global $SERVERROOT;
  231. $dir = opendir( "$SERVERROOT/apps" );
  232. while( false !== ( $filename = readdir( $dir ))){
  233. if( substr( $filename, 0, 1 ) != '.' and is_dir("$SERVERROOT/apps/$filename") ){
  234. if( file_exists( "$SERVERROOT/apps/$filename/appinfo/app.php" )){
  235. if(!OC_Installer::isInstalled($filename)){
  236. //install the database
  237. if(is_file("$SERVERROOT/apps/$filename/appinfo/database.xml")){
  238. OC_DB::createDbFromStructure("$SERVERROOT/apps/$filename/appinfo/database.xml");
  239. }
  240. //run appinfo/install.php
  241. if(is_file("$SERVERROOT/apps/$filename/appinfo/install.php")){
  242. include("$SERVERROOT/apps/$filename/appinfo/install.php");
  243. }
  244. $info=OC_App::getAppInfo("$SERVERROOT/apps/$filename/appinfo/info.xml");
  245. OC_Appconfig::setValue($filename,'installed_version',$info['version']);
  246. if( $enabled ){
  247. OC_Appconfig::setValue($filename,'enabled','yes');
  248. }else{
  249. OC_Appconfig::setValue($filename,'enabled','no');
  250. }
  251. }
  252. }
  253. }
  254. }
  255. closedir( $dir );
  256. }
  257. }