diff --git a/core/ajax/plugin.ajax.php b/core/ajax/plugin.ajax.php index 909cc46060..a6face2566 100644 --- a/core/ajax/plugin.ajax.php +++ b/core/ajax/plugin.ajax.php @@ -30,7 +30,7 @@ if (!isConnect('admin')) { throw new Exception(__('401 - Accès non autorisé', __FILE__)); } - $plugin = plugin::byId(init('id')); + $plugin = plugin::byId(init('id'),init('full',0)); $update = update::byLogicalId(init('id')); $return = utils::o2a($plugin); $return['activate'] = $plugin->isActive(); diff --git a/core/api/jeeApi.php b/core/api/jeeApi.php index 59f9db54b4..0ebce9bd61 100644 --- a/core/api/jeeApi.php +++ b/core/api/jeeApi.php @@ -33,8 +33,11 @@ /** @var bool $_RESTRICTED */ global $_RESTRICTED; $_RESTRICTED = false; + + if (init('type') != '') { try { + if (init('type') == 'ask') { if (trim(init('token')) == '' || strlen(init('token')) < 64) { throw new Exception(__('Commande inconnue ou Token invalide', __FILE__)); @@ -60,6 +63,13 @@ sleep(5); throw new Exception(__('Vous n\'êtes pas autorisé à effectuer cette action, IP :', __FILE__) . ' ' . getClientIp()); } + + if(config::byKey('api::forbidden::method', 'core', '') !== '' && preg_match(config::byKey('api::forbidden::method', 'core', ''), init('type'))){ + throw new Exception(__('Cette demande n\'est autorisée', __FILE__) . ' ' . getClientIp()); + } + if(config::byKey('api::allow::method', 'core', '') !== '' && !preg_match(config::byKey('api::allow::method', 'core', ''), init('type'))){ + throw new Exception(__('Cette demande n\'est autorisée', __FILE__) . ' ' . getClientIp()); + } $type = init('type'); log::add('api', 'debug', __('Demande sur l\'api http venant de :', __FILE__) . ' ' . getClientIp() . ' => ' . json_encode($_GET)); @@ -225,7 +235,7 @@ if ($type == 'fullData') { log::add('api', 'debug', __('Demande API pour les commandes', __FILE__)); header('Content-Type: application/json'); - echo json_encode(jeeObject::fullData(), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE, 1024); + echo json_encode(jeeObject::fullData(null,$_USER_GLOBAL), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE, 1024); die(); } if ($type == 'variable') { @@ -269,6 +279,13 @@ throw new Exception(__('Requête invalide. Version JSON-RPC invalide :', __FILE__) . ' ' . $jsonrpc->getJsonrpc(), -32001); } + if(config::byKey('api::forbidden::method', 'core', '') !== '' && preg_match(config::byKey('api::forbidden::method', 'core', ''), $jsonrpc->getMethod())){ + throw new Exception(__('Cette demande n\'est autorisée', __FILE__)); + } + if(config::byKey('api::allow::method', 'core', '') !== '' && !preg_match(config::byKey('api::allow::method', 'core', ''), $jsonrpc->getMethod())){ + throw new Exception(__('Cette demande n\'est autorisée', __FILE__) . ' ' . getClientIp()); + } + $params = $jsonrpc->getParams(); if (!isset($params['plugin']) || $params['plugin'] == '') { diff --git a/core/class/DB.class.php b/core/class/DB.class.php index 4cd5a96487..ca3b48db09 100644 --- a/core/class/DB.class.php +++ b/core/class/DB.class.php @@ -91,6 +91,15 @@ public static function &Prepare($_query, $_params, $_fetchType = self::FETCH_TYP $stmt = static::getConnection()->prepare($_query); $res = NULL; if ($stmt != false && $stmt->execute($_params) != false) { + if(preg_match('/^update|^replace|^delete|^create|^drop|^alter|^truncate/i', $_query)){ + $errorInfo = $stmt->errorInfo(); + if ($errorInfo[0] != 0000) { + static::$lastConnection = 0; + throw new Exception('[MySQL] Error code : ' . $errorInfo[0] . ' (' . $errorInfo[1] . '). ' . $errorInfo[2] . ' : ' . $_query); + } + static::$lastConnection = strtotime('now'); + return $res; + } if ($_fetchType == static::FETCH_TYPE_ROW) { if ($_fetch_opt === null) { $res = $stmt->fetch($_fetch_param); diff --git a/core/class/cache.class.php b/core/class/cache.class.php index 0b594b0f85..857085a47e 100644 --- a/core/class/cache.class.php +++ b/core/class/cache.class.php @@ -96,46 +96,60 @@ public static function stats($_details = false) { * @name getCache() * @access public * @static + * @param string $_engine to override the current cache defined in configuration * @return \Doctrine\Common\Cache\CacheProvider */ - public static function getCache() { - if (self::$cache !== null) { + public static function getCache($_engine = null) { + if ($_engine === null && self::$cache !== null) { return self::$cache; } - $engine = config::byKey('cache::engine'); - if ($engine == 'MemcachedCache' && !class_exists('memcached')) { - $engine = 'FilesystemCache'; - config::save('cache::engine', 'FilesystemCache'); - } - if ($engine == 'RedisCache' && !class_exists('redis')) { - $engine = 'FilesystemCache'; - config::save('cache::engine', 'FilesystemCache'); + if( $_engine === null){ + // get current cache + $engine = config::byKey('cache::engine'); + }else{ + // override existing configuration + $engine = $_engine; + config::save('cache::engine', $_engine); } switch ($engine) { - case 'FilesystemCache': - self::$cache = new \Doctrine\Common\Cache\FilesystemCache(self::getFolder()); - break; case 'PhpFileCache': self::$cache = new \Doctrine\Common\Cache\FilesystemCache(self::getFolder()); break; case 'MemcachedCache': + // check if memcached extention is available + if (!class_exists('memcached')) { + log::add( __CLASS__, 'error', 'memcached extension not installed, fall back to FilesystemCache.'); + return self::getCache( 'FilesystemCache'); + } $memcached = new Memcached(); $memcached->addServer(config::byKey('cache::memcacheaddr'), config::byKey('cache::memcacheport')); self::$cache = new \Doctrine\Common\Cache\MemcachedCache(); self::$cache->setMemcached($memcached); break; case 'RedisCache': + // check if redis extension is available + if (!class_exists('redis')) { + log::add( __CLASS__, 'error', 'redis extension not installed, fall back to FilesystemCache.'); + return self::getCache( 'FilesystemCache'); + } $redis = new Redis(); $redisAddr = config::byKey('cache::redisaddr'); - if (strncmp($redisAddr, '/', 1) === 0) { - $redis->connect($redisAddr); - } else { - $redis->connect($redisAddr, config::byKey('cache::redisport')); + try{ + // try to connect to redis + if (strncmp($redisAddr, '/', 1) === 0) { + $redis->connect($redisAddr); + } else { + $redis->connect($redisAddr, config::byKey('cache::redisport')); + } + }catch( Exception $e){ + // error : fall back to FilesystemCache + log::add( __CLASS__, 'error', 'Unable to connect to redis instance, fall back to FilesystemCache.'."\n".$e->getMessage()); + return self::getCache( 'FilesystemCache'); } self::$cache = new \Doctrine\Common\Cache\RedisCache(); self::$cache->setRedis($redis); break; - default: + default: // default is FilesystemCache self::$cache = new \Doctrine\Common\Cache\FilesystemCache(self::getFolder()); break; } diff --git a/core/class/cmd.class.php b/core/class/cmd.class.php index f2e983a3a8..f83148b77a 100644 --- a/core/class/cmd.class.php +++ b/core/class/cmd.class.php @@ -1658,7 +1658,7 @@ public function toHtml($_version = 'dashboard', $_options = '') { $coupleArray = explode('|', $element); $cmdValue = $this->getCmdValue(); if (is_object($cmdValue) && $cmdValue->getType() == 'info') { - if ($cmdValue->execCmd() == $coupleArray[0]) { + if ($cmdValue->execCmd() == $coupleArray[0] || $cmdValue->execCmd() == $coupleArray[1]) { $listOption .= ''; $foundSelect = true; } else { diff --git a/core/class/cron.class.php b/core/class/cron.class.php index 643604072c..12c415670f 100644 --- a/core/class/cron.class.php +++ b/core/class/cron.class.php @@ -372,6 +372,10 @@ public function isDue() { return false; } try { + $schedule = explode(' ',$this->getSchedule()); + if(count($schedule) == 6 && $schedule[5] != strtotime('Y')){ + return false; + } $c = new Cron\CronExpression(checkAndFixCron($this->getSchedule()), new Cron\FieldFactory); try { if ($c->isDue()) { @@ -551,7 +555,7 @@ public function setDeamonSleepTime($_deamonSleepTime) { } public function getOption() { - return json_decode($this->option, true); + return json_decode($this->option ?? '', true); } public function getOnce($_default = 0) { diff --git a/core/class/eqLogic.class.php b/core/class/eqLogic.class.php index 8b14b22a1a..272a8306be 100644 --- a/core/class/eqLogic.class.php +++ b/core/class/eqLogic.class.php @@ -494,6 +494,9 @@ public static function toHumanReadable($_input) { } public static function fromHumanReadable($_input) { + if(empty($_input)){ + return $_input; + } $isJson = false; if (is_json($_input)) { $isJson = true; @@ -525,7 +528,7 @@ public static function fromHumanReadable($_input) { return $_input; } $text = $_input; - preg_match_all("/#\[(.*?)\]\[(.*?)\]#/", $text, $matches); + preg_match_all( "/#\[(.*?)\]\[(.*?)\]#/", $text, $matches); if (count($matches) == 3) { $countMatches = count($matches[0]); for ($i = 0; $i < $countMatches; $i++) { diff --git a/core/class/history.class.php b/core/class/history.class.php index c1ed749631..d0f5de4a99 100644 --- a/core/class/history.class.php +++ b/core/class/history.class.php @@ -1010,7 +1010,7 @@ public function save($_cmd = null, $_direct = false) { if ($this->getValue() === null) { return; } - //global $JEEDOM_INTERNAL_CONFIG; + global $JEEDOM_INTERNAL_CONFIG; if ($_cmd === null) { $cmd = $this->getCmd(); if (!is_object($cmd)) { diff --git a/core/class/jeeObject.class.php b/core/class/jeeObject.class.php index efb641ad12..37775f9722 100644 --- a/core/class/jeeObject.class.php +++ b/core/class/jeeObject.class.php @@ -147,6 +147,9 @@ public static function toHumanReadable($_input) { } public static function fromHumanReadable($_input) { + if(empty($_input)){ + return $_input; + } $isJson = false; if (is_json($_input)) { $isJson = true; diff --git a/core/class/jeedom.class.php b/core/class/jeedom.class.php index b3bfd2bf1e..2e280b282c 100644 --- a/core/class/jeedom.class.php +++ b/core/class/jeedom.class.php @@ -190,18 +190,19 @@ public static function health() { 'comment' => '', 'key' => 'uptodate' ); - - $status = shell_exec('systemctl status fail2ban.service'); - $failed = stripos($status, 'failed') !== false; - $running = stripos($status, 'running') !== false; - $state = $failed ? 0 : ($running ? 1 : 2); - $return[] = array( - 'name' => __('Etat du service fail2ban', __FILE__), - 'state' => $failed ? 0 : ($running ? 1 : 2), - 'result' => $failed ? __('En échec', __FILE__) : ($running ? __('Actif', __FILE__) : __('Désactivé', __FILE__)), - 'comment' => ($failed || !$running) ? __("Le service Linux fail2ban est désactivé ou en échec : les tentatives d'accès infructueuses à Jeedom ne résulteront pas en un bannissement des IP concernées. Vérifiez l'état du service si vous souhaitez réactiver fail2ban.", __FILE__) : '', - 'key' => 'service::fail2ban' - ); + if (version_compare(self::getOsVersion(), '12', '<')) { + $status = shell_exec('systemctl status fail2ban.service'); + $failed = stripos($status, 'failed') !== false; + $running = stripos($status, 'running') !== false; + $state = $failed ? 0 : ($running ? 1 : 2); + $return[] = array( + 'name' => __('Etat du service fail2ban', __FILE__), + 'state' => $failed ? 0 : ($running ? 1 : 2), + 'result' => $failed ? __('En échec', __FILE__) : ($running ? __('Actif', __FILE__) : __('Désactivé', __FILE__)), + 'comment' => ($failed || !$running) ? __("Le service Linux fail2ban est désactivé ou en échec : les tentatives d'accès infructueuses à Jeedom ne résulteront pas en un bannissement des IP concernées. Vérifiez l'état du service si vous souhaitez réactiver fail2ban.", __FILE__) : '', + 'key' => 'service::fail2ban' + ); + } $state = (config::byKey('enableCron', 'core', 1, true) != 0) ? true : false; $return[] = array( @@ -459,7 +460,7 @@ public static function health() { ); if (shell_exec('which python') != '') { - $value = shell_exec('python --version'); + $value = shell_exec('python --version 2>&1'); // prior python 3.4, 'python --version' output was on stderr $return[] = array( 'name' => __('Python', __FILE__), 'state' => true, diff --git a/core/class/jsonrpcClient.class.php b/core/class/jsonrpcClient.class.php index f388d24b11..5a00138230 100644 --- a/core/class/jsonrpcClient.class.php +++ b/core/class/jsonrpcClient.class.php @@ -175,7 +175,7 @@ private function send($_request, $_timeout = 15, $_file = null, $_maxRetry = 2) if (curl_errno($ch)) { $this->error = 'Erreur curl sur : ' . $this->apiAddr . '. Détail :' . curl_error($ch); } - curl_close($ch); + unset($ch); return $response; } diff --git a/core/class/network.class.php b/core/class/network.class.php index 7cd4136309..0573c82b32 100644 --- a/core/class/network.class.php +++ b/core/class/network.class.php @@ -275,7 +275,7 @@ public static function test($_mode = 'external', $_timeout = 15) { return false; } } - curl_close($ch); + unset($ch); if (trim($data) != 'ok') { log::add('network', 'debug', 'Retour NOK sur ' . $url . ' => ' . $data); return false; diff --git a/core/class/plugin.class.php b/core/class/plugin.class.php index 575559014b..7cc8b10386 100644 --- a/core/class/plugin.class.php +++ b/core/class/plugin.class.php @@ -57,10 +57,10 @@ class plugin { /* * ***********************Méthodes statiques*************************** */ - public static function byId($_id) { + public static function byId($_id,$_full = false) { global $JEEDOM_INTERNAL_CONFIG; - if (is_string($_id) && isset(self::$_cache[$_id])) { - return self::$_cache[$_id]; + if (is_string($_id) && isset(self::$_cache[$_id.'::'.$_full])) { + return self::$_cache[$_id.'::'.$_full]; } if (!file_exists($_id) || strpos($_id, '/') === false) { $path = self::getPathById($_id); @@ -109,7 +109,6 @@ public static function byId($_id) { $plugin->changelog_beta = (isset($data['changelog_beta'])) ? str_replace('#language#', config::byKey('language', 'core', 'fr_FR'), $data['changelog_beta']) : ''; $plugin->documentation_beta = (isset($data['documentation_beta'])) ? str_replace('#language#', config::byKey('language', 'core', 'fr_FR'), $data['documentation_beta']) : ''; if (isset($data['specialAttributes'])) { - if (isset($data['specialAttributes']['object'])) { $plugin->specialAttributes['object'] = $data['specialAttributes']['object']; } @@ -132,16 +131,22 @@ public static function byId($_id) { 'type' => 'class', ); } - $plugin->functionality['interact'] = array('exists' => method_exists($plugin->getId(), 'interact'), 'controlable' => 1); - $plugin->functionality['cron'] = array('exists' => method_exists($plugin->getId(), 'cron'), 'controlable' => 1); - $plugin->functionality['cron5'] = array('exists' => method_exists($plugin->getId(), 'cron5'), 'controlable' => 1); - $plugin->functionality['cron10'] = array('exists' => method_exists($plugin->getId(), 'cron10'), 'controlable' => 1); - $plugin->functionality['cron15'] = array('exists' => method_exists($plugin->getId(), 'cron15'), 'controlable' => 1); - $plugin->functionality['cron30'] = array('exists' => method_exists($plugin->getId(), 'cron30'), 'controlable' => 1); - $plugin->functionality['cronHourly'] = array('exists' => method_exists($plugin->getId(), 'cronHourly'), 'controlable' => 1); - $plugin->functionality['cronDaily'] = array('exists' => method_exists($plugin->getId(), 'cronDaily'), 'controlable' => 1); - $plugin->functionality['deadcmd'] = array('exists' => method_exists($plugin->getId(), 'deadCmd'), 'controlable' => 0); - $plugin->functionality['health'] = array('exists' => method_exists($plugin->getId(), 'health'), 'controlable' => 0); + if($_full){ + $plugin->functionality['interact'] = array('exists' => method_exists($plugin->getId(), 'interact'), 'controlable' => 1); + $plugin->functionality['cron'] = array('exists' => method_exists($plugin->getId(), 'cron'), 'controlable' => 1); + $plugin->functionality['cron5'] = array('exists' => method_exists($plugin->getId(), 'cron5'), 'controlable' => 1); + $plugin->functionality['cron10'] = array('exists' => method_exists($plugin->getId(), 'cron10'), 'controlable' => 1); + $plugin->functionality['cron15'] = array('exists' => method_exists($plugin->getId(), 'cron15'), 'controlable' => 1); + $plugin->functionality['cron30'] = array('exists' => method_exists($plugin->getId(), 'cron30'), 'controlable' => 1); + $plugin->functionality['cronHourly'] = array('exists' => method_exists($plugin->getId(), 'cronHourly'), 'controlable' => 1); + $plugin->functionality['cronDaily'] = array('exists' => method_exists($plugin->getId(), 'cronDaily'), 'controlable' => 1); + $plugin->functionality['deadcmd'] = array('exists' => method_exists($plugin->getId(), 'deadCmd'), 'controlable' => 0); + $plugin->functionality['health'] = array('exists' => method_exists($plugin->getId(), 'health'), 'controlable' => 0); + if($plugin->getCache('usedSpace',-1) == -1){ + $plugin->setCache('usedSpace',getDirectorySize(__DIR__ . '/../../plugins/' . $data['id']),86400); + } + $plugin->usedSpace = $plugin->getCache('usedSpace',-1); + } if (!isset($JEEDOM_INTERNAL_CONFIG['plugin']['category'][$plugin->category])) { foreach ($JEEDOM_INTERNAL_CONFIG['plugin']['category'] as $key => $value) { if (!isset($value['alias'])) { @@ -153,8 +158,7 @@ public static function byId($_id) { } } } - $plugin->usedSpace = getDirectorySize(__DIR__ . '/../../plugins/' . $data['id']); - self::$_cache[$plugin->id] = $plugin; + self::$_cache[$plugin->id.'::'.$_full] = $plugin; return $plugin; } @@ -1332,4 +1336,13 @@ public function setWhiteListFolders($paths) { $this->whiteListFolders = (array) $paths; return $this; } + + public function getCache($_key = '', $_default = '') { + $cache = cache::byKey('pluginCacheAttr' . $this->getId())->getValue(); + return utils::getJsonAttr($cache, $_key, $_default); + } + + public function setCache($_key, $_value = null, $_lifetime = 0) { + cache::set('pluginCacheAttr' . $this->getId(), utils::setJsonAttr(cache::byKey('pluginCacheAttr' . $this->getId())->getValue(), $_key, $_value), $_lifetime); + } } diff --git a/core/class/scenario.class.php b/core/class/scenario.class.php index a579549236..20f58ed5c3 100644 --- a/core/class/scenario.class.php +++ b/core/class/scenario.class.php @@ -660,6 +660,9 @@ public static function toHumanReadable($_input) { * @return string|object|array return value will depends on $_input received */ public static function fromHumanReadable($_input) { + if(empty($_input)){ + return $_input; + } $isJson = false; if (is_json($_input)) { $isJson = true; @@ -1191,6 +1194,12 @@ public function calculateScheduleDate() { $c = new Cron\CronExpression(checkAndFixCron($schedule), new Cron\FieldFactory); $calculatedDate_tmp['prevDate'] = $c->getPreviousRunDate()->format('Y-m-d H:i:s'); $calculatedDate_tmp['nextDate'] = $c->getNextRunDate()->format('Y-m-d H:i:s'); + if(count($schedule) == 6 && $schedule[5] != $c->getPreviousRunDate()->format('Y')){ + $calculatedDate['prevDate'] = ''; + } + if(count($schedule) == 6 && $schedule[5] != $c->getNextRunDate()->format('Y')){ + $calculatedDate['nextDate'] = ''; + } } catch (Exception $exc) { } catch (Error $exc) { } @@ -1206,10 +1215,18 @@ public function calculateScheduleDate() { $c = new Cron\CronExpression(checkAndFixCron($this->getSchedule()), new Cron\FieldFactory); $calculatedDate['prevDate'] = $c->getPreviousRunDate()->format('Y-m-d H:i:s'); $calculatedDate['nextDate'] = $c->getNextRunDate()->format('Y-m-d H:i:s'); + $schedule = explode(' ',$this->getSchedule()); + if(count($schedule) == 6 && $schedule[5] != $c->getPreviousRunDate()->format('Y')){ + $calculatedDate['prevDate'] = ''; + } + if(count($schedule) == 6 && $schedule[5] != $c->getNextRunDate()->format('Y')){ + $calculatedDate['nextDate'] = ''; + } } catch (Exception $exc) { } catch (Error $exc) { } } + return $calculatedDate; } /** @@ -1230,6 +1247,10 @@ public function isDue() { if (is_array($this->getSchedule())) { foreach (($this->getSchedule()) as $schedule) { try { + $schedule = explode(' ',$this->getSchedule()); + if(count($schedule) == 6 && $schedule[5] != strtotime('Y')){ + return false; + } $c = new Cron\CronExpression(checkAndFixCron($schedule), new Cron\FieldFactory); try { if ($c->isDue()) { diff --git a/core/class/system.class.php b/core/class/system.class.php index 96e614a299..58d508bad1 100644 --- a/core/class/system.class.php +++ b/core/class/system.class.php @@ -54,7 +54,7 @@ public static function getDistrib() { return 'custom'; } if (self::$_distrib === null) { - self::$_distrib = trim(shell_exec('grep CPE_NAME /etc/os-release | cut -d \'"\' -f 2 | cut -d : -f 3 ')); + self::$_distrib = trim(shell_exec('grep CPE_NAME /etc/os-release | cut -d \'"\' -f 2 | cut -d : -f 3 ') ?? ''); if (self::$_distrib == '') { self::$_distrib = trim(shell_exec('grep -e "^ID" /etc/os-release | cut -d \'=\' -f 2')); } @@ -94,6 +94,8 @@ public static function getCmdSudo(): string { } public static function fuserk($_port, $_protocol = 'tcp'): void { + if (!is_string($_port)) return; + if (file_exists($_port)) { exec(system::getCmdSudo() . 'fuser -k ' . $_port . ' > /dev/null 2>&1'); } else { @@ -379,6 +381,13 @@ public static function getInstallPackage($_type, $_plugin) { break; case 'pip3': $datas = json_decode(shell_exec(self::getCmdSudo() . self::getCmdPython3($_plugin) . ' -m pip list --format=json 2>/dev/null'), true); + if (!is_array($datas)) { + // patch mainly for debian 11 because python3-gpg is on version '1.14.0-unknown' and pip>24.1 raise error with non-standard version format + // no check on os version in case this issue occurs also with debian 12 (hopefully not) + // the awk command transforms the output of 'pip list' (multiline columns) to a "json string" to reproduce the result of '--format=json' argument + $listToJson = self::getCmdSudo() . self::getCmdPython3($_plugin) . ' -m pip list 2>/dev/null | awk \'BEGIN{print "["} NR>2 {printf "%s{\"name\": \"%s\", \"version\": \"%s\"}",sep,$1,$2; sep=", "} END{print "]\n"}\' ORS=\'\''; + $datas = json_decode(shell_exec($listToJson), true); + } if (!is_array($datas)) { break; } @@ -419,7 +428,7 @@ public static function getInstallPackage($_type, $_plugin) { } break; case 'composer': - $datas = json_decode(shell_exec(self::getCmdSudo() . ' composer show -f json 2>/dev/null')); + $datas = json_decode(shell_exec(self::getCmdSudo() . ' composer show -f json 2>/dev/null'), true); foreach ($datas['installed'] as $value) { self::$_installPackage[$type_key][mb_strtolower($value['name'])] = array('version' => $value['version']); } @@ -467,7 +476,7 @@ public static function checkAndInstall($_packages, $_fix = false, $_foreground = if (file_exists(__DIR__ . '/../../' . $package . '/package.json')) { $version = json_decode(file_get_contents(__DIR__ . '/../../' . $package . '/package.json'), true)['version']; if ($type == 'npm') { - if (file_exists(__DIR__ . '/../../' . $package . '/node_modules')) { + if (file_exists(__DIR__ . '/../../' . $package . '/node_modules') && isset(scandir(__DIR__ . '/../../' . $package . '/node_modules', SCANDIR_SORT_NONE)[2])) { exec('cd ' . __DIR__ . '/../../' . $package . ';' . self::getCmdSudo() . ' npm ls', $output, $return_var); if ($return_var == 0) { $found = 1; diff --git a/core/class/update.class.php b/core/class/update.class.php index 8067db4cb2..eb0fc78652 100644 --- a/core/class/update.class.php +++ b/core/class/update.class.php @@ -483,6 +483,7 @@ public function postInstallUpdate($_infos) { if (is_object($plugin) && $plugin->isActive()) { $plugin->setIsEnable(1); } + $plugin->setCache('usedSpace',null); break; } if (isset($_infos['localVersion'])) { diff --git a/core/class/user.class.php b/core/class/user.class.php index 9026002c89..670019cb7a 100644 --- a/core/class/user.class.php +++ b/core/class/user.class.php @@ -327,8 +327,8 @@ public static function isBan(): bool { $values[] = array('datetime' => strtotime('now'), 'ip' => getClientIp()); $_SESSION['failed_count'] = 0; $_SESSION['failed_datetime'] = -1; - @session_write_close(); } + @session_write_close(); cache::set('security::banip', json_encode($values)); if (!is_array($values)) { $values = array(); diff --git a/core/class/utils.class.php b/core/class/utils.class.php index dadef62f97..43389dc37f 100644 --- a/core/class/utils.class.php +++ b/core/class/utils.class.php @@ -174,7 +174,7 @@ public static function getJsonAttr(&$_attr, $_key = '', $_default = '') { if ($_key == '') { return is_json($_attr, array()); } - if ($_attr === '') { + if (empty($_attr)) { if (is_array($_key)) { foreach ($_key as $key) { $return[$key] = $_default; @@ -226,7 +226,7 @@ public static function encrypt($plaintext, $password = null) { } public static function decrypt($ciphertext, $password = null) { - if ($ciphertext === '') { + if (empty($ciphertext)) { return null; } if ($password == null) { diff --git a/core/com/http.com.php b/core/com/http.com.php index 46a33f5164..8f174ab6f0 100644 --- a/core/com/http.com.php +++ b/core/com/http.com.php @@ -128,7 +128,7 @@ public function exec($_timeout = 2, $_maxRetry = 3) { if (!isset($response)) { $response = ''; } - if (isset($ch) && is_resource($ch)) { + if (isset($ch) && $ch !== false) { if (curl_errno($ch)) { $curl_error = curl_error($ch); curl_close($ch); @@ -142,7 +142,7 @@ public function exec($_timeout = 2, $_maxRetry = 3) { throw new Exception(__('Echec de la requête HTTP :', __FILE__) . ' ' . $this->url . ' cURL error : ' . $curl_error, 404); } } else { - curl_close($ch); + unset($ch); } } $ch = null; diff --git a/core/config/version b/core/config/version index 3401474547..bc30b06460 100644 --- a/core/config/version +++ b/core/config/version @@ -1 +1 @@ -4.4.7 \ No newline at end of file +4.4.8 \ No newline at end of file diff --git a/core/dom/dom.ui.js b/core/dom/dom.ui.js index 44ae6a101b..343994b4e4 100644 --- a/core/dom/dom.ui.js +++ b/core/dom/dom.ui.js @@ -77,7 +77,20 @@ NodeList.prototype.unseen = function() { } return this } - +Element.prototype.toggle = function() { + if (this.offsetParent === null){ + this.style.display = '' + } else { + this.style.display = 'none' + } + return this +} +NodeList.prototype.toggle = function() { + for (var idx = 0; idx < this.length; idx++) { + this[idx].toggle() + } + return this +} Element.prototype.empty = function() { while (this.firstChild) { this.removeChild(this.lastChild) diff --git a/core/js/plugin.class.js b/core/js/plugin.class.js index 236204d9e9..7a17f656fe 100644 --- a/core/js/plugin.class.js +++ b/core/js/plugin.class.js @@ -79,7 +79,8 @@ jeedom.plugin.get = function (_params) { paramsAJAX.url = 'core/ajax/plugin.ajax.php'; paramsAJAX.data = { action: 'getConf', - id: _params.id + id: _params.id, + full: _params.full || 0, }; domUtils.ajax(paramsAJAX); } diff --git a/core/php/getResource.php b/core/php/getResource.php index 9faef3ff57..f70ba961ef 100644 --- a/core/php/getResource.php +++ b/core/php/getResource.php @@ -42,7 +42,7 @@ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT'); header('Etag: ' . $etagFile); header('Cache-Control: public'); - if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified || $etagHeader == $etagFile) { + if (($ifModifiedSince !== false && $ifModifiedSince == $lastModified) || $etagHeader == $etagFile) { header('HTTP/1.1 304 Not Modified'); exit; } diff --git a/core/php/utils.inc.php b/core/php/utils.inc.php index c113fcf7d0..ad4c666c83 100644 --- a/core/php/utils.inc.php +++ b/core/php/utils.inc.php @@ -254,9 +254,9 @@ function mySqlIsHere() { function displayException($e) { $message = '' . $e->getMessage() . ''; - if (DEBUG) { - $message .= 'Show traces'; - $message .= '
'; + if (DEBUG !== 0) { + $message .= "Show traces"; + $message .= '
'; } return $message; } @@ -859,7 +859,11 @@ function getDirectorySize($path) { $path = realpath($path); if($path!==false && $path!='' && file_exists($path) && !is_link($path)){ foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)) as $object){ - $bytestotal += $object->getSize(); + try { + $bytestotal += $object->getSize(); + } catch (\Throwable $th) { + + } } } return $bytestotal; @@ -881,7 +885,6 @@ function sizeFormat($size) { * @return boolean */ function netMatch($network, $ip) { - $ip = trim($ip); if ($ip == trim($network)) { return true; @@ -1440,6 +1443,22 @@ function checkAndFixCron($_cron) { return $return; } +function cronIsDue($_cron){ + $schedule = explode(' ',$_cron); + if(count($schedule) == 6 && $schedule[5] != strtotime('Y')){ + return false; + } + $c = new Cron\CronExpression(checkAndFixCron($_cron), new Cron\FieldFactory); + try { + return $c->isDue(); + } catch (Exception $e) { + + } catch (Error $e) { + + } + return false; +} + function getTZoffsetMin() { $tz = date_default_timezone_get(); date_default_timezone_set("UTC"); @@ -1551,7 +1570,9 @@ function pageTitle($_page) { } function cleanComponanteName($_name) { - return strip_tags(str_replace(array('&', '#', ']', '[', '%', "\\", "/", "'", '"', "*"), '', $_name)); + $return = strip_tags(str_replace(array('&', '#', ']', '[', '%', "\\", "/", "'", '"', "*"), '', $_name)); + $return = preg_replace('/\s+/', ' ', $return); + return $return; } function startsWith($haystack, $needle) { diff --git a/core/template/scenario/scenario.default.html b/core/template/scenario/scenario.default.html index 1d75242a0b..0774702d3c 100644 --- a/core/template/scenario/scenario.default.html +++ b/core/template/scenario/scenario.default.html @@ -2,6 +2,7 @@
{{Scénario}} + {{Action}} +
diff --git a/desktop/common/js/utils.js b/desktop/common/js/utils.js index e86f861728..f14df86803 100644 --- a/desktop/common/js/utils.js +++ b/desktop/common/js/utils.js @@ -1102,7 +1102,7 @@ jeedomUtils.initReportMode = function() { jeedomUtils.initTableSorter = function(filter) { if (typeof jQuery !== 'function') return - if (typeof $.tablesorter !== 'function') return + if (typeof $.tablesorter !== 'object') return var widgets = ['uitheme', 'resizable'] if (!filter) { filter = true @@ -1133,18 +1133,16 @@ jeedomUtils.initTableSorter = function(filter) { }).css('width', '') } -jeedomUtils.initDataTables = function(_selector, _paging, _searching) { +jeedomUtils.initDataTables = function(_selector, _paging, _searching,_init) { if (!isset(_selector)) _selector = 'body' if (!_paging) _paging = false if (!_searching) _searching = false document.querySelector(_selector).querySelectorAll('table.dataTable').forEach(_table => { if (_table._dataTable) { _table._dataTable.destroy() - } + } new DataTable(_table, { - columns: [ - { select: 0, sort: "asc" } - ], + columns: _init || [{ select: 0, sort: "asc" }], paging: _paging, searchable: _searching, }) diff --git a/desktop/css/desktop.main.css b/desktop/css/desktop.main.css index 874bdb127c..dadd8fce1f 100644 --- a/desktop/css/desktop.main.css +++ b/desktop/css/desktop.main.css @@ -4685,7 +4685,7 @@ div.eqLogic-widget.editingMode .panelLink { } #pre_scenariolog { width: 100%; - height: calc(100% - 30px); + height: calc(100% - 36px); overflow: auto; } #pre_globallog, diff --git a/desktop/js/plugin.js b/desktop/js/plugin.js index 99eea9b15e..4c17e48821 100644 --- a/desktop/js/plugin.js +++ b/desktop/js/plugin.js @@ -68,6 +68,7 @@ if (!jeeFrontEnd.plugin) { domUtils.showLoading() jeedom.plugin.get({ id: _pluginId, + full: 1, error: function(error) { jeedomUtils.showAlert({ message: error.message, diff --git a/desktop/js/reboot.js b/desktop/js/reboot.js index c70e268c44..6b4a016ba2 100644 --- a/desktop/js/reboot.js +++ b/desktop/js/reboot.js @@ -21,7 +21,7 @@ function redirectIP() { new ping(ip, function (status, e) { // console.log(status) if (redirect == 100) { - document.getElementById('div_reboot_jeedom_texte').empty().html('
{{Impossible de trouver la box suite au redémarrage ...}}
') + document.getElementById('div_reboot_jeedom_texte').empty().html('
' + JEEDOM_PRODUCT_NAME + ' {{Impossible de trouver la box suite au redémarrage ...}}
') } else { if (status == 'timeout') { document.getElementById('progressbar_reboot').style.width = redirect + '%' @@ -29,7 +29,7 @@ function redirectIP() { redirectIP() }, 2000) } else if(status == 'responded') { - document.getElementById('div_reboot_jeedom_texte').empty().html('
{{est de nouveau opérationnel. Vous allez être redirigé vers votre dashboard. Cela peut prendre environ 30 secondes.}}
') + document.getElementById('div_reboot_jeedom_texte').empty().html('
' + JEEDOM_PRODUCT_NAME + ' {{est de nouveau opérationnel. Vous allez être redirigé vers votre dashboard. Cela peut prendre environ 30 secondes.}}
') document.getElementById('progressbar_reboot').addClass('progress-bar-success').removeClass('progress-bar-danger') document.getElementById('progressbar_reboot').style.width = '75%' setTimeout(function() { @@ -46,7 +46,7 @@ function returnToJeedom() { } function reboot_jeedom() { - document.getElementById('div_reboot_jeedom_texte').empty().html('
{{Merci de patienter...}}
{{est en cours de redémarrage.}}
') + document.getElementById('div_reboot_jeedom_texte').empty().html('
{{Merci de patienter...}}
' + JEEDOM_PRODUCT_NAME + ' {{est en cours de redémarrage.}}
') document.getElementById('progressbar_reboot').style.width = '25%' redirectIP() } diff --git a/desktop/modal/cmd.configureHistory.php b/desktop/modal/cmd.configureHistory.php index 86b4ecd4b7..90062f9c68 100644 --- a/desktop/modal/cmd.configureHistory.php +++ b/desktop/modal/cmd.configureHistory.php @@ -47,6 +47,7 @@ {{Lissage}} {{Purge}} + + {{Limiter à}} {{Action}} @@ -134,15 +143,30 @@ if ($cmd->getType() == 'info') { $confHistoryPurge = $cmd->getConfiguration('historyPurge'); $tr .= ''; + } + $tr .= ''; + + //smoothTime + $tr .= ''; + if ($cmd->getType() == 'info') { + $confHistoryPurge = $cmd->getConfiguration('history::smooth'); + $tr .= ''; } $tr .= ''; @@ -183,7 +207,7 @@ jeeFrontEnd.md_cmdConfigureHistory.vDataTable = new DataTable(jeeFrontEnd.md_cmdConfigureHistory.tableConfig, { columns: [ { select: 0, sort: "asc" }, - { select: [8], sortable: false } + { select: [9], sortable: false } ], paging: true, perPage: 20, @@ -305,6 +329,17 @@ }) return } + + if (_target = event.target.closest('#smoothTimeSelectAll')) { + event.stopPropagation() + event.preventDefault() + var cells = Array.from(document.querySelectorAll('#table_cmdConfigureHistory select.cmdAttr[data-l2key="history::smooth"]')).filter(c => c.isVisible() && c.disabled == false ) + cells.forEach(_cell => { + _cell.value = _target.value + _cell.closest('tr').setAttribute('data-change', '1') + }) + return + } }) })() diff --git a/desktop/modal/first.use.php b/desktop/modal/first.use.php index be5d8f13af..7d0d07729e 100644 --- a/desktop/modal/first.use.php +++ b/desktop/modal/first.use.php @@ -21,10 +21,15 @@ } $pluginJeeEasy = false; -if(is_object(plugin::byId('jeeasy'))) { - $pluginJeeEasy = true; +try { + if(is_object(plugin::byId('jeeasy'))) { + $pluginJeeEasy = true; + } +} catch (\Throwable $th) { + } + $showDoc = false; if (config::byKey('doc::base_url', 'core') != '') { $showDoc = true; diff --git a/desktop/modal/message.display.php b/desktop/modal/message.display.php index eb501871ad..a8ce41e68e 100644 --- a/desktop/modal/message.display.php +++ b/desktop/modal/message.display.php @@ -80,7 +80,7 @@ (function() {// Self Isolation! jeedomUtils.hideAlert() - jeedomUtils.initDataTables('#md_messageDisplay', false, false) + jeedomUtils.initDataTables('#md_messageDisplay', false, false,[{ select: 1, sort: "desc" }]) let table = document.querySelector('#md_messageDisplay #table_message') let msgDataTable = table._dataTable diff --git a/desktop/php/administration.php b/desktop/php/administration.php index 7b4ae84935..53c752f964 100644 --- a/desktop/php/administration.php +++ b/desktop/php/administration.php @@ -2178,6 +2178,20 @@ + +
+ +
+ +
+
+
+ +
+ +
+
+
-
- - - - -
@@ -38,6 +32,12 @@
+
+ + + + +


diff --git a/docs/fr_FR/changelog.md b/docs/fr_FR/changelog.md index dc48aa43d8..48d15eed7e 100644 --- a/docs/fr_FR/changelog.md +++ b/docs/fr_FR/changelog.md @@ -1,8 +1,32 @@ # Changelog Jeedom V4.4 ->**IMPORTANT** -> ->Même si elles ne sont pas forcément visibles au premier abord, la version 4.4 de Jeedom apporte des modifications majeures avec une interface qui a été complètement réécrite pour une maitrise complète et surtout un gain de fluidité de navigation inégalé. La gestion des dépendances PHP à également été revue afin de pouvoir les maintenir à jour automatiquement. Même si l'équipe Jeedom et les beta testeurs ont fait énormément de tests, il y a autant de version de jeedom qu'il y a de jeedom... Il n'est donc pas possible de garantir un bon fonctionnement dans 100% des cas cependant en cas de souci vous pouvez [ouvrir un sujet sur le forum avec l'étiquette `v4_4`](https://community.jeedom.com/) ou contacter le support depuis votre profil market *(sous condition d'être détenteur d'un service pack ou supérieur)*. +# 4.4.8 + +- Ajout d'options avancées pour interdire certaines mehtodes api ou n'autoriser que certain [LIEN](https://github.com/jeedom/core/issues/2707) +- Amélioration de la fenetre de configuration des historiques [LIEN](https://github.com/jeedom/core/issues/2687) +- Amélioration des trace en debug [LIEN](https://github.com/jeedom/core/pull/2654) +- Suppression de message de warning [LIEN](https://github.com/jeedom/core/pull/2657) +- Correction d'un soucis sur la page des logs sur les petits ecran ou les boutons étaient non visible [LIEN](https://github.com/jeedom/core/issues/2671). Une autre amélioration est prévu plus tard pour avoir les boutons mieux placé [LIEN](https://github.com/jeedom/core/issues/2672) +- Amélioration de la gestion des select [LIEN](https://github.com/jeedom/core/pull/2675) +- Augmentation de la taille du champs pour la valeur du sleep dans les scénarios [LIEN](https://github.com/jeedom/core/pull/2682) +- Correction d'un soucis sur l'ordre des messages dans le centre des messages [LIEN](https://github.com/jeedom/core/issues/2686) +- Optimisation du chargement des plugins [LIEN](https://github.com/jeedom/core/issues/2689) +- Augmentation de la taille des barres de defilements sur certain page [LIEN](https://github.com/jeedom/core/pull/2691) +- Amélioration de la page de redemarrage de jeedom [LIEN](https://github.com/jeedom/core/pull/2685) +- Correction d'un soucis sur les dépendances nodejs lors des restauration [LIEN](https://github.com/jeedom/core/issues/2621). Note : cela va réduire la taille des backups +- Correction d'un bug sur le système de mise à jour de la base de données [LIEN](https://github.com/jeedom/core/issues/2693) +- Correction d'un soucis d'indexe manquant pour les interactions [LIEN](https://github.com/jeedom/core/issues/2694) +- Amélioration du script sick.php pour mieux détecter les soucis de base de données [LIEN](https://github.com/jeedom/core/pull/2677) +- Meilleurs gestion de python2 sur la page santé [LIEN](https://github.com/jeedom/core/pull/2674) +- Amélioration du champs de selection des scénarios (avec recherche) dans les actions sur scénario [LIEN](https://github.com/jeedom/core/pull/2688) +- Amélioration de la gestion des cron en prevision de php8 [LIEN](https://github.com/jeedom/core/issues/2698) +- Amélioration de la fonction de gestion de l'arret des demons par le numero de port [LIEN](https://github.com/jeedom/core/pull/2697) +- Correction d'un soucis sur certain navigateur avec les filtres [LIEN](https://github.com/jeedom/core/issues/2699) +- Amélioration du support de curl [LIEN](https://github.com/jeedom/core/pull/2702) +- Correction d'un bug sur la gestion des dépendances composer [LIEN](https://github.com/jeedom/core/pull/2703) +- Amélioration du systeme de gestion du cache [LIEN](https://github.com/jeedom/core/pull/2706) +- Meilleurs gestion des droits utilisateurs sur les appels API [LIEN](https://github.com/jeedom/core/pull/2695) +- Correction de warning [LIEN](https://github.com/jeedom/core/pull/2701) # 4.4.7 @@ -24,7 +48,7 @@ - Correction d'un soucis d'incoherence sur les valeurs minimales des tailles de rapport [LIEN](https://github.com/jeedom/core/issues/2449) - Correction d'un bug sur la verfication de la base de données ou il pouvait toujours manquer un index [LIEN](https://github.com/jeedom/core/issues/2655) - Correction d'un bug sur le graphique des liens [LIEN](https://github.com/jeedom/core/issues/2659) -- Suppression sur service worker en mobile (plus utilisé) [LIEN](https://github.com/jeedom/core/issues/2660) +- Suppression du service worker en mobile (plus utilisé) [LIEN](https://github.com/jeedom/core/issues/2660) - Correction d'un bug pouvant affecter la limitation du nombre d'evenement dans la timeline [LIEN](https://github.com/jeedom/core/issues/2663) - Correction d'un bug sur l'affichage des tooltips sur les designs [LIEN](https://github.com/jeedom/core/pull/2667) - Amélioration de la gestion des trace de PDO avec php8 [LIEN](https://github.com/jeedom/core/pull/2661) @@ -73,6 +97,10 @@ - Vérification de la version minimale du core requise avant installation ou mise à jour d'un plugin. - Ajout d'un bouton **Assistance** sur la page de configuration des plugins *(Création automatique d'une demande d'aide sur le forum)*. +>**IMPORTANT** +> +>Même si elles ne sont pas forcément visibles au premier abord, la version 4.4 de Jeedom apporte des modifications majeures avec une interface qui a été complètement réécrite pour une maitrise complète et surtout un gain de fluidité de navigation inégalé. La gestion des dépendances PHP à également été revue afin de pouvoir les maintenir à jour automatiquement. Même si l'équipe Jeedom et les beta testeurs ont fait énormément de tests, il y a autant de version de jeedom qu'il y a de jeedom... Il n'est donc pas possible de garantir un bon fonctionnement dans 100% des cas cependant en cas de souci vous pouvez [ouvrir un sujet sur le forum avec l'étiquette `v4_4`](https://community.jeedom.com/) ou contacter le support depuis votre profil market *(sous condition d'être détenteur d'un service pack ou supérieur)*. + ### 4.4 : Pré-requis - Debian 11 "Bullseye" *(très fortement recommandé, Jeedom reste fonctionnel en version précédente)* diff --git a/install/backup.php b/install/backup.php index 216889c117..0e0d4affb0 100644 --- a/install/backup.php +++ b/install/backup.php @@ -131,6 +131,7 @@ 'script/tunnel', '.git', '.gitignore', + 'node_modules', '.log', 'core/config/common.config.php', 'data/imgOs', diff --git a/install/database.json b/install/database.json index 75e55d7383..4834eb5b88 100644 --- a/install/database.json +++ b/install/database.json @@ -909,8 +909,19 @@ } ], "indexes": { - "fk_sarahQuery_sarahDef1_idx": { - "Key_name": "fk_sarahQuery_sarahDef1_idx", + "logicalID": { + "Key_name": "query", + "Non_unique": "1", + "Index_type" : "FULLTEXT", + "columns": { + "1": { + "column": "query", + "Sub_part": null + } + } + }, + "interactDef_id": { + "Key_name": "interactDef_id", "Non_unique": "1", "columns": { "1": { diff --git a/install/fail2ban.jeedom.conf b/install/fail2ban.jeedom.conf index 2acd2fd9b3..a3ab19c601 100644 --- a/install/fail2ban.jeedom.conf +++ b/install/fail2ban.jeedom.conf @@ -42,4 +42,4 @@ enabled = true port = http,https filter = apache-noscript logpath = /var/www/html/log/http*.error -maxretry = 1 +maxretry = 1 \ No newline at end of file diff --git a/sick.php b/sick.php index 6855776dc6..adad233470 100644 --- a/sick.php +++ b/sick.php @@ -29,7 +29,7 @@ try { require_once __DIR__ . "/core/php/core.inc.php"; echo "OK\n"; -} catch (Exeption $e) { +} catch (Exception $e) { echo "ERROR\n"; echo "Cannot load Jeedom environment : " . $e->getMessage(); echo "\n"; @@ -37,7 +37,7 @@ } /* Check log dir */ -echo "Checl write mode on log files ..."; +echo "Check write mode on log files ..."; if (!file_exists($install_dir . '/log')) { echo "unfound /log folder\n"; echo "Required command : mkdir " . $install_dir . "/log\n"; @@ -50,6 +50,86 @@ } echo "OK\n"; +echo " +************************************************** +* DATABASE CONNECTION * +************************************************** +"; + +// check that mysql exists as available driver +if( !in_array( 'mysql', PDO::getAvailableDrivers())){ + die( "Driver mysql non installé !\n"); +}else{ + echo "Driver mysql disponible.\n"; +} +// check database configuration +if(!file_exists(__DIR__ . '/core/config/common.config.php')){ + die('Configuration manquante ! core/config/common.config.php non généré.'); +} + +require_once __DIR__ . '/core/config/common.config.php'; + +// check local socket if localhost is configured +if(isset($CONFIG['db']['unix_socket']) || (isset($CONFIG['db']['host']) && $CONFIG['db']['host'] == 'localhost')) { + + // check default socket configuration for mysql + $default_socket = ini_get('pdo_mysql.default_socket'); + if(empty($default_socket)){ + die( "pdo_mysql.default_socket = VIDE ! + vérifier /usr/local/etc/php/php.ini + et ajouter dans la section [Pdo_mysql] + pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock"); + } else { + if(!file_exists($default_socket)){ + die( "Pas de socker: $default_socket"); + } + if(!is_readable($default_socket)){ + die( "Fichier inaccessible en lecture ! $default_socket"); + } + if(!is_writeable($default_socket)){ + die( "Fichier inaccessible en écriture ! $default_socket"); + } + } + +} + +// TODO: check env var MYSQL_HOST ? + +if (isset($CONFIG['db']['unix_socket'])) { + try { + $connection = new PDO('mysql:unix_socket=' . $CONFIG['db']['unix_socket'] . ';dbname=' . $CONFIG['db']['dbname'], $CONFIG['db']['username'], $CONFIG['db']['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci', PDO::ATTR_PERSISTENT => true)); + } catch (Exception $e) { + echo $e->getMessage(); + } +} else { + try { + $connection = new PDO('mysql:host=' . $CONFIG['db']['host'] . ';port=' . $CONFIG['db']['port'] . ';dbname=' . $CONFIG['db']['dbname'], $CONFIG['db']['username'], $CONFIG['db']['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci', PDO::ATTR_PERSISTENT => true)); + } catch (Exception $e) { + echo $e->getMessage(); + } +} + +if( !isset($connection)) { + die( 'ECHEC ! impossible de se connecter à la bdd mariadb'); +}else{ + $result = $connection->query('SHOW TABLES;'); + $arr = $result->fetchAll(); + if(count($arr) == 0){ + die( "Aucune table ! relancer l'installation: php instal.php --force"); + }else{ + echo 'Connection OK - ' . count($arr) . ' tables. + '; + } +} + +if(empty(session_save_path())) { + echo "Paramètre session.save_path manquant dans /usr/local/etc/php/php.ini + [Session] + session.save_path = \"/tmp/jeedom\" + "; +} + + echo "\n**************************************************\n"; echo "* USERS *"; echo "\n**************************************************\n"; @@ -75,7 +155,7 @@ $user->save(); echo "OK (admin/admin)\n"; } -} catch (Exeption $e) { +} catch (Exception $e) { echo "ERROR\n"; echo "Description : " . $e->getMessage(); echo "\n";