PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/libraries/controllers/SetupController.php

https://github.com/geraintp/frontend
PHP | 444 lines | 332 code | 53 blank | 59 comment | 79 complexity | f92077dbf44578637b4dcd741d6dcb63 MD5 | raw file
  1. <?php
  2. /**
  3. * Setup controller for HTML endpoints
  4. * This controls the setup flow when the software is first installed.
  5. * The main purpose of this flow is to generate settings.ini.
  6. *
  7. * @author Jaisen Mathai <jaisen@jmathai.com>
  8. * @author Kevin Hornschemeier <khornschemeier@gmail.com>
  9. */
  10. class SetupController
  11. {
  12. /**
  13. * Returns the setup step 1 screen markup.
  14. *
  15. * @return string HTML
  16. */
  17. public static function setup()
  18. {
  19. $step = 1;
  20. $appId = 'openphoto-frontend';
  21. getSession('step', 1);
  22. $imageLibs = array();
  23. if(class_exists('Imagick'))
  24. $imageLibs['ImageMagick'] = 'ImageMagick';
  25. if(class_exists('Gmagick'))
  26. $imageLibs['GraphicsMagick'] = 'GraphicsMagick';
  27. if(extension_loaded('gd') && function_exists('gd_info'))
  28. $imageLibs['GD'] = 'GD';
  29. $errors = self::verifyRequirements($imageLibs);
  30. if($errors !== true)
  31. $step = 0;
  32. else
  33. $errors = '';
  34. $body = getTheme()->get('setup.php', array('imageLibs' => $imageLibs, 'appId' => $appId, 'step' => $step, 'errors' => $errors));
  35. getTheme()->display('template.php', array('body' => $body, 'page' => 'setup'));
  36. }
  37. /**
  38. * Posts the setup values from step 1 of the form, checks them, and saves in session
  39. *
  40. * @return void HTTP redirect (setup step 2)
  41. */
  42. public static function setupPost()
  43. {
  44. $step = 1;
  45. $appId = isset($_POST['appId']) ? $_POST['appId'] : '';
  46. $email = isset($_POST['email']) ? $_POST['email'] : '';
  47. $input = array(
  48. array('Email', $email, 'required')
  49. );
  50. $errors = getForm()->hasErrors($input);
  51. if($errors === false)
  52. {
  53. getSession()->set('step', 2);
  54. getSession()->set('appId', $appId);
  55. getSession()->set('email', $email);
  56. getRoute()->redirect('/setup/2');
  57. }
  58. $body = getTheme()->get('setup.php', array('emai' => $email, 'appId' => $appId, 'step' => $step, 'errors' => $errors));
  59. getTheme()->display('template.php', array('body' => $body, 'page' => 'setup'));
  60. }
  61. /**
  62. * Returns the setup step 2 screen markup.
  63. *
  64. * @return string HTML
  65. */
  66. public static function setup2()
  67. {
  68. // make sure the user should be on this step
  69. if(getSession()->get('step') != 2)
  70. getRoute()->redirect('/setup');
  71. $step = 2;
  72. $imageLibs = array();
  73. if(class_exists('Imagick'))
  74. $imageLibs['ImageMagick'] = 'ImageMagick';
  75. if(class_exists('Gmagick'))
  76. $imageLibs['GraphicsMagick'] = 'GraphicsMagick';
  77. if(extension_loaded('gd') && function_exists('gd_info'))
  78. $imageLibs['GD'] = 'GD';
  79. $body = getTheme()->get('setup.php', array('imageLibs' => $imageLibs, 'appId' => 'openphoto-frontend', 'step' => $step));
  80. getTheme()->display('template.php', array('body' => $body, 'page' => 'setup'));
  81. }
  82. /**
  83. * Posts the setup values from step 2 of the form, checks them, and saves in session
  84. *
  85. * @return void HTTP redirect (setup step 3)
  86. */
  87. public static function setup2Post()
  88. {
  89. getSession()->set('step', 3);
  90. getSession()->set('imageLibrary', $_POST['imageLibrary']);
  91. getSession()->set('database', $_POST['database']);
  92. getSession()->set('fileSystem', $_POST['fileSystem']);
  93. getRoute()->redirect('/setup/3');
  94. }
  95. /**
  96. * Returns the setup step 3 screen markup.
  97. *
  98. * @return string HTML
  99. */
  100. public static function setup3()
  101. {
  102. // make sure the user should be on this step
  103. if(getSession()->get('step') != 3)
  104. {
  105. if(getSession()->get('step') == 2)
  106. getRoute()->redirect('/setup/2');
  107. getRoute()->redirect('/setup');
  108. }
  109. $step = 3;
  110. $appId = getSession()->get('appId');
  111. $usesAws = (getSession()->get('database') == 'SimpleDb' || getSession()->get('fileSystem') == 'S3') ? true : false;
  112. $usesMySql = (getSession()->get('database') == 'MySql') ? true : false;
  113. $usesLocalFs = (getSession()->get('fileSystem') == 'LocalFs') ? true : false;
  114. $usesS3 = (getSession()->get('fileSystem') == 'S3') ? true : false;
  115. $usesSimpleDb = (getSession()->get('database') == 'SimpleDb') ? true : false;
  116. $usesCloudFiles = (getSession()->get('fileSystem') == 'CloudFiles') ? true : false;
  117. $body = getTheme()->get('setup.php', array('step' => $step, 'usesAws' => $usesAws, 'usesMySql' => $usesMySql, 'usesLocalFs' => $usesLocalFs, 'usesS3' => $usesS3, 'usesCloudFiles' => $usesCloudFiles, 'usesSimpleDb' => $usesSimpleDb, 'appId' => $appId));
  118. getTheme()->display('template.php', array('body' => $body, 'page' => 'setup'));
  119. }
  120. /**
  121. * Posts the setup values from step 3 of the form, checks them, and saves in session
  122. *
  123. * @return void HTTP redirect (home)
  124. */
  125. public static function setup3Post()
  126. {
  127. $step = 3;
  128. $appId = getSession()->get('appId');
  129. $usesAws = (getSession()->get('database') == 'SimpleDb' || getSession()->get('fileSystem') == 'S3') ? true : false;
  130. $usesMySql = (getSession()->get('database') == 'MySql') ? true : false;
  131. $usesLocalFs = (getSession()->get('fileSystem') == 'LocalFs') ? true : false;
  132. $usesS3 = (getSession()->get('fileSystem') == 'S3') ? true : false;
  133. $usesCloudFiles = (getSession()->get('fileSystem') == 'CloudFiles') ? true : false;
  134. $usesSimpleDb = (getSession()->get('database') == 'SimpleDb') ? true : false;
  135. $awsErrors = false;
  136. $mySqlErrors = false;
  137. $localFsErrors = false;
  138. $cfErrors = false;
  139. $fsErrors = false;
  140. $dbErrors = false;
  141. $writeErrors = false;
  142. if($usesAws)
  143. {
  144. $awsKey = $_POST['awsKey'];
  145. $awsSecret = $_POST['awsSecret'];
  146. $input = array(
  147. array('Amazon Access Key ID', $awsKey, 'required'),
  148. array('Amazon Secret Access Key', $awsSecret, 'required')
  149. );
  150. if($usesS3)
  151. {
  152. $s3Bucket = $_POST['s3Bucket'];
  153. $input[] = array('Amazon S3 Bucket Name', $s3Bucket, 'required');
  154. }
  155. if($usesSimpleDb)
  156. {
  157. $simpleDbDomain = $_POST['simpleDbDomain'];
  158. $input[] = array('Amazon SimpleDb Domain', $simpleDbDomain, 'required');
  159. }
  160. $awsErrors = getForm()->hasErrors($input);
  161. }
  162. if($usesMySql)
  163. {
  164. $mySqlHost = $_POST['mySqlHost'];
  165. $mySqlUser = $_POST['mySqlUser'];
  166. $mySqlPassword = $_POST['mySqlPassword'];
  167. $mySqlDb = $_POST['mySqlDb'];
  168. $input = array(
  169. array('MySQL Host', $mySqlHost, 'required'),
  170. array('MySQL Username', $mySqlUser, 'required'),
  171. array('MySQL Password', $mySqlPassword, 'required')
  172. );
  173. $mySqlErrors = getForm()->hasErrors($input);
  174. }
  175. if($usesLocalFs)
  176. {
  177. $fsRoot = $_POST['fsRoot'];
  178. $fsHost = $_POST['fsHost'];
  179. $input = array(
  180. array('File System Root', $fsRoot, 'required'),
  181. array('File System Host', $fsHost, 'required')
  182. );
  183. $localFsErrors = getForm()->hasErrors($input);
  184. }
  185. if ($usesCloudFiles) {
  186. $cfUserName = $_POST['cfUserName'];
  187. $cfApiKey = $_POST['cfApiKey'];
  188. $cfContainer = $_POST['cfContainer'];
  189. $cfAuthUrl = $_POST['cfAuthUrl'];
  190. $input = array(
  191. array('CloudFiles Username', $cfUserName, 'required'),
  192. array('CloudFiles API Key', $cfApiKey, 'required'),
  193. array('CloudFiles Container', $cfContainer, 'required')
  194. );
  195. $mySqlErrors = getForm()->hasErrors($input);
  196. }
  197. if($awsErrors === false && $mySqlErrors === false && $localFsErrors === false && $cfErrors === false)
  198. {
  199. $credentials = new stdClass;
  200. if($usesAws)
  201. {
  202. getSession()->set('awsKey', $awsKey);
  203. getSession()->set('awsSecret', $awsSecret);
  204. $credentials->awsKey = $awsKey;
  205. $credentials->awsSecret = $awsSecret;
  206. $aws = new stdClass;
  207. if($usesS3)
  208. {
  209. getSession()->set('s3BucketName', $s3Bucket);
  210. $aws->s3BucketName = $s3Bucket;
  211. $aws->s3Host = "{$s3Bucket}.s3.amazonaws.com";
  212. }
  213. if($usesSimpleDb)
  214. {
  215. getSession()->set('simpleDbDomain', $simpleDbDomain);
  216. $aws->simpleDbDomain = $simpleDbDomain;
  217. }
  218. }
  219. if($usesMySql)
  220. {
  221. getSession()->set('mySqlHost', $mySqlHost);
  222. getSession()->set('mySqlUser', $mySqlUser);
  223. getSession()->set('mySqlPassword', $mySqlPassword);
  224. getSession()->set('mySqlDb', $mySqlDb);
  225. $mysql = new stdClass;
  226. $mysql->mySqlHost = $mySqlHost;
  227. $mysql->mySqlUser = $mySqlUser;
  228. $mysql->mySqlPassword = $mySqlPassword;
  229. $mysql->mySqlDb = $mySqlDb;
  230. }
  231. if($usesLocalFs)
  232. {
  233. getSession()->set('fsRoot', $fsRoot);
  234. getSession()->set('fsHost', $fsHost);
  235. $fs = new stdClass;
  236. $fs->fsRoot = $fsRoot;
  237. $fs->fsHost = $fsHost;
  238. }
  239. if($usesCloudFiles){
  240. getSession()->set('cfUserName', $cfUserName);
  241. getSession()->set('cfApiKey', $cfApiKey);
  242. getSession()->set('cfContainer', $cfContainer);
  243. getSession()->set('cfAuthUrl', $cfAuthUrl);
  244. $cf = new stdClass;
  245. $cf->cfUserName = $cfUserName;
  246. $cf->cfApiKey = $cfApiKey;
  247. $cf->cfContainer = $cfContainer;
  248. $cf->cfAuthUrl = $cfAuthUrl;
  249. }
  250. //print_r($cf);
  251. $systems = new stdClass;
  252. $systems->database = getSession()->get('database');
  253. $systems->fileSystem = getSession()->get('fileSystem');
  254. // save the config info
  255. getConfig()->set('credentials', $credentials);
  256. if($usesAws)
  257. getConfig()->set('aws', $aws);
  258. if($usesMySql)
  259. getConfig()->set('mysql', $mysql);
  260. if($usesLocalFs)
  261. getConfig()->set('localfs', $fs);
  262. if ($usesCloudFiles)
  263. getConfig()->set('cloudfiles', $cf);
  264. getConfig()->set('systems', $systems);
  265. $fsObj = getFs();
  266. $dbObj = getDb();
  267. if(!$fsObj->initialize())
  268. {
  269. if($usesAws)
  270. $fsErrors[] = 'Unable to initialize s3';
  271. else if($usesLocalFs)
  272. $fsErrors[] = 'Unable to initialize the file system';
  273. else
  274. $fsErrors[] = 'File system error';
  275. }
  276. if(!$dbObj->initialize())
  277. {
  278. if($usesAws)
  279. $dbErrors[] = 'Unable to initialize simpledb';
  280. else if($usesMySql)
  281. $fsErrors[] = 'Unable to initialize mysql';
  282. else
  283. $fsErrors[] = 'Database error';
  284. }
  285. if($fsErrors === false && $dbErrors === false)
  286. {
  287. $writeError = self::writeConfigFile();
  288. if($writeErrors === false)
  289. getRoute()->redirect('/?m=welcome');
  290. else
  291. $writeErrors[] = 'Error writing settings ini file';
  292. }
  293. }
  294. // combine all errors if they exist
  295. $errors = array();
  296. if(is_array($awsErrors))
  297. $errors = array_merge($errors, $awsErrors);
  298. if(is_array($mySqlErrors))
  299. $errors = array_merge($errors, $mySqlErrors);
  300. if(is_array($localFsErrors))
  301. $errors = array_merge($errors, $localFsErrors);
  302. if(is_array($fsErrors))
  303. $errors = array_merge($errors, $fsErrors);
  304. if(is_array($dbErrors))
  305. $errors = array_merge($errors, $dbErrors);
  306. if(is_array($writeErrors))
  307. $errors = array_merge($errors, $writeErrors);
  308. $body = getTheme()->get('setup.php', array('step' => $step, 'usesAws' => $usesAws, 'usesMySql' => $usesMySql, 'usesLocalFs' => $usesLocalFs, 'usesS3' => $usesS3, 'usesSimpleDb' => $usesSimpleDb, 's3Bucket' => $s3Bucket, 'simpleDbDomain' => $simpleDbDomain, 'appId' => $appId, 'errors' => $errors));
  309. getTheme()->display('template.php', array('body' => $body, 'page' => 'setup'));
  310. }
  311. /**
  312. * Clears out the session data and redirects to step 1
  313. *
  314. * @return void HTTP redirect (setup step 1)
  315. */
  316. public static function setupRestart()
  317. {
  318. getSession()->end();
  319. getRoute()->redirect('/setup');
  320. }
  321. /**
  322. * Verify the server requirements are available on this host.
  323. *
  324. * @return mixed TRUE on success, array on error
  325. */
  326. private static function verifyRequirements($imageLibs)
  327. {
  328. $errors = array();
  329. $configDir = dirname(dirname(dirname(__FILE__))) . '/configs';
  330. $generatedDir = "{$configDir}/generated";
  331. if(file_exists($generatedDir) && is_writable($generatedDir) && !empty($imageLibs))
  332. return true;
  333. $user = exec("whoami");
  334. if(empty($user))
  335. $user = 'Apache user';
  336. if(!is_writable($configDir))
  337. $errors[] = "Please make sure {$user} can write to {$configDir}";
  338. if(!file_exists($generatedDir))
  339. {
  340. $createDir = mkdir($generatedDir, 0700);
  341. if(!$createDir)
  342. $errors[] = "An error occurred while trying to create {$generatedDir}";
  343. }
  344. elseif(!is_writable($generatedDir))
  345. $errors[] = "{$generatedDir} exists but is not writable by {$user}";
  346. if(empty($imageLibs))
  347. $errors[] = "The Imagick library, Gmagick library, or GD library do not exist";
  348. return $errors;
  349. }
  350. /**
  351. * Write out the settings config file
  352. *
  353. * @return boolean TRUE on success, FALSE on error
  354. */
  355. private static function writeConfigFile()
  356. {
  357. // continue if no errors
  358. $baseDir = dirname(dirname(dirname(__FILE__)));
  359. $htmlDir = "{$baseDir}/html";
  360. $libDir = "{$baseDir}/libraries";
  361. $configDir = "{$baseDir}/configs";
  362. $replacements = array(
  363. '{adapters}' => "{$libDir}/adapters",
  364. '{configs}' => $configDir,
  365. '{controllers}' => "{$libDir}/controllers",
  366. '{external}' => "{$libDir}/external",
  367. '{libraries}' => "{$libDir}",
  368. '{models}' => "{$libDir}/models",
  369. '{photos}' => "{$htmlDir}/photos",
  370. '{themes}' => "{$htmlDir}/assets/themes",
  371. '{exiftran}' => exec('which exiftran'),
  372. '{localSecret}' => sha1(uniqid(true)),
  373. '{s3Host}' => getSession()->get('s3BucketName') . '.s3.amazonaws.com',
  374. '{email}' => getSession()->get('email')
  375. );
  376. $pReplace = array();
  377. $session = getSession()->getAll();
  378. foreach($session as $key => $val)
  379. $pReplace["{{$key}}"] = $val;
  380. $replacements = array_merge($pReplace, $replacements);
  381. $generatedIni = str_replace(
  382. array_keys($replacements),
  383. array_values($replacements),
  384. file_get_contents("{$configDir}/template.ini")
  385. );
  386. $iniWritten = file_put_contents("{$configDir}/generated/settings.ini", $generatedIni);
  387. if(!$iniWritten)
  388. return false;
  389. return true;
  390. }
  391. }