SproutCMS

This is the code documentation for the SproutCMS project

source of /modules/Welcome/Controllers/WelcomeController.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. namespace SproutModules\Karmabunny\Welcome\Controllers;
  15.  
  16. use Exception;
  17. use PDOException;
  18.  
  19. use Kohana;
  20.  
  21. use Sprout\Controllers\Controller;
  22. use karmabunny\pdb\Exceptions\QueryException;
  23. use Sprout\Helpers\AdminAuth;
  24. use Sprout\Helpers\Auth;
  25. use Sprout\Helpers\Constants;
  26. use Sprout\Helpers\DatabaseSync;
  27. use Sprout\Helpers\Enc;
  28. use Sprout\Helpers\File;
  29. use Sprout\Helpers\FileConstants;
  30. use Sprout\Helpers\Form;
  31. use Sprout\Helpers\Json;
  32. use Sprout\Helpers\Notification;
  33. use Sprout\Helpers\Pdb;
  34. use Sprout\Helpers\Security;
  35. use Sprout\Helpers\Session;
  36. use Sprout\Helpers\Sprout;
  37. use Sprout\Helpers\Url;
  38. use Sprout\Helpers\Validator;
  39. use Sprout\Helpers\View;
  40.  
  41.  
  42. /**
  43.  * Forms used for setting up SproutCMS for the first time
  44.  */
  45. class WelcomeController extends Controller
  46. {
  47.  
  48. public function __construct()
  49. {
  50. Session::instance();
  51. }
  52.  
  53.  
  54. /**
  55.   * Redirect home page traffic to the welcome checklist
  56.   */
  57. public function redirect()
  58. {
  59. Url::redirect('welcome/checklist');
  60. }
  61.  
  62.  
  63. /**
  64.   * Show a phpinfo() view along with some extra information
  65.   */
  66. public function phpInfo()
  67. {
  68. $view = new View('modules/Welcome/phpinfo');
  69.  
  70. $view->vars = array(
  71. 'PHP version' => phpversion(),
  72. 'PHP sapi' => php_sapi_name(),
  73. 'Server software' => @$_SERVER['SERVER_SOFTWARE'],
  74. 'Server OS' => PHP_OS,
  75. 'DOCROOT' => DOCROOT,
  76. 'KOHANA' => KOHANA,
  77. 'APPPATH' => APPPATH,
  78. 'HTTP_X_FORWARDED_FOR' => @$_SERVER['HTTP_X_FORWARDED_FOR'],
  79. 'REMOTE_ADDR' => @$_SERVER['REMOTE_ADDR'],
  80. 'PHP date' => date('Y-m-d H:i:s'),
  81. );
  82.  
  83. $skin = new View('sprout/admin/login_layout');
  84. $skin->browser_title = 'PHP information';
  85. $skin->main_title = 'PHP information';
  86. $skin->main_content = $view->render();
  87. echo $skin->render();
  88. }
  89.  
  90.  
  91. /**
  92.   * Display the welcome checklist
  93.   */
  94. public function checklist()
  95. {
  96. unset($_SESSION['database_config']);
  97.  
  98. $view = new View('modules/Welcome/checklist');
  99. $view->results = [
  100. 'dbconf' => $this->testDbconf(),
  101. 'superop' => $this->testSuperOp(),
  102. 'dbsync' => $this->testDbsync(),
  103. 'sample' => $this->testSampleContent(),
  104. 'welcome' => $this->testWelcome(),
  105. ];
  106.  
  107. $view->overall_success = true;
  108. foreach($view->results as $row) {
  109. if ($row[0] == false) {
  110. $view->overall_success = false;
  111. break;
  112. }
  113. }
  114.  
  115. // Find the line number which has the welcome module registration
  116. $conf = file_get_contents(DOCROOT . 'config/config.php');
  117. $pos = strpos($conf, "'Welcome'");
  118. $num = substr_count($conf, "\n", 0, $pos);
  119. $view->welcome_line_num = $num + 1;
  120.  
  121. $skin = new View('sprout/admin/login_layout');
  122. $skin->browser_title = 'Welcome to SproutCMS';
  123. $skin->main_title = 'Welcome to SproutCMS';
  124. $skin->main_content = $view->render();
  125. echo $skin->render();
  126. }
  127.  
  128.  
  129. /**
  130.   * Test the database config is correct
  131.   *
  132.   * @return array [0] boolean overall result [1] string message
  133.   */
  134. private function testDbconf()
  135. {
  136. if (!file_exists(DOCROOT . 'config/database.php')) {
  137. return [false];
  138. }
  139.  
  140. try {
  141. Pdb::getConnection();
  142. return [true];
  143. } catch (PDOException $ex) {
  144. return [false, $ex->getMessage()];
  145. } catch (Exception $ex) {
  146. return [false, $ex->getMessage()];
  147. }
  148. }
  149.  
  150.  
  151. /**
  152.   * Test whether one or more super operators have been created
  153.   *
  154.   * @return array [0] boolean overall result [1] string message
  155.   */
  156. private function testSuperOp()
  157. {
  158. try {
  159. $ops = Kohana::config('super_ops.operators');
  160. } catch (Exception $ex) {
  161. $ops = [];
  162. }
  163.  
  164. if (count($ops) > 0) {
  165. return [0 => true, 1 => 'Local file'];
  166. }
  167.  
  168. return [0 => false];
  169. }
  170.  
  171.  
  172. /**
  173.   * Test that tables are available
  174.   *
  175.   * @return array [0] boolean overall result [1] string message
  176.   */
  177. private function testDbsync()
  178. {
  179. try {
  180. $q = "SELECT * FROM ~pages LIMIT 1";
  181. Pdb::query($q, [], 'null');
  182. return [true];
  183. } catch (PDOException $ex) {
  184. return [false, 'Unable to connect to database'];
  185. } catch (QueryException $ex) {
  186. return [false, $ex->getMessage()];
  187. } catch (Exception $ex) {
  188. return [false, $ex->getMessage()];
  189. }
  190. }
  191.  
  192.  
  193. /**
  194.   * Test that sample content has been added
  195.   *
  196.   * @return array [0] boolean overall result [1] string message
  197.   */
  198. private function testSampleContent()
  199. {
  200. try {
  201. $q = "SELECT COUNT(*) FROM ~pages LIMIT 1";
  202. $num_pages = Pdb::query($q, [], 'val');
  203. return [$num_pages > 0];
  204. } catch (PDOException $ex) {
  205. return [false, 'Unable to connect to database'];
  206. } catch (QueryException $ex) {
  207. return [false, $ex->getMessage()];
  208. } catch (Exception $ex) {
  209. return [false, $ex->getMessage()];
  210. }
  211. }
  212.  
  213.  
  214. /**
  215.   * Test that the welcome module isn't installed
  216.   *
  217.   * @return array [0] boolean overall result [1] string message
  218.   */
  219. private function testWelcome()
  220. {
  221. return [
  222. !Sprout::moduleInstalled('Welcome')
  223. ];
  224. }
  225.  
  226.  
  227. /**
  228.   * Show a UI for generating a database config
  229.   */
  230. public function dbConfForm()
  231. {
  232. unset($_SESSION['database_config']);
  233.  
  234. $data = Form::loadFromSession('db_conf');
  235. if (empty($data)) {
  236. Form::setData([
  237. 'host' => 'localhost',
  238. ]);
  239. }
  240.  
  241. $view = new View('modules/Welcome/db_conf_form');
  242.  
  243. $skin = new View('sprout/admin/login_layout');
  244. $skin->browser_title = 'Database sync';
  245. $skin->main_title = 'Database sync';
  246. $skin->main_content = $view->render();
  247. echo $skin->render();
  248. }
  249.  
  250.  
  251. /**
  252.   * Ajax method to test the db connection for a given set of params
  253.   */
  254. public function dbConfTest()
  255. {
  256. if (empty($_POST['host'])) Json::out(['result' => 'You must specify a host']);
  257. if (empty($_POST['user'])) Json::out(['result' => 'You must specify a user']);
  258. if (empty($_POST['pass'])) Json::out(['result' => 'You must specify a pass']);
  259. if (empty($_POST['database'])) Json::out(['result' => 'You must specify a database']);
  260.  
  261. try {
  262. new \PDO(
  263. "mysql:host={$_POST['host']};dbname={$_POST['database']}",
  264. $_POST['user'],
  265. $_POST['pass']
  266. );
  267. Json::out(['result' => 'Connection successful']);
  268. } catch (PDOException $ex) {
  269. Json::out(['result' => $ex->getMessage()]);
  270. }
  271. }
  272.  
  273.  
  274. /**
  275.   * Display the generated database config
  276.   */
  277. public function dbConfResult()
  278. {
  279. $_SESSION['db_conf']['field_values'] = Validator::trim($_POST);
  280.  
  281. $valid = new Validator($_POST);
  282. $valid->required(['production', 'host', 'user', 'pass', 'database']);
  283.  
  284. if ($valid->hasErrors()) {
  285. $_SESSION['db_conf']['field_errors'] = $valid->getFieldErrors();
  286. Url::redirect('welcome/db_conf_form');
  287. } else {
  288. unset($_SESSION['db_conf']);
  289. }
  290.  
  291. $_SESSION['database_config'] = $_POST;
  292.  
  293. $view = new View('modules/Welcome/db_conf_result');
  294. $view->db_config_url = 'welcome/db_conf_database';
  295.  
  296. if ($_POST['production'] == 'live') {
  297. $view->pass_config_url = 'welcome/db_conf_password';
  298. $view->pass_config = self::genPassConfig($_POST);
  299.  
  300. $parts = explode(DIRECTORY_SEPARATOR, rtrim(DOCROOT, DIRECTORY_SEPARATOR));
  301. array_pop($parts);
  302. $view->pass_filename = implode(DIRECTORY_SEPARATOR, $parts) . DIRECTORY_SEPARATOR . 'database.config.php';
  303. } else {
  304. $view->host_config_url = 'welcome/db_conf_hosts';
  305. $view->host_config = self::genDevHostsConfig();
  306.  
  307. $view->dev_hostname = php_uname('n');
  308. }
  309.  
  310. $skin = new View('sprout/admin/login_layout');
  311. $skin->browser_title = 'Database sync';
  312. $skin->main_title = 'Database sync';
  313. $skin->main_content = $view->render();
  314. echo $skin->render();
  315. }
  316.  
  317.  
  318. /**
  319.   * Generate and download a database config file
  320.   */
  321. public static function dbConfDatabase()
  322. {
  323. $config = self::genDbConfig($_SESSION['database_config']);
  324.  
  325. header('Content-type: application/php');
  326. header('Content-disposition: attachment; filename="database.php"');
  327. echo $config;
  328. exit(0);
  329. }
  330.  
  331.  
  332. /**
  333.   * Generate and download a dev hosts config file
  334.   */
  335. public static function dbConfHosts()
  336. {
  337. $config = self::genDevHostsConfig();
  338.  
  339. header('Content-type: application/php');
  340. header('Content-disposition: attachment; filename="dev_hosts.php"');
  341. echo $config;
  342. exit(0);
  343. }
  344.  
  345.  
  346. /**
  347.   * Generate a database config from given parameters
  348.   *
  349.   * @param array $data Config params; 'production', 'host', 'user', 'pass', 'database'
  350.   * @return string
  351.   */
  352. private static function genDbConfig(array $data)
  353. {
  354. $db_config = file_get_contents(__DIR__ . '/../config_tmpl/database.php');
  355.  
  356. if ($data['production'] == 'live') {
  357. $db_config = str_replace('{{PROD-HOST}}', $data['host'], $db_config);
  358. $db_config = str_replace('{{PROD-USER}}', $data['user'], $db_config);
  359. $db_config = str_replace('{{PROD-DATABASE}}', $data['database'], $db_config);
  360. $db_config = str_replace('{{TEST-USER}}', '-- username --', $db_config);
  361. $db_config = str_replace('{{TEST-PASS}}', '-- password --', $db_config);
  362. $db_config = str_replace('{{TEST-DATABASE}}', '-- database --', $db_config);
  363. $db_config = str_replace('{{TEST-HOST}}', 'localhost', $db_config);
  364. } else {
  365. $db_config = str_replace('{{TEST-HOST}}', $data['host'], $db_config);
  366. $db_config = str_replace('{{TEST-USER}}', $data['user'], $db_config);
  367. $db_config = str_replace('{{TEST-PASS}}', $data['pass'], $db_config);
  368. $db_config = str_replace('{{TEST-DATABASE}}', $data['database'], $db_config);
  369. $db_config = str_replace('{{PROD-USER}}', '-- username --', $db_config);
  370. $db_config = str_replace('{{PROD-DATABASE}}', '-- database --', $db_config);
  371. $db_config = str_replace('{{PROD-HOST}}', 'localhost', $db_config);
  372. }
  373.  
  374. $db_config = str_replace('{{SERVER-KEY}}', Security::randStr(16), $db_config);
  375.  
  376. return $db_config;
  377. }
  378.  
  379.  
  380. /**
  381.   * Generate a dev hosts config, which contains the existing config and the current hostname
  382.   *
  383.   * @return string
  384.   */
  385. private static function genDevHostsConfig()
  386. {
  387. if (file_exists(DOCROOT . 'config/dev_hosts.php')) {
  388. require DOCROOT . 'config/dev_hosts.php';
  389. if (@is_array($dev_hosts)) {
  390. $dev_hosts = array_filter($dev_hosts);
  391. }
  392. }
  393. if (empty($dev_hosts)) {
  394. $dev_hosts = [];
  395. }
  396. $dev_hosts[] = php_uname('n');
  397. $dev_hosts = array_unique($dev_hosts);
  398.  
  399. $lines = [
  400. '<?php',
  401. '$dev_hosts = ['
  402. ];
  403. foreach ($dev_hosts as $host) {
  404. $lines[] = " '" . addslashes($host) . "',";
  405. }
  406. $lines[] = '];';
  407.  
  408. return implode("\n", $lines);
  409. }
  410.  
  411.  
  412. /**
  413.   * Generate and download a password config file
  414.   */
  415. public static function dbConfPassword()
  416. {
  417. $config = self::genPassConfig($_SESSION['database_config']);
  418.  
  419. header('Content-type: application/php');
  420. header('Content-disposition: attachment; filename="database.config.php"');
  421. echo $config;
  422. exit(0);
  423. }
  424.  
  425.  
  426. /**
  427.   * Generate a database password file from given parameters
  428.   *
  429.   * @param array $data Config params; 'pass'
  430.   * @return string
  431.   */
  432. private static function genPassConfig(array $data)
  433. {
  434. $pass_config = file_get_contents(__DIR__ . '/../config_tmpl/prod_password.php');
  435. $pass_config = str_replace('{{PROD-PASS}}', $data['pass'], $pass_config);
  436. return $pass_config;
  437. }
  438.  
  439.  
  440. /**
  441.   * Run a database sync
  442.   */
  443. public function sync()
  444. {
  445. $sync = new DatabaseSync(true);
  446. $sync->loadStandardXmlFiles();
  447. $sync->sanityCheck();
  448.  
  449. if ($sync->hasLoadErrors()) {
  450. $out = $sync->getLoadErrorsHtml();
  451. die('Sync failed sanity check: ' . $out);
  452. }
  453.  
  454. try {
  455. $log = $sync->updateDatabase();
  456. } catch (Exception $ex) {
  457. Notification::error('Please configure Database - Step 1 of checklist.');
  458. Url::redirect('welcome/checklist');
  459. }
  460.  
  461. if (empty($log)) {
  462. $log = '<p>Everything is up to date</p>';
  463. }
  464.  
  465. $view = new View('modules/Welcome/sync');
  466. $view->log = $log;
  467.  
  468. $skin = new View('sprout/admin/login_layout');
  469. $skin->browser_title = 'Database sync';
  470. $skin->main_title = 'Database sync';
  471. $skin->main_content = $view->render();
  472. echo $skin->render();
  473. }
  474.  
  475.  
  476. /**
  477.   * Show a UI to create a super-operator
  478.   */
  479. public function superOperatorForm()
  480. {
  481. Form::loadFromSession('super_op');
  482.  
  483. $view = new View('modules/Welcome/super_op_form');
  484.  
  485. $skin = new View('sprout/admin/login_layout');
  486. $skin->browser_title = 'Super operator';
  487. $skin->main_title = 'Super operator';
  488. $skin->main_content = $view->render();
  489. echo $skin->render();
  490. }
  491.  
  492.  
  493. /**
  494.   * Generate and download super operator config file
  495.   *
  496.   * @return void Echos directly
  497.   */
  498. public function superOperatorConf()
  499. {
  500. $users = AdminAuth::injectLocalSuperConf($_SESSION['supeop_config']['user'], $_SESSION['supeop_config']['hash'], $_SESSION['supeop_config']['salt']);
  501. $config = '';
  502.  
  503. $config .= "<?php\n\$config['operators'] = [\n";
  504. foreach ($users as $username => $user) {
  505. $config .= " '" . Enc::html(Enc::js($username));
  506. $config .= "' => ['uid' => {$user['uid']}, " . "'hash' => '" . Enc::html(Enc::js($user['hash']));
  507. $config .= "', 'salt' => '" . Enc::html(Enc::js($user['salt'])) . "'],\n";
  508. $config .= "];\n";
  509. }
  510.  
  511. header('Content-type: application/php');
  512. header('Content-disposition: attachment; filename="super_ops.php"');
  513. echo $config;
  514. exit(0);
  515. }
  516.  
  517.  
  518. /**
  519.   * Ensure password has enough complexity
  520.   */
  521. private static function passwordComplexity($str)
  522. {
  523. // Longer than this won't be brute forced any time soon.
  524. if (strlen($str) >= 16) {
  525. return true;
  526. }
  527.  
  528. $errs = [];
  529. if (!preg_match('/[0-9]/', $str)) {
  530. $errs[] = 'Must contain a number character';
  531. }
  532. if (!preg_match('/[A-Z]/', $str)) {
  533. $errs[] = 'Must contain an uppercase character';
  534. }
  535. if (!preg_match('/[a-z]/', $str)) {
  536. $errs[] = 'Must contain a lowercase character';
  537. }
  538.  
  539. if (count($errs) == 0) return true;
  540. return $errs;
  541. }
  542.  
  543.  
  544. /**
  545.   * Create a super operator
  546.   *
  547.   * @return void Redirects
  548.   */
  549. public function superOperatorAction()
  550. {
  551. $_SESSION['super_op']['field_values'] = Validator::trim($_POST);
  552.  
  553. $valid = new Validator($_POST);
  554. $valid->required(['username', 'password1', 'password2']);
  555. $valid->check('username', 'Validity::length', 0, 50);
  556.  
  557. try {
  558. $valid->check('username', 'Validity::uniqueValue', 'operators', 'username', 0, 'An operator already exists with that username');
  559. } catch (Exception $ex) {
  560. Notification::error('Please configure Database - Step 1 of checklist. It\'s required for validation!');
  561. Url::redirect('welcome/super_op_form');
  562. }
  563.  
  564. $valid->check('username', 'Validity::regex', '/^[a-zA-Z0-9]+$/');
  565. $valid->check('password1', 'Validity::length', 8, 60);
  566. $valid->check('password2', 'Validity::length', 8, 60);
  567. $valid->multipleCheck(['password1', 'password2'], 'Validity::allMatch');
  568.  
  569. if (!empty($_POST['password1']) and $_POST['password1'] === $_POST['password2']) {
  570. $complexity = self::passwordComplexity($_POST['password1']);
  571. if ($complexity !== true) {
  572. $valid->addFieldError('password1', 'Not complex enough');
  573. $valid->addFieldError('password2', 'Not complex enough');
  574.  
  575. Notification::error('Password does not meet complexity requirements:');
  576. foreach ($complexity as $c) {
  577. Notification::error(" \xC2\xA0 \xC2\xA0 " . $c);
  578. }
  579. }
  580. }
  581.  
  582. if ($valid->hasErrors()) {
  583. $_SESSION['super_op']['field_errors'] = $valid->getFieldErrors();
  584. Url::redirect('welcome/super_op_form');
  585. } else {
  586. unset($_SESSION['super_op']['field_errors']);
  587. }
  588.  
  589. $hashed = Auth::hashPassword($_POST['password1'], Constants::PASSWORD_BCRYPT12);
  590.  
  591. $params = [
  592. 'user' => $_POST['username'],
  593. 'hash' => $hashed[0],
  594. 'salt' => $hashed[2],
  595. ];
  596. Url::redirect('welcome/super_op_result?' . http_build_query($params));
  597. }
  598.  
  599.  
  600. /**
  601.   * Show the generated super operator details
  602.   */
  603. public function superOperatorResult()
  604. {
  605. $users = AdminAuth::injectLocalSuperConf($_GET['user'], $_GET['hash'], $_GET['salt']);
  606.  
  607. $_SESSION['supeop_config'] = $_GET;
  608.  
  609. $view = new View('modules/Welcome/super_op_result');
  610. $view->superop_config_url = 'welcome/super_op_conf';
  611. $view->users = $users;
  612.  
  613. $skin = new View('sprout/admin/login_layout');
  614. $skin->browser_title = 'Super operator';
  615. $skin->main_title = 'Super operator';
  616. $skin->main_content = $view->render();
  617. echo $skin->render();
  618. }
  619.  
  620.  
  621. /**
  622.   * Add sample content
  623.   */
  624. public function addSampleAction()
  625. {
  626. // During development, uncomment this line:
  627. //$this->wipeTables();
  628.  
  629. try {
  630. $num_pages = Pdb::query("SELECT COUNT(*) FROM ~pages LIMIT 1", [], 'val');
  631. $num_files = Pdb::query("SELECT COUNT(*) FROM ~files LIMIT 1", [], 'val');
  632. } catch (Exception $ex) {
  633. Notification::error('Please configure Database - Step 1 of checklist.');
  634. Url::redirect('welcome/checklist');
  635. }
  636.  
  637.  
  638. if ($num_pages or $num_files) {
  639. Notification::error('This site already has content');
  640. Url::redirect('welcome/checklist');
  641. }
  642.  
  643. $this->addSampleFiles();
  644. $this->addSamplePages();
  645. $this->addSampleHomePage();
  646.  
  647. Notification::confirm('Sample content has been added');
  648. Url::redirect('welcome/checklist');
  649. }
  650.  
  651.  
  652. /**
  653.   * Wipe the tables used by the sample code system (dev only code)
  654.   */
  655. private function wipeTables()
  656. {
  657. Pdb::query("DELETE FROM ~page_widgets", [], 'null');
  658. Pdb::query("DELETE FROM ~page_revisions", [], 'null');
  659. Pdb::query("DELETE FROM ~pages", [], 'null');
  660. Pdb::query("DELETE FROM ~homepage_banners", [], 'null');
  661. Pdb::query("DELETE FROM ~homepage_promos", [], 'null');
  662. Pdb::query("DELETE FROM ~files", [], 'null');
  663. Pdb::query("DELETE FROM ~files_cat_join", [], 'null');
  664. Pdb::query("DELETE FROM ~files_cat_list", [], 'null');
  665. }
  666.  
  667.  
  668. /**
  669.   * Add sample files from sample_content/files.xml
  670.   */
  671. private function addSampleFiles()
  672. {
  673. $xml = file_get_contents(DOCROOT . 'modules/Welcome/sample_content/files.xml');
  674. $xml = simplexml_load_string($xml);
  675.  
  676. $data = [];
  677. $data['name'] = 'Sample files';
  678. $data['date_added'] = Pdb::now();
  679. $data['date_modified'] = Pdb::now();
  680. $cat_id = Pdb::insert('files_cat_list', $data);
  681.  
  682. $file_id = 0;
  683. foreach ($xml->file as $elem) {
  684. $name = (string)$elem['name'];
  685. $filename = (string)$elem['filename'];
  686. $file_id += 1;
  687.  
  688. $orig = DOCROOT . 'modules/Welcome/sample_content/' . $filename;
  689.  
  690. $data = [];
  691. $data['id'] = $file_id;
  692. $data['name'] = $name;
  693. $data['filename'] = "{$file_id}_{$filename}";
  694. $data['type'] = FileConstants::TYPE_IMAGE;
  695. $data['date_added'] = Pdb::now();
  696. $data['date_modified'] = Pdb::now();
  697. $data['date_file_modified'] = Pdb::now();
  698. $data['sha1'] = sha1_file($orig);
  699. Pdb::insert('files', $data);
  700.  
  701. $data = [];
  702. $data['file_id'] = $file_id;
  703. $data['cat_id'] = $cat_id;
  704. Pdb::insert('files_cat_join', $data);
  705.  
  706. File::putExisting("{$file_id}_{$filename}", $orig);
  707.  
  708. File::postUploadProcessing("{$file_id}_{$filename}", $file_id, FileConstants::TYPE_IMAGE);
  709. }
  710. }
  711.  
  712.  
  713. /**
  714.   * Add sample files from sample_content/pages.xml
  715.   */
  716. private function addSamplePages()
  717. {
  718. $xml = file_get_contents(DOCROOT . 'modules/Welcome/sample_content/pages.xml');
  719. $xml = simplexml_load_string($xml);
  720.  
  721. $page_id = 0;
  722. $parent_lookup = [];
  723. foreach ($xml->page as $elem) {
  724. $name = (string)$elem['name'];
  725. $template = (string)$elem['template'];
  726. $content = (string)$elem;
  727. $page_id += 1;
  728.  
  729. if (isset($elem['parent'])) {
  730. $parent_id = $parent_lookup[(string)$elem['parent']];
  731. } else {
  732. $parent_id = 0;
  733. }
  734.  
  735. $data = [];
  736. $data['id'] = $page_id;
  737. $data['parent_id'] = $parent_id;
  738. $data['subsite_id'] = 1;
  739. $data['name'] = $name;
  740. $data['slug'] = Enc::urlname($name);
  741. $data['active'] = 1;
  742. $data['show_in_nav'] = 1;
  743. $data['alt_template'] = ($template ?: 'skin/inner');
  744. $data['date_added'] = Pdb::now();
  745. $data['date_modified'] = Pdb::now();
  746. Pdb::insert('pages', $data);
  747. $parent_lookup[$name] = $page_id;
  748.  
  749. $data = [];
  750. $data['page_id'] = $page_id;
  751. $data['type'] = 'standard';
  752. $data['status'] = 'live';
  753. $data['modified_editor'] = 'Sample pages tool';
  754. $data['changes_made'] = 'Added sample page';
  755. $data['date_added'] = Pdb::now();
  756. $data['date_modified'] = Pdb::now();
  757. $revision_id = Pdb::insert('page_revisions', $data);
  758.  
  759. $data = [];
  760. $data['page_revision_id'] = $revision_id;
  761. $data['area_id'] = 1;
  762. $data['active'] = 1;
  763. $data['type'] = 'RichText';
  764. $data['settings'] = json_encode(['text' => $content]);
  765. $data['record_order'] = 1;
  766. Pdb::insert('page_widgets', $data);
  767. }
  768. }
  769.  
  770.  
  771. /**
  772.   * Updates to home page - hardcoded rather than an xml file
  773.   */
  774. private function addSampleHomePage()
  775. {
  776. $data = [];
  777. $data['text'] = '<p>There\'s a voice that keeps on calling me. Down the road, that\'s where I\'ll always be.</p>'
  778. . '<p>This being said, the ownership issues inherent in dominant thematic implementations cannot be understated</p>';
  779. Pdb::update('homepages', $data, ['id' => 1]);
  780.  
  781. $data = [];
  782. $data['homepage_id'] = 1;
  783. $data['active'] = 1;
  784. $data['file_id'] = 1;
  785. $data['heading'] = 'SproutCMS';
  786. $data['description'] = 'It\'s a brand new website';
  787. $data['link'] = json_encode(['class' => '\Sprout\Helpers\LinkSpecPage', 'data' => '3']);
  788. $data['link_label'] = 'Our services';
  789. Pdb::insert('homepage_banners', $data);
  790.  
  791. $data = [];
  792. $data['homepage_id'] = 1;
  793. $data['record_order'] = 1;
  794. $data['active'] = 1;
  795. $data['file_id'] = 2;
  796. $data['heading'] = 'Promo one';
  797. $data['description'] = 'Cat ipsum dolor sit amet';
  798. $data['link'] = json_encode(['class' => '\Sprout\Helpers\LinkSpecPage', 'data' => '4']);
  799. Pdb::insert('homepage_promos', $data);
  800.  
  801. $data = [];
  802. $data['homepage_id'] = 1;
  803. $data['record_order'] = 2;
  804. $data['active'] = 1;
  805. $data['file_id'] = 3;
  806. $data['heading'] = 'Promo two';
  807. $data['description'] = 'Lorem ipsum dolor sit amet';
  808. $data['link'] = json_encode(['class' => '\Sprout\Helpers\LinkSpecPage', 'data' => '9']);
  809. $data['link_label'] = 'Buy now';
  810. Pdb::insert('homepage_promos', $data);
  811.  
  812. $data = [];
  813. $data['homepage_id'] = 1;
  814. $data['record_order'] = 3;
  815. $data['active'] = 1;
  816. $data['file_id'] = 4;
  817. $data['heading'] = 'Promo three';
  818. $data['description'] = 'A nice warm laptop for me to sit on';
  819. $data['link'] = json_encode(['class' => '\Sprout\Helpers\LinkSpecPage', 'data' => '10']);
  820. Pdb::insert('homepage_promos', $data);
  821. }
  822.  
  823. }
  824.