diff --git a/.htaccess b/.htaccess index 065d1c7d8b..39aec231fc 100755 --- a/.htaccess +++ b/.htaccess @@ -1,4 +1,4 @@ -DirectoryIndex index.php +DirectoryIndex index.php index.html RedirectMatch 403 \.config$ diff --git a/api/index.html b/api/index.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/data/.data b/data/.data old mode 100644 new mode 100755 diff --git a/install/core/Installer.php b/install/core/Installer.php index 9aadedf9fe..5deb395664 100644 --- a/install/core/Installer.php +++ b/install/core/Installer.php @@ -295,7 +295,6 @@ class Installer public function fixAjaxPermission($url = null) { $permission = array(0644, 0755); - $fileManager = $this->app->getContainer()->get('fileManager'); $result = false; @@ -310,7 +309,7 @@ class Installer $result = $fileManager->getPermissionUtils()->chmod($path, $permission, true); } } - + return $result; } diff --git a/install/core/SystemHelper.php b/install/core/SystemHelper.php index 95ca7f1819..81c7b11fe5 100644 --- a/install/core/SystemHelper.php +++ b/install/core/SystemHelper.php @@ -35,10 +35,21 @@ class SystemHelper protected $modRewriteUrl = '/api/v1/Metadata'; + protected $writableDir = 'data'; - public function __construct() + + public function initWritable() { + if (is_writable($this->writableDir)) { + return true; + } + return false; + } + + public function getWritableDir() + { + return $this->writableDir; } @@ -96,92 +107,6 @@ class SystemHelper return $result; } - public function checkModRewrite() - { - if ( function_exists('apache_get_modules') && in_array('mod_rewrite',apache_get_modules()) ) { - return true; - } elseif (isset($_SERVER['IIS_UrlRewriteModule'])) { - return true; - } elseif (getenv('ESPO_MR')=='On' ) { - return true; - } elseif (isset($_SERVER['ESPO_MR'])) { - return true; - } elseif ($this->checkModRewriteByUrl()) { - return true; - } - - return false; - } - - protected function checkModRewriteByUrl() - { - $url = $this->getBaseUrl().$this->modRewriteUrl; - - if (!$this->isCurl()) { - $httpCode = $this->getHttpCodeByCurl($url); - } - - $httpCode = $this->getHttpCodeByHeader($url); - - if ($httpCode != false && !empty($httpCode)) { - if ($httpCode == '200' || $httpCode == '401') { - return true; - } - } - - return false; - } - - public function getModRewriteUrl() - { - return $this->modRewriteUrl; - } - - protected function getHttpCodeByCurl($url) - { - $ch = curl_init($url); - - curl_setopt($ch, CURLOPT_NOSIGNAL, 1); - curl_setopt($ch, CURLOPT_TIMEOUT, 5); - - $response = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - curl_close($ch); - - if ($response != false && !empty($httpCode)) { - return $httpCode; - } - - return false; - } - - protected function getHttpCodeByHeader($url) - { - stream_context_set_default( - array( - 'http' => array( - 'timeout' => 3.0, - ) - ) - ); - $headers = get_headers($url); - - if ($headers != false) { - - preg_match('/HTTP.*([0-9]{3})/i', $headers[0], $match); - - return $httpCode = trim($match[1]); - } - - return false; - } - - protected function isCurl() - { - return function_exists('curl_version'); - } - public function getBaseUrl() { $pageUrl = ($_SERVER["HTTPS"] == 'on') ? 'https://' : 'http://'; @@ -197,6 +122,10 @@ class SystemHelper return $baseUrl; } + public function getModRewriteUrl() + { + return $this->modRewriteUrl; + } /** * Get web server name @@ -208,9 +137,123 @@ class SystemHelper $serverSoft = $_SERVER['SERVER_SOFTWARE']; preg_match('/^(.*)\//i', $serverSoft, $match); + if (empty($match[1])) { + preg_match('/^(.*)\/?/i', $serverSoft, $match); + } $serverName = strtolower( trim($match[1]) ); return $serverName; } + /** + * Get Operating System of web server. Details http://en.wikipedia.org/wiki/Uname + * + * @return string Ex. "windows", "mac", "linux" + */ + public function getOS() + { + $osList = array( + 'windows' => array( + 'win', + 'UWIN', + ), + 'mac' => array( + 'mac', + 'darwin', + ), + 'linux' => array( + 'linux', + 'cygwin', + 'GNU', + 'FreeBSD', + 'OpenBSD', + 'NetBSD', + ), + ); + + $sysOS = strtolower(PHP_OS); + + foreach ($osList as $osName => $osSystem) { + if (preg_match('/^('.implode('|', $osSystem).')/i', $sysOS)) { + return $osName; + } + } + + return false; + } + + + public function getRootDir() + { + $rootDir = dirname(__FILE__); + + $rootDir = preg_replace('/\/install\/core\/?/', '', $rootDir, 1); + + return $rootDir; + } + + public function getPhpBin() + { + return (defined("PHP_BINDIR"))? PHP_BINDIR.DIRECTORY_SEPARATOR.'php' : 'php'; + } + + public function getChmodCommand($path, $permissions = array('755'), $isFile = null) + { + $path = $this->getFullPath($path); + + if (is_string($permissions)) { + $permissions = (array) $permissions; + } + + if (!isset($isFile) && count($permissions) == 1) { + return 'chmod -R '.$permissions[0].' '.$path; + } + + $bufPerm = (count($permissions) == 1) ? array_fill(0, 2, $permissions[0]) : $permissions; + + $commands = array(); + $commands[] = 'chmod '.$bufPerm[0].' $(find '.$path.' -type f)'; + $commands[] = 'chmod '.$bufPerm[1].' $(find '.$path.' -type d)'; + + if (count($permissions) >= 2) { + return implode(' && ', $commands); + } + + return $isFile ? $commands[0] : $commands[1]; + } + + public function getChownCommand($path) + { + $owner = posix_getuid(); + $group = posix_getegid(); + + if (empty($owner) || empty($group)) { + return null; + } + + return 'chown -R '.$owner.':'.$group.' '.$this->getFullPath($path); + } + + public function getFullPath($path) + { + if (!empty($path)) { + $path = DIRECTORY_SEPARATOR . $path; + } + + return $this->getRootDir() . $path; + } + + public function getPermissionCommands($path, $permissions = array('644', '755'), $isFile = null) + { + $commands = array(); + $commands[] = $this->getChmodCommand($path, $permissions, $isFile); + + $chown = $this->getChownCommand($path); + if (isset($chown)) { + $commands[] = $chown; + } + + return implode(' && ', $commands); + } + } diff --git a/install/core/actions/finish.php b/install/core/actions/finish.php index 4c4d4f04af..90d89125e0 100644 --- a/install/core/actions/finish.php +++ b/install/core/actions/finish.php @@ -18,20 +18,15 @@ * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. - ************************************************************************/ - - + ************************************************************************/ $serverType = $systemHelper->getServerType(); -$serverType = 'microsoft-iis'; -$rootDir = dirname(__FILE__); -$rootDir = preg_replace('/\/install\/core\/actions\/?/', '', $rootDir, 1); -$cronFile = $rootDir.DIRECTORY_SEPARATOR.'cron.php'; -$phpBinDir = (defined("PHP_BINDIR"))? PHP_BINDIR.DIRECTORY_SEPARATOR.'php' : 'php'; + +$cronFile = $systemHelper->getRootDir().DIRECTORY_SEPARATOR.'cron.php'; $cronHelp = (isset($langs['cronHelp'][$serverType]))? $langs['cronHelp'][$serverType] : $langs['cronHelp']['default']; $cronHelp = str_replace('', $cronFile, $cronHelp); -$cronHelp = str_replace('', $phpBinDir, $cronHelp); +$cronHelp = str_replace('', $systemHelper->getPhpBin(), $cronHelp); $cronTitle = (isset($langs['cronTitle'][$serverType]))? $langs['cronTitle'][$serverType] : $langs['cronTitle']['default']; $smarty->assign('cronTitle', $cronTitle); diff --git a/install/core/actions/fixAjaxPermission.php b/install/core/actions/fixAjaxPermission.php index 6d69856507..d300bf1179 100644 --- a/install/core/actions/fixAjaxPermission.php +++ b/install/core/actions/fixAjaxPermission.php @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. - ************************************************************************/ + ************************************************************************/ ob_start(); $result = array('success' => false, 'errors' => array()); @@ -30,8 +30,9 @@ if (!empty($_REQUEST['url'])) { else { $result['success'] = false; $result['errorMsg'] = $_REQUEST['url']; + $result['errorFixInstruction'] = $systemHelper->getPermissionCommands($_REQUEST['url'], array('644', '755')); } } ob_clean(); -echo json_encode($result); \ No newline at end of file +echo json_encode($result); diff --git a/install/core/actions/settingsTest.php b/install/core/actions/settingsTest.php index bb4c1fdfc0..4ca9682b33 100644 --- a/install/core/actions/settingsTest.php +++ b/install/core/actions/settingsTest.php @@ -30,17 +30,6 @@ if (!empty($res['errors'])) { $result['errors'] = array_merge($result['errors'], $res['errors']); } -/*if (!$systemHelper->checkModRewrite()) { - $result['success'] = false; - $result['errors']['modRewrite'] = $langs['modRewriteHelp']['default']; - - $serverType = $systemHelper->getServerType(); - if (isset($langs['modRewriteHelp'][$serverType])) { - $result['errors']['modRewrite'] = $langs['modRewriteHelp'][$serverType]; - } -}*/ - - if (!empty($_REQUEST['dbName']) && !empty($_REQUEST['hostName']) && !empty($_REQUEST['dbUserName'])) { $connect = false; diff --git a/install/core/i18n/en_US.php b/install/core/i18n/en_US.php index 50b550acf8..a9f4c77f16 100644 --- a/install/core/i18n/en_US.php +++ b/install/core/i18n/en_US.php @@ -23,6 +23,7 @@ return array( 'Main page title' => 'Welcome to EspoCRM', 'Main page header' => '', + 'Bad init Permission' => 'Permission denied for "{*}" directory. Please set 775 for "{*}" or just execute this command in the terminal
{C}
', 'Start page title' => 'License Agreement', 'Step1 page title' => 'License Agreement', 'License Agreement' => 'License Agreement', @@ -88,6 +89,7 @@ return array( 'Ajax failed' => 'Ajax failed', 'Cannot create user' => 'Cannot create user', 'Permission denied' => 'Permission denied', + 'permissionInstruction' => '
Run this in Terminal
"{C}"
', 'Cannot write to files' => 'Cannot write to file(s)', 'Can not save settings' => 'Can not save settings', 'Cannot save preferences' => 'Cannot save preferences', @@ -97,6 +99,20 @@ return array( 'pdo_mysql' => 'PDO MySQL', ), + 'modRewriteInstruction' => array( + 'apache' => array( + 'linux' => '

Run those commands in Terminal
1. a2enmod rewrite 
2. service apache2 restart
', + 'windows' => '
1. Find the httpd.conf file (usually you will find it in a folder called conf, config or something along those lines)
+2. Inside the httpd.conf file uncomment the line LoadModule rewrite_module modules/mod_rewrite.so (remove the pound \'#\' sign from in front of the line)
+3. Also find the line ClearModuleList is uncommented then find and make sure that the line AddModule mod_rewrite.c is not commented out. +
', + ), + 'microsoft-iis' => array( + 'windows' => '', + + ), + ), + 'modRewriteHelp' => array( 'apache' => 'Enable "mod_rewrite" in Apache server', 'nginx' => 'Add this code to Nginx Host Config (inside "server" block):
diff --git a/install/core/tpl/errors.tpl b/install/core/tpl/errors.tpl index 3b99bc6629..b18080e7a6 100644 --- a/install/core/tpl/errors.tpl +++ b/install/core/tpl/errors.tpl @@ -25,10 +25,11 @@ langs: {$langsJs}, ajaxUrls: {$ajaxUrls}, modRewriteUrl: '{$modRewriteUrl}', - serverType: '{$serverType}' + serverType: '{$serverType}', + OS: '{$OS}' } {literal} var installScript = new InstallScript(opt); }) {/literal} - \ No newline at end of file + diff --git a/install/core/tpl/step3.tpl b/install/core/tpl/step3.tpl index 26b27274fd..0135e52738 100644 --- a/install/core/tpl/step3.tpl +++ b/install/core/tpl/step3.tpl @@ -52,10 +52,11 @@ langs: {$langsJs}, ajaxUrls: {$ajaxUrls}, modRewriteUrl: '{$modRewriteUrl}', - serverType: '{$serverType}' + serverType: '{$serverType}', + OS: '{$OS}' } {literal} var installScript = new InstallScript(opt); }) {/literal} - \ No newline at end of file + diff --git a/install/index.php b/install/index.php index 6efa772936..a4c8225bb9 100644 --- a/install/index.php +++ b/install/index.php @@ -20,17 +20,37 @@ * along with EspoCRM. If not, see http://www.gnu.org/licenses/. ************************************************************************/ -error_reporting(0); +//error_reporting(-1); session_start(); require_once('../bootstrap.php'); +// get user selected language +$userLang = (!empty($_SESSION['install']['user-lang']))? $_SESSION['install']['user-lang'] : 'en_US'; +$langFileName = 'core/i18n/'.$userLang.'.php'; +$langs = array(); +if (file_exists('install/'.$langFileName)) { + $langs = include($langFileName); +} else { + $langs = include('core/i18n/en_US.php'); +} + +require_once 'core/SystemHelper.php'; +$systemHelper = new SystemHelper(); + +if (!$systemHelper->initWritable()) { + $dir = $systemHelper->getWritableDir(); + + $message = $langs['Bad init Permission']; + $message = str_replace('{*}', $dir, $message); + $message = str_replace('{C}', $systemHelper->getPermissionCommands($dir, '775'), $message); + die($message); +} + require_once ('install/vendor/smarty/libs/Smarty.class.php'); require_once 'core/Installer.php'; -require_once 'core/SystemHelper.php'; - $smarty = new Smarty(); $installer = new Installer(); @@ -60,21 +80,9 @@ if (!empty($_REQUEST)) { } } -// get user selected language -$userLang = (!empty($_SESSION['install']['user-lang']))? $_SESSION['install']['user-lang'] : 'en_US'; -$langFileName = 'core/i18n/'.$userLang.'.php'; -$langs = array(); -if (file_exists('install/'.$langFileName)) { - $langs = include($langFileName); -} else { - $langs = include('core/i18n/en_US.php'); -} - $smarty->assign("langs", $langs); $smarty->assign("langsJs", json_encode($langs)); -$systemHelper = new SystemHelper(); - // include actions and set tpl name $tplName = 'main.tpl'; $actionsDir = 'core/actions'; @@ -95,6 +103,8 @@ switch ($action) { $smarty->assign("modRewriteUrl", $modRewriteUrl); $serverType = $systemHelper->getServerType(); $smarty->assign("serverType", $serverType); + $os = $systemHelper->getOS(); + $smarty->assign("OS", $os); break; case 'step4': diff --git a/install/js/install.js b/install/js/install.js index 81a1905c78..da46e1b7fe 100644 --- a/install/js/install.js +++ b/install/js/install.js @@ -42,6 +42,10 @@ var InstallScript = function(opt) { if (typeof(opt.serverType) !== 'undefined') { this.serverType = opt.serverType; } + + if (typeof(opt.OS) !== 'undefined') { + this.OS = opt.OS; + } this.connSett = {}; this.userSett = {}; @@ -525,6 +529,7 @@ InstallScript.prototype.checkAjaxPermission = function() { this.ajaxUrlFinished = 0; this.ajaxUrlPermRes = true; this.ajaxUrlPermMsgs = []; + this.ajaxUrlPermInstructions = []; var len = this.ajaxUrls.length; for (var count = 0; count < len; count++) { @@ -600,6 +605,9 @@ InstallScript.prototype.callbackAjaxPerm = function(data) { if (typeof(data.success) != 'undefined' && !data.success) { this.ajaxUrlPermRes = false; this.ajaxUrlPermMsgs.push(data.errorMsg); + if (typeof(data.errorFixInstruction) != 'undefined') { + this.ajaxUrlPermInstructions.push(data.errorFixInstruction); + } } if (this.ajaxUrlFinished == this.ajaxUrls.length) { @@ -608,7 +616,10 @@ InstallScript.prototype.callbackAjaxPerm = function(data) { 'success': this.ajaxUrlPermRes } if (!this.ajaxUrlPermRes) { - var errorMsg = this.getLang('Permission denied') + ':
' + this.ajaxUrlPermMsgs.join('
'); + var errorMsg = this.getLang('Permission denied') + ' ( ' + this.ajaxUrlPermMsgs.join(', ') + ' ) .'; + if (this.ajaxUrlPermInstructions.length > 0) { + errorMsg += '
' + this.getLang('permissionInstruction').replace('"{C}"', this.ajaxUrlPermInstructions.join('
')); + } ajaxData.errorMsg = errorMsg; } this.checkAction(ajaxData); @@ -625,8 +636,10 @@ InstallScript.prototype.callbackModRewrite = function(data) { return; } ajaxData.success = false; - ajaxData.errorMsg = (typeof(this.langs) !== 'undefined' && typeof(this.langs['modRewriteHelp'][this.serverType]) !== 'undefined')? this.langs['modRewriteHelp'][this.serverType] : this.langs['modRewriteHelp']['default']; - + if (typeof(this.langs) !== 'undefined') { + ajaxData.errorMsg = (typeof(this.langs['modRewriteHelp'][this.serverType]) !== 'undefined')? this.langs['modRewriteHelp'][this.serverType] : this.langs['modRewriteHelp']['default']; + ajaxData.errorMsg += (typeof(this.langs['modRewriteInstruction'][this.serverType]) !== 'undefined' && typeof(this.langs['modRewriteInstruction'][this.serverType][this.OS]) !== 'undefined') ? this.langs['modRewriteInstruction'][this.serverType][this.OS] : ''; + } var realCheckIndex = this.checkIndex - 1; if (typeof(this.checkActions[realCheckIndex]) != 'undefined' && typeof(this.checkActions[realCheckIndex].break) != 'undefined') {