path_config = PATH_CORE . 'config/'; $this->path_languages = PATH_CORE . 'content/languages/'; $this->path_plugins = PATH_CORE . 'plugins/'; $this->path_xmlforms = PATH_CORE . 'xmlform/'; $this->path_public = PATH_HOME . 'public_html/index.html'; $this->path_shared = PATH_TRUNK . 'shared/'; $this->path_sep = PATH_SEP; $this->systemName = ''; $this->path_translations = PATH_CORE . 'js/labels/'; $this->path_translationsMafe = PATH_HOME . 'public_html/translations/'; } public function index($httpData) { if (file_exists(FILE_PATHS_INSTALLED)) { $this->setJSVar('messageError', G::LoadTranslation('ID_PROCESSMAKER_ALREADY_INSTALLED')); $this->includeExtJS('installer/stopInstall'); $this->setView('installer/mainStopInstall'); G::RenderPage('publish', 'extJs'); return; } if ((strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') && (file_exists($this->path_shared . 'partner.info'))) { $this->setJSVar('messageError', G::LoadTranslation('ID_NO_INSTALL')); $this->includeExtJS('installer/stopInstall'); $this->setView('installer/mainStopInstall'); G::RenderPage('publish', 'extJs'); return; } $licenseContent = file_get_contents(PATH_TRUNK . 'LICENSE.txt'); $this->includeExtJS('installer/CardLayout', false); $this->includeExtJS('installer/Wizard', false); $this->includeExtJS('installer/Header', false); $this->includeExtJS('installer/Card', false); $this->includeExtJS('installer/installer_cards'); $this->includeExtJS('installer/main', false); $this->setView('installer/main'); G::RenderPage('publish', 'extJs'); } /** * Set config connection * * @param string $nameConnection name Connection * @param string $host * @param string $user * @param string $pass * @param string $database * @param int $port * @param array $options * * @throws Exception */ public static function setNewConnection($nameConnection, $host, $user, $pass, $database, $port, $options = []) { try { if (empty($port)) { $dbHost = explode(':', $host); $port = 3306; if (count($dbHost) > 1) { $port = $dbHost[1]; } $host = $dbHost[0]; } config(['database.connections.' . $nameConnection => [ 'driver' => 'mysql', 'host' => $host, 'port' => $port, 'database' => $database, 'username' => $user, 'password' => $pass, 'unix_socket' => '', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_0900_ai_ci', 'prefix' => '', 'strict' => false, 'engine' => 'InnoDB', 'options' => $options ]]); DB::connection($nameConnection)->getPdo(); } catch (Exception $e) { throw new Exception(G::LoadTranslation('ID_MYSQL_CREDENTIALS_WRONG')); } } /** * Get system information for review the requirements to install ProcessMaker * * @return object */ public function getSystemInfo() { $this->setResponseType('json'); // PHP info and verification $phpVer = phpversion(); preg_match('/[0-9\.]+/', $phpVer, $match); $phpVerNum = (float)$match[0]; $info = new stdclass(); $info->php = new stdclass(); $info->mysql = new stdclass(); $info->openssl = new stdclass(); $info->curl = new stdclass(); $info->dom = new stdclass(); $info->gd = new stdclass(); $info->multibyte = new stdclass(); $info->soap = new stdclass(); $info->ldap = new stdclass(); $info->memory = new stdclass(); $info->php->version = $phpVer; $info->php->result = ( version_compare(phpversion(), self::PHP_VERSION_MINIMUM_SUPPORTED, '>=') && version_compare(phpversion(), self::PHP_VERSION_NOT_SUPPORTED, '<')) ? true : false; // MYSQL info and verification $info->mysql->result = false; if (function_exists('mysqli_query')) { $mysqlVer = mysqli_get_client_info(); preg_match('/[0-9\.]+/', $mysqlVer, $match); $mysqlNum = (float)$match[0]; $info->mysql->version = 'Client API version ' . $mysqlVer; $info->mysql->result = $mysqlNum >= 5.0; } // OpenSSL info $info->openssl->result = false; $info->openssl->version = G::LoadTranslation('ID_NOT_ENABLED'); if (function_exists('openssl_open')) { $info->openssl->result = true; $info->openssl->version = G::LoadTranslation('ID_ENABLED'); } // Curl info $info->curl->result = false; $info->curl->version = G::LoadTranslation('ID_NOT_ENABLED'); if (function_exists('curl_version')) { $info->curl->result = true; $version = curl_version(); $info->curl->version = 'cURL ' . $version['version']; $info->openssl->version = $version['ssl_version']; } // DOMDocument info $info->dom->result = false; $info->dom->version = G::LoadTranslation('ID_NOT_ENABLED'); if (class_exists('DOMDocument')) { $info->dom->result = true; $info->dom->version = G::LoadTranslation('ID_ENABLED'); } // GD info $info->gd->result = false; $info->gd->version = G::LoadTranslation('ID_NOT_ENABLED'); if (function_exists('gd_info')) { $info->gd->result = true; $gdinfo = gd_info(); $info->gd->version = $gdinfo['GD Version']; } // Multibyte info $info->multibyte->result = false; $info->multibyte->version = G::LoadTranslation('ID_NOT_ENABLED'); if (function_exists('mb_check_encoding')) { $info->multibyte->result = true; $info->multibyte->version = G::LoadTranslation('ID_ENABLED'); } // soap info $info->soap->result = false; $info->soap->version = G::LoadTranslation('ID_NOT_ENABLED'); if (class_exists('SoapClient')) { $info->soap->result = true; $info->soap->version = G::LoadTranslation('ID_ENABLED'); } // ldap info $info->ldap->result = false; $info->ldap->version = G::LoadTranslation('ID_NOT_ENABLED'); if (function_exists('ldap_connect')) { $info->ldap->result = true; $info->ldap->version = G::LoadTranslation('ID_ENABLED'); } // memory limit verification $memory = (int)ini_get('memory_limit'); $info->memory->version = changeAbbreviationOfDirectives(ini_get('memory_limit')); $info->memory->result = $memory > 255; return $info; } public function is_dir_writable($path) { return G::is_writable_r($path); } /** * Test db connection * * @return StdClass */ public function testConnection() { $this->setResponseType('json'); $info = new StdClass(); try { $info = $this->testMySQLConnection(); } catch (Exception $e) { $info->result = false; $info->message = G::LoadTranslation('DBCONNECTIONS_MSGA'); } return $info; } /** * log the queries and other information to install.log, * the install.log files should be placed in shared/logs * for that reason we are using the $_REQUEST of pathShared */ private function installLog($text) { //if this function is called outside the createWorkspace, just returns and do nothing if (!isset($_REQUEST['pathShared'])) { return; } //log file is in shared/logs $pathShared = trim($_REQUEST['pathShared']); if (substr($pathShared, -1) !== '/') { $pathShared .= '/'; } $pathSharedLog = $pathShared . 'logs/'; G::verifyPath($pathSharedLog, true); $logFile = $pathSharedLog . 'install.log'; if (!is_file($logFile)) { G::mk_dir(dirname($pathShared)); $fpt = fopen($logFile, 'w'); if ($fpt !== null) { fwrite($fpt, sprintf("%s %s\n", date('Y:m:d H:i:s'), '----- ' . G::LoadTranslation('ID_STARTING_LOG_FILE') . ' ------')); fclose($fpt); } else { throw new Exception(G::LoadTranslation('ID_FILE_NOT_WRITEABLE', SYS_LANG, [$logFile])); return $false; } } $filter = new InputFilter(); $logFile = $filter->validateInput($logFile, 'path'); $fpt = fopen($logFile, 'a'); fwrite($fpt, sprintf("%s %s\n", date('Y:m:d H:i:s'), trim($text))); fclose($fpt); return true; } /** * Display an error when processMaker is already installed * * @return void */ private function displayError() { $this->setJSVar('messageError', G::LoadTranslation('ID_PROCESSMAKER_ALREADY_INSTALLED')); $this->includeExtJS('installer/stopInstall'); $this->setView('installer/mainStopInstall'); G::RenderPage('publish', 'extJs'); } public function forceTogenerateTranslationsFiles($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, G::browserCacheFilesUrl(System::getServerProtocolHost() . "/js/ext/translation.en.js?r=" . rand(1, 10000))); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); curl_exec($ch); curl_close($ch); } /** * query_sql_file send many statements to server * * @param string $file * @param string $connection * @return array $report */ public function mysqlFileQuery($file) { if (!is_file($file)) { throw new Exception(G::LoadTranslation('ID_SQL_FILE_INVALID', SYS_LANG, [$file])); return $false; } $this->installLog(G::LoadTranslation('ID_PROCESING', SYS_LANG, [$file])); $startTime = microtime(true); //New Update, to support more complex queries $lines = file($file); $previous = null; DB::connection(self::CONNECTION_INSTALL) ->statement("SET NAMES 'utf8'"); foreach ($lines as $j => $line) { $line = trim($line); // Remove comments from the script if (strpos($line, '--') === 0) { $line = substr($line, 0, strpos($line, '--')); } if (empty($line)) { continue; } if (strpos($line, '#') === 0) { $line = substr($line, 0, strpos($line, '#')); } if (empty($line)) { continue; } // Concatenate the previous line, if any, with the current if ($previous) { $line = $previous . ' ' . $line; } $previous = null; // If the current line doesnt end with ; then put this line together // with the next one, thus supporting multi-line statements. if (strrpos($line, ';') !== strlen($line) - 1) { $previous = $line; continue; } $line = substr($line, 0, strrpos($line, ';')); DB::connection(self::CONNECTION_INSTALL) ->statement($line); } $endTime = microtime(true); $this->installLog(G::LoadTranslation('ID_FILE_PROCESSED', SYS_LANG, [basename($file), $endTime - $startTime])); return true; } /** * Privates functions section, non callable by http request */ private function testMySQLConnection() { try { $filter = new InputFilter(); $info = new StdClass(); $info->result = false; $info->message = ''; if (!function_exists('mysqli_connect')) { $info->message = G::LoadTranslation('ID_PHP_MYSQLI_NOT_INSTALL'); return $info; } $dataRequest = $_REQUEST; $db_hostname = $filter->validateInput($dataRequest['db_hostname']); $db_port = $filter->validateInput($dataRequest['db_port']); $db_username = $filter->validateInput($dataRequest['db_username']); $db_password = urlencode($dataRequest['db_password']); $db_password = urldecode($filter->validateInput($db_password)); $fp = @fsockopen($db_hostname, $db_port, $errno, $errstr, 30); if (!$fp) { $info->message .= G::LoadTranslation('ID_CONNECTION_ERROR', SYS_LANG, ["$errstr ($errno)"]); return $info; } $db_username = $filter->validateInput($db_username, 'nosql'); $db_hostname = $filter->validateInput($db_hostname, 'nosql'); self::setNewConnection(self::CONNECTION_TEST_INSTALL, $db_hostname, $db_username, $db_password, '', $db_port); $query = "SELECT * FROM `information_schema`.`USER_PRIVILEGES` where (GRANTEE = \"'$db_username'@'$db_hostname'\" OR GRANTEE = \"'$db_username'@'%%'\") "; $response = DB::connection(self::CONNECTION_TEST_INSTALL)->select($query); if (!is_array($response)) { $info->message .= G::LoadTranslation('ID_CONNECTION_ERROR_PRIVILEGE', SYS_LANG, [$db_username]); return $info; } $info->message .= G::LoadTranslation('ID_MYSQL_SUCCESS_CONNECT'); $info->result = true; } catch (Exception $e) { $info->result = false; $info->message = G::LoadTranslation('ID_MYSQL_CREDENTIALS_WRONG'); } return $info; } /** * Verify/create framework shared directory structure * */ private function verifySharedFrameworkPaths($sharedPath) { // Check if $sharedPath ends with a slash and append if necessary if (substr($sharedPath, -1) !== DIRECTORY_SEPARATOR) { $sharedPath .= DIRECTORY_SEPARATOR; } $paths = [ $sharedPath . 'fonts' => 0770, $sharedPath . 'framework' => 0770, $sharedPath . 'framework' . DIRECTORY_SEPARATOR . 'cache' => 0770, ]; foreach ($paths as $path => $permission) { if (!file_exists($path)) { G::mk_dir($path, $permission); } if (!file_exists($path)) { return false; } } return true; } }