PageRenderTime 57ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/src/libraries/controllers/SetupController.php

https://github.com/iamxande/frontend
PHP | 413 lines | 305 code | 49 blank | 59 comment | 73 complexity | 02303ad229278f7ff1063d5271d86616 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(count($errors) > 0)
  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. $body = getTheme()->get('setup.php', array('step' => $step, 'usesAws' => $usesAws, 'usesMySql' => $usesMySql, 'usesLocalFs' => $usesLocalFs, 'usesS3' => $usesS3, 'usesSimpleDb' => $usesSimpleDb, 'appId' => $appId));
  117. getTheme()->display('template.php', array('body' => $body, 'page' => 'setup'));
  118. }
  119. /**
  120. * Posts the setup values from step 3 of the form, checks them, and saves in session
  121. *
  122. * @return void HTTP redirect (home)
  123. */
  124. public static function setup3Post()
  125. {
  126. $step = 3;
  127. $appId = getSession()->get('appId');
  128. $usesAws = (getSession()->get('database') == 'SimpleDb' || getSession()->get('fileSystem') == 'S3') ? true : false;
  129. $usesMySql = (getSession()->get('database') == 'MySql') ? true : false;
  130. $usesLocalFs = (getSession()->get('fileSystem') == 'LocalFs') ? true : false;
  131. $usesS3 = (getSession()->get('fileSystem') == 'S3') ? true : false;
  132. $usesSimpleDb = (getSession()->get('database') == 'SimpleDb') ? true : false;
  133. $awsErrors = false;
  134. $mySqlErrors = false;
  135. $localFsErrors = false;
  136. $fsErrors = false;
  137. $dbErrors = false;
  138. $writeErrors = false;
  139. if($usesAws)
  140. {
  141. $awsKey = $_POST['awsKey'];
  142. $awsSecret = $_POST['awsSecret'];
  143. $input = array(
  144. array('Amazon Access Key ID', $awsKey, 'required'),
  145. array('Amazon Secret Access Key', $awsSecret, 'required')
  146. );
  147. if($usesS3)
  148. {
  149. $s3Bucket = $_POST['s3Bucket'];
  150. $input[] = array('Amazon S3 Bucket Name', $s3Bucket, 'required');
  151. }
  152. if($usesSimpleDb)
  153. {
  154. $simpleDbDomain = $_POST['simpleDbDomain'];
  155. $input[] = array('Amazon SimpleDb Domain', $simpleDbDomain, 'required');
  156. }
  157. $awsErrors = getForm()->hasErrors($input);
  158. }
  159. if($usesMySql)
  160. {
  161. $mySqlHost = $_POST['mySqlHost'];
  162. $mySqlUser = $_POST['mySqlUser'];
  163. $mySqlPassword = $_POST['mySqlPassword'];
  164. $mySqlDb = $_POST['mySqlDb'];
  165. $input = array(
  166. array('MySQL Host', $mySqlHost, 'required'),
  167. array('MySQL Username', $mySqlUser, 'required'),
  168. array('MySQL Password', $mySqlPassword, 'required')
  169. );
  170. $mySqlErrors = getForm()->hasErrors($input);
  171. }
  172. if($usesLocalFs)
  173. {
  174. $fsRoot = $_POST['fsRoot'];
  175. $fsHost = $_POST['fsHost'];
  176. $input = array(
  177. array('File System Root', $fsRoot, 'required'),
  178. array('File System Host', $fsHost, 'required')
  179. );
  180. $localFsErrors = getForm()->hasErrors($input);
  181. }
  182. if($awsErrors === false && $mySqlErrors === false && $localFsErrors === false)
  183. {
  184. $credentials = new stdClass;
  185. if($usesAws)
  186. {
  187. getSession()->set('awsKey', $awsKey);
  188. getSession()->set('awsSecret', $awsSecret);
  189. $credentials->awsKey = $awsKey;
  190. $credentials->awsSecret = $awsSecret;
  191. $aws = new stdClass;
  192. if($usesS3)
  193. {
  194. getSession()->set('s3BucketName', $s3Bucket);
  195. $aws->s3BucketName = $s3Bucket;
  196. $aws->s3Host = "{$s3Bucket}.s3.amazonaws.com";
  197. }
  198. if($usesSimpleDb)
  199. {
  200. getSession()->set('simpleDbDomain', $simpleDbDomain);
  201. $aws->simpleDbDomain = $simpleDbDomain;
  202. }
  203. }
  204. if($usesMySql)
  205. {
  206. getSession()->set('mySqlHost', $mySqlHost);
  207. getSession()->set('mySqlUser', $mySqlUser);
  208. getSession()->set('mySqlPassword', $mySqlPassword);
  209. getSession()->set('mySqlDb', $mySqlDb);
  210. $mysql = new stdClass;
  211. $mysql->mySqlHost = $mySqlHost;
  212. $mysql->mySqlUser = $mySqlUser;
  213. $mysql->mySqlPassword = $mySqlPassword;
  214. $mysql->mySqlDb = $mySqlDb;
  215. }
  216. if($usesLocalFs)
  217. {
  218. getSession()->set('fsRoot', $fsRoot);
  219. getSession()->set('fsHost', $fsHost);
  220. $fs = new stdClass;
  221. $fs->fsRoot = $fsRoot;
  222. $fs->fsHost = $fsHost;
  223. }
  224. $systems = new stdClass;
  225. $systems->database = getSession()->get('database');
  226. $systems->fileSystem = getSession()->get('fileSystem');
  227. // save the config info
  228. getConfig()->set('credentials', $credentials);
  229. if($usesAws)
  230. getConfig()->set('aws', $aws);
  231. if($usesMySql)
  232. getConfig()->set('mysql', $mysql);
  233. if($usesLocalFs)
  234. getConfig()->set('localfs', $fs);
  235. getConfig()->set('systems', $systems);
  236. $fsObj = getFs();
  237. $dbObj = getDb();
  238. if(!$fsObj->initialize())
  239. {
  240. if($usesAws)
  241. $fsErrors[] = 'Unable to initialize s3';
  242. else if($usesLocalFs)
  243. $fsErrors[] = 'Unable to initialize the file system';
  244. else
  245. $fsErrors[] = 'File system error';
  246. }
  247. if(!$dbObj->initialize())
  248. {
  249. if($usesAws)
  250. $dbErrors[] = 'Unable to initialize simpledb';
  251. else if($usesMySql)
  252. $fsErrors[] = 'Unable to initialize mysql';
  253. else
  254. $fsErrors[] = 'Database error';
  255. }
  256. if($fsErrors === false && $dbErrors === false)
  257. {
  258. $writeError = self::writeConfigFile();
  259. if($writeErrors === false)
  260. getRoute()->redirect('/?m=welcome');
  261. else
  262. $writeErrors[] = 'Error writing settings ini file';
  263. }
  264. }
  265. // combine all errors if they exist
  266. $errors = array();
  267. if(is_array($awsErrors))
  268. $errors = array_merge($errors, $awsErrors);
  269. if(is_array($mySqlErrors))
  270. $errors = array_merge($errors, $mySqlErrors);
  271. if(is_array($localFsErrors))
  272. $errors = array_merge($errors, $localFsErrors);
  273. if(is_array($fsErrors))
  274. $errors = array_merge($errors, $fsErrors);
  275. if(is_array($dbErrors))
  276. $errors = array_merge($errors, $dbErrors);
  277. if(is_array($writeErrors))
  278. $errors = array_merge($errors, $writeErrors);
  279. $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));
  280. getTheme()->display('template.php', array('body' => $body, 'page' => 'setup'));
  281. }
  282. /**
  283. * Clears out the session data and redirects to step 1
  284. *
  285. * @return void HTTP redirect (setup step 1)
  286. */
  287. public static function setupRestart()
  288. {
  289. getSession()->end();
  290. getRoute()->redirect('/setup');
  291. }
  292. /**
  293. * Verify the server requirements are available on this host.
  294. *
  295. * @return mixed TRUE on success, array on error
  296. */
  297. private static function verifyRequirements($imageLibs)
  298. {
  299. $errors = array();
  300. $configDir = dirname(dirname(dirname(__FILE__))) . '/configs';
  301. $generatedDir = "{$configDir}/generated";
  302. if(file_exists($generatedDir) && is_writable($generatedDir) && !empty($imageLibs))
  303. # No errors, return empty array
  304. return $errors;
  305. $user = exec("whoami");
  306. if(empty($user))
  307. $user = 'Apache user';
  308. if(!is_writable($configDir))
  309. $errors[] = "Please make sure {$user} can write to {$configDir}";
  310. if(!file_exists($generatedDir))
  311. {
  312. $createDir = mkdir($generatedDir, 0700);
  313. if(!$createDir)
  314. $errors[] = "An error occurred while trying to create {$generatedDir}";
  315. }
  316. elseif(!is_writable($generatedDir))
  317. $errors[] = "{$generatedDir} exists but is not writable by {$user}";
  318. if(empty($imageLibs))
  319. $errors[] = "The Imagick library, Gmagick library, or GD library do not exist";
  320. return $errors;
  321. }
  322. /**
  323. * Write out the settings config file
  324. *
  325. * @return boolean TRUE on success, FALSE on error
  326. */
  327. private static function writeConfigFile()
  328. {
  329. // continue if no errors
  330. $baseDir = dirname(dirname(dirname(__FILE__)));
  331. $htmlDir = "{$baseDir}/html";
  332. $libDir = "{$baseDir}/libraries";
  333. $configDir = "{$baseDir}/configs";
  334. $replacements = array(
  335. '{adapters}' => "{$libDir}/adapters",
  336. '{configs}' => $configDir,
  337. '{controllers}' => "{$libDir}/controllers",
  338. '{external}' => "{$libDir}/external",
  339. '{libraries}' => "{$libDir}",
  340. '{models}' => "{$libDir}/models",
  341. '{photos}' => "{$htmlDir}/photos",
  342. '{themes}' => "{$htmlDir}/assets/themes",
  343. '{exiftran}' => exec('which exiftran'),
  344. '{localSecret}' => sha1(uniqid(true)),
  345. '{s3Bucket}' => getSession()->get('s3BucketName'),
  346. '{s3Host}' => getSession()->get('s3BucketName') . '.s3.amazonaws.com',
  347. '{email}' => getSession()->get('email')
  348. );
  349. $pReplace = array();
  350. $session = getSession()->getAll();
  351. foreach($session as $key => $val)
  352. $pReplace["{{$key}}"] = $val;
  353. $replacements = array_merge($pReplace, $replacements);
  354. $generatedIni = str_replace(
  355. array_keys($replacements),
  356. array_values($replacements),
  357. file_get_contents("{$configDir}/template.ini")
  358. );
  359. $iniWritten = file_put_contents("{$configDir}/generated/settings.ini", $generatedIni);
  360. if(!$iniWritten)
  361. return false;
  362. return true;
  363. }
  364. }