332 lines
13 KiB
PHP
Executable File
332 lines
13 KiB
PHP
Executable File
<?php
|
|
|
|
defined('BASEPATH') OR exit('No direct script access allowed');
|
|
/**
|
|
* Pancake
|
|
* A simple, fast, self-hosted invoicing application
|
|
*
|
|
* @package Pancake
|
|
* @author Pancake Dev Team
|
|
* @copyright Copyright (c) 2014, Pancake Payments
|
|
* @license http://pancakeapp.com/license
|
|
* @link http://pancakeapp.com
|
|
* @since Version 1.0
|
|
*/
|
|
// ------------------------------------------------------------------------
|
|
|
|
/**
|
|
* The install wizard controller
|
|
*
|
|
* @subpackage Controllers
|
|
* @category Wizard
|
|
* @property Installer $installer
|
|
*/
|
|
class Wizard extends CI_Controller {
|
|
|
|
/**
|
|
* @var string The path to the config folder
|
|
*/
|
|
private $config_path;
|
|
|
|
/**
|
|
* @var string The path to the config.php file
|
|
*/
|
|
private $config_file;
|
|
|
|
/**
|
|
* @var string The path to the stripe.php config file
|
|
*/
|
|
private $stripe_config_file;
|
|
|
|
/**
|
|
* @var string The path to the uploads folder
|
|
*/
|
|
private $upload_path;
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
public function __construct() {
|
|
parent::__construct();
|
|
|
|
# Disable all caching for Varnish.
|
|
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
|
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
|
header("Cache-Control: private");
|
|
header("Pragma: no-cache");
|
|
|
|
$this->config_path = FCPATH . 'system/pancake/config';
|
|
$this->config_file = $this->config_path . "/config.php";
|
|
$this->stripe_config_file = $this->config_path . "/stripe.php";
|
|
$this->upload_path = FCPATH . 'uploads/';
|
|
require_once FCPATH . 'system/pancake/helpers/pancake_helper.php';
|
|
include_once FCPATH . 'system/pancake/libraries/Asset.php';
|
|
Asset::add_path(APPPATH . 'assets/');
|
|
Asset::set_asset_url(BASE_URL);
|
|
}
|
|
|
|
public function _detect_url_rewriting() {
|
|
include_once APPPATH . 'libraries/HTTP_Request.php';
|
|
$http = new HTTP_Request();
|
|
try {
|
|
$url_without_index_php = BASE_URL . "admin";
|
|
$contents = $http->request($url_without_index_php);
|
|
if (stristr($contents, "run the installer") === false) {
|
|
$contents = $http->request(BASE_URL . "index.php/admin");
|
|
if (stristr($contents, "run the installer") === false) {
|
|
$contents = $http->request(BASE_URL . "index.php?/admin");
|
|
if (stristr($contents, "run the installer") === false) {
|
|
# Could not detect any valid way to access Pancake, so assume it works if there's a .htaccess and it's Apache, otherwise default to "index.php".
|
|
|
|
$htaccess_servers = array(
|
|
"Apache",
|
|
"LiteSpeed",
|
|
"WebServerX",
|
|
"1984",
|
|
);
|
|
|
|
$use_index_php = "index.php";
|
|
foreach ($htaccess_servers as $server) {
|
|
if (strpos($_SERVER["SERVER_SOFTWARE"], $server) !== false) {
|
|
$use_index_php = is_file(FCPATH . '.htaccess') ? '' : 'index.php';
|
|
}
|
|
}
|
|
} else {
|
|
# Found "run the installer", works with index.php?.
|
|
$use_index_php = "index.php?";
|
|
}
|
|
|
|
} else {
|
|
# Found "run the installer", works with index.php.
|
|
$use_index_php = "index.php";
|
|
}
|
|
} else {
|
|
# Found "run the installer", works without index.php.
|
|
$use_index_php = "";
|
|
}
|
|
} catch (Exception $e) {
|
|
# Could not detect URL Rewriting correctly; defaulting to "index.php?".
|
|
$use_index_php = "index.php?";
|
|
}
|
|
|
|
if ($use_index_php !== $this->config->item("index_page")) {
|
|
if (is_really_writable($this->config_file)) {
|
|
file_put_contents($this->config_file, str_replace("\$config['index_page'] = \$config['index_page'];", "\$config['index_page'] = '$use_index_php'; #CORRECTED", file_get_contents($this->config_file)));
|
|
if (strstr(file_get_contents($this->config_file), "#CORRECTED") !== false) {
|
|
# Everything is OK; the file was corrected.
|
|
return true;
|
|
} else {
|
|
# Something went wrong while updating the file.
|
|
return false;
|
|
}
|
|
} else {
|
|
# The file can't be corrected.
|
|
return false;
|
|
}
|
|
} else {
|
|
# Everything is OK; detection was correct.
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public function _detect_tls12() {
|
|
\Stripe\Stripe::setApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
|
|
\Stripe\Stripe::$apiBase = "https://api-tls12.stripe.com";
|
|
$curl = new \Stripe\HttpClient\CurlClient([CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2]);
|
|
\Stripe\ApiRequestor::setHttpClient($curl);
|
|
|
|
try {
|
|
\Stripe\Charge::all();
|
|
return true;
|
|
} catch (\Stripe\Error\ApiConnection $e) {
|
|
# Try without the CURLOPT.
|
|
$curl = new \Stripe\HttpClient\CurlClient();
|
|
\Stripe\ApiRequestor::setHttpClient($curl);
|
|
try {
|
|
\Stripe\Charge::all();
|
|
|
|
# Fix stripe.php config file.
|
|
if (is_really_writable($this->stripe_config_file)) {
|
|
file_put_contents($this->stripe_config_file, str_replace("[CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2]", "[]", file_get_contents($this->stripe_config_file)));
|
|
if (strstr(file_get_contents($this->stripe_config_file), "\$config['stripe_curlopts'] = [];") !== false) {
|
|
# Everything is OK; the file was corrected.
|
|
return true;
|
|
} else {
|
|
# Something went wrong while updating the file.
|
|
return false;
|
|
}
|
|
} else {
|
|
# The file can't be corrected.
|
|
return false;
|
|
}
|
|
} catch (\Stripe\Error\ApiConnection $e) {
|
|
# Cannot work with or without the CURLOPT trickery.
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function index() {
|
|
if ($_POST) {
|
|
$this->load->library('form_validation');
|
|
$data = [];
|
|
|
|
$this->form_validation->set_rules('db_host', 'Database Host', 'required');
|
|
$this->form_validation->set_rules('db_user', 'Database Username', 'required');
|
|
$this->form_validation->set_rules('db_pass', 'Database Password', 'required');
|
|
$this->form_validation->set_rules('db_name', 'Database Name', 'required');
|
|
$this->form_validation->set_rules('db_port', 'Database Port', 'required');
|
|
$this->form_validation->set_rules('username', 'Username', 'required|xss_clean');
|
|
$this->form_validation->set_rules('password', 'Password', 'required|min_length[5]|matches[password_confirm]');
|
|
$this->form_validation->set_rules('password_confirm', 'Password Confirmation', 'required');
|
|
|
|
if ($this->form_validation->run()) {
|
|
$data['hostname'] = $this->input->post('db_host');
|
|
$data['database'] = $this->input->post('db_name');
|
|
$data['dbprefix'] = 'pancake_';
|
|
$data['username'] = $this->input->post('db_user');
|
|
$data['password'] = $this->input->post('db_pass');
|
|
$data['port'] = $this->input->post('db_port');
|
|
$data['port'] = (!$data['port']) ? '3306' : $data['port'];
|
|
$db = $this->_check_db($data["hostname"], $data["username"], $data["password"], $data["database"], $data["port"]);
|
|
|
|
if ($db["success"]) {
|
|
if ($db["is_installed"]) {
|
|
$this->_output_step("steps/stop");
|
|
return;
|
|
} else {
|
|
$this->load->library('installer');
|
|
if ($this->installer->install($data, $this->input->post("username"), $this->input->post("password"))) {
|
|
# Redirect to Pancake, showing successful install modal.
|
|
redirect("admin");
|
|
} else {
|
|
$data['error'] = "The installer could not store the database configurations. Make sure that system/pancake/config is writable.";
|
|
$this->_output_step('steps/single_step', $data);
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
$data['error'] = 'Database Error: ' . $db["error"];
|
|
$this->_output_step('steps/single_step', $data);
|
|
return;
|
|
}
|
|
} else {
|
|
$this->_output_step('steps/single_step', $data);
|
|
return;
|
|
}
|
|
} else {
|
|
$this->config->load("license");
|
|
$checks = $this->_run_checks();
|
|
if ($checks['can_continue']) {
|
|
$this->_output_step('steps/single_step');
|
|
} else {
|
|
$this->_output_step('steps/checks', $checks);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function error() {
|
|
$this->_output_step('error');
|
|
}
|
|
|
|
protected function _run_checks() {
|
|
$data = array();
|
|
$data['is_url_rewriting_working'] = $this->_detect_url_rewriting();
|
|
$data['config_writable'] = is_really_writable($this->config_path) ? true : false;
|
|
$data['upload_writable'] = is_really_writable($this->upload_path) ? true : false;
|
|
$data['license_valid'] = $this->_check_license($this->config->item("license_key"));
|
|
$data['curl_installed'] = function_exists('curl_init');
|
|
$data['tls12'] = $this->_detect_tls12();
|
|
|
|
$data['installed'] = array(
|
|
'gd' => (extension_loaded('gd') && function_exists('gd_info')),
|
|
'json' => (extension_loaded('json') && function_exists('json_encode')),
|
|
'dom' => (extension_loaded('dom')),
|
|
'xml' => (extension_loaded('xml')),
|
|
'mysql' => (extension_loaded('mysqli') || extension_loaded('mysql')),
|
|
);
|
|
|
|
include_once APPPATH . 'libraries/HTTP_Request.php';
|
|
$http = new HTTP_Request();
|
|
try {
|
|
$http->request(MANAGE_PANCAKE_BASE_URL);
|
|
$data['manage_pancakeapp'] = true;
|
|
} catch (Exception $e) {
|
|
$data['manage_pancakeapp'] = false;
|
|
}
|
|
|
|
$can_continue = true;
|
|
foreach ($data as $value) {
|
|
if (is_array($value)) {
|
|
foreach ($value as $subvalue) {
|
|
if (!$subvalue) {
|
|
$can_continue = false;
|
|
break 2;
|
|
}
|
|
}
|
|
} else {
|
|
if (!$value) {
|
|
$can_continue = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
$data['can_continue'] = $can_continue;
|
|
return $data;
|
|
}
|
|
|
|
protected function _check_db($host, $user, $pass, $name, $port, $prefix = "pancake_") {
|
|
$is_installed = false;
|
|
|
|
if (function_exists("mysqli_connect")) {
|
|
$mysqli = @new mysqli($host, $user, $pass, $name, $port);
|
|
$success = !$mysqli->connect_error;
|
|
$error = $mysqli->connect_error;
|
|
if ($success) {
|
|
$is_installed = $mysqli->query("show tables like '" . $mysqli->real_escape_string($prefix) . "%'")->num_rows > 0;
|
|
}
|
|
} else {
|
|
$link = @mysql_connect($host . ':' . $port, $user, $pass, true);
|
|
|
|
if ($link) {
|
|
// If the database is not there create it
|
|
mysql_query('CREATE DATABASE IF NOT EXISTS ' . $name, $link);
|
|
}
|
|
|
|
$success = ($link && @ mysql_select_db($name, $link));
|
|
$error = mysql_error();
|
|
|
|
if ($success) {
|
|
$result = mysql_query("show tables like '" . mysql_real_escape_string($prefix, $link) . "%'", $link);
|
|
$is_installed = mysql_num_rows($result) > 0;
|
|
}
|
|
}
|
|
|
|
return [
|
|
"success" => $success,
|
|
"error" => $error,
|
|
"is_installed" => $is_installed,
|
|
];
|
|
}
|
|
|
|
private function _check_license($key) {
|
|
$key = trim($key);
|
|
|
|
$result = get_url_contents(MANAGE_PANCAKE_BASE_URL . 'verify/key/' . $key, false);
|
|
if (empty($result)) {
|
|
show_error('Pancake could not verify if the key "' . $key . '" is valid.');
|
|
}
|
|
|
|
return ($result === 'valid');
|
|
}
|
|
|
|
private function _output_step($view, $data = array()) {
|
|
$content = $this->load->view($view, $data, true);
|
|
|
|
$this->load->view('template', array('content' => $content));
|
|
}
|
|
|
|
}
|
|
|
|
/* End of file wizard.php */ |