From fc5b1879846dcf9f479216c8dd2f099c106af5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= <1536036+zoic21@users.noreply.github.com> Date: Tue, 17 Jun 2025 12:29:29 +0200 Subject: [PATCH 01/24] Fix too much refresh https://community.jeedom.com/t/refresh-de-la-tuile-sur-une-cmd-action-color/141380/6 --- core/class/cmd.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/class/cmd.class.php b/core/class/cmd.class.php index 9000d3935f..27f07b9827 100644 --- a/core/class/cmd.class.php +++ b/core/class/cmd.class.php @@ -3066,8 +3066,8 @@ public function getDisplay($_key = '', $_default = '') { return utils::getJsonAttr($this->display, $_key, $_default); } - public function setDisplay($_key, $_value) { - if ($this->getDisplay($_key) !== $_value) { + public function setDisplay($_key, $_value = null) { + if ($this->getDisplay($_key,null) !== $_value) { $this->_needRefreshWidget = true; $this->_changed = true; } From d593c0650a009987c020a6b4108c42bb8996077b Mon Sep 17 00:00:00 2001 From: David <79108364+Phpvarious@users.noreply.github.com> Date: Sun, 27 Jul 2025 21:49:16 +0200 Subject: [PATCH 02/24] Update user.class.php --- core/class/user.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/class/user.class.php b/core/class/user.class.php index 8f834215c1..95567f5302 100644 --- a/core/class/user.class.php +++ b/core/class/user.class.php @@ -122,7 +122,7 @@ public static function connect(string $_login, string $_mdp) { ->setProfils($profile); $user->save(); log::add("connection", "info", __('User created from the LDAP :', __FILE__) . ' ' . $_login); - jeedom::event('user_connect'); + jeedom::event('user_connect', false, array('trigger_value' => $_login)); // TODO : if username == password => change ldap password log::add('event', 'info', __('User connection accepted', __FILE__) . ' ' . $_login); return $user; @@ -145,7 +145,7 @@ public static function connect(string $_login, string $_mdp) { if (is_object($user)) { $user->setOptions('lastConnection', date('Y-m-d H:i:s')); $user->save(); - jeedom::event('user_connect'); + jeedom::event('user_connect', false, array('trigger_value' => $_login)); log::add('event', 'info', __('Local account found for', __FILE__) . ' ' . $_login); log::add('event', 'info', __('User connection accepted', __FILE__) . ' ' . $_login); } From 99715ffbd6154c88d0b2f7a43e1c7e9c35394af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= <1536036+zoic21@users.noreply.github.com> Date: Tue, 25 Nov 2025 14:35:25 +0100 Subject: [PATCH 03/24] Fix error Class "SolarData\SolarData" not found --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 25d7fc3830..607694c32b 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "require": { + "abbadon1334/sun-position-spa-php" : "^2", "dragonmantank/cron-expression": "^3", "symfony/expression-language": "5 - 7", "pragmarx/google2fa-qrcode": "^3", From 593a8ac98d10a3a782e1525e190ca454b267efee Mon Sep 17 00:00:00 2001 From: Salvialf Date: Tue, 25 Nov 2025 18:40:46 +0100 Subject: [PATCH 04/24] update composer.lock --- composer.lock | 206 +++++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/composer.lock b/composer.lock index b78c8572c4..3c89db4378 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,59 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6d3817ee337cc5ed162b1e9463030e8a", + "content-hash": "be46045c22daf0366a838f96eed56caf", "packages": [ + { + "name": "abbadon1334/sun-position-spa-php", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/abbadon1334/sun-position-spa-php.git", + "reference": "26244d51284ae80061dc21f26d4b1c31672354bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/abbadon1334/sun-position-spa-php/zipball/26244d51284ae80061dc21f26d4b1c31672354bf", + "reference": "26244d51284ae80061dc21f26d4b1c31672354bf", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "codacy/coverage": "dev-master", + "friendsofphp/php-cs-fixer": "dev-master@dev", + "phpmd/phpmd": "2.6.0", + "phpmetrics/phpmetrics": "dev-master@dev", + "phpstan/phpstan": "0.11.5", + "phpunit/phpunit": "*", + "squizlabs/php_codesniffer": "3.4.2", + "symfony/yaml": "~2.1|~3.0|~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "SolarData\\": "src/", + "SolarData\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Francesco Danti", + "email": "fdanti@gmail.com" + } + ], + "description": "solar data calculation and sun position", + "support": { + "issues": "https://github.com/abbadon1334/sun-position-spa-php/issues", + "source": "https://github.com/abbadon1334/sun-position-spa-php/tree/master" + }, + "time": "2019-07-08T09:51:15+00:00" + }, { "name": "bacon/bacon-qr-code", "version": "2.0.8", @@ -128,16 +179,16 @@ }, { "name": "dasprid/enum", - "version": "1.0.6", + "version": "1.0.7", "source": { "type": "git", "url": "https://github.com/DASPRiD/Enum.git", - "reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90" + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/8dfd07c6d2cf31c8da90c53b83c026c7696dda90", - "reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", "shasum": "" }, "require": { @@ -172,35 +223,34 @@ ], "support": { "issues": "https://github.com/DASPRiD/Enum/issues", - "source": "https://github.com/DASPRiD/Enum/tree/1.0.6" + "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" }, - "time": "2024-08-09T14:30:48+00:00" + "time": "2025-09-16T12:23:56+00:00" }, { "name": "dragonmantank/cron-expression", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "8c784d071debd117328803d86b2097615b457500" + "reference": "1b2de7f4a468165dca07b142240733a1973e766d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/8c784d071debd117328803d86b2097615b457500", - "reference": "8c784d071debd117328803d86b2097615b457500", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/1b2de7f4a468165dca07b142240733a1973e766d", + "reference": "1b2de7f4a468165dca07b142240733a1973e766d", "shasum": "" }, "require": { - "php": "^7.2|^8.0", - "webmozart/assert": "^1.0" + "php": "^7.2|^8.0" }, "replace": { "mtdowling/cron-expression": "^1.0" }, "require-dev": { - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0" + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.32|^2.1.31", + "phpunit/phpunit": "^8.5.48|^9.0" }, "type": "library", "extra": { @@ -231,7 +281,7 @@ ], "support": { "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.4.0" + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.5.0" }, "funding": [ { @@ -239,20 +289,20 @@ "type": "github" } ], - "time": "2024-10-09T13:47:03+00:00" + "time": "2025-10-31T18:36:32+00:00" }, { "name": "influxdata/influxdb-client-php", - "version": "3.6.0", + "version": "3.8.0", "source": { "type": "git", "url": "https://github.com/influxdata/influxdb-client-php.git", - "reference": "3606b12214508f22126b7ed0565d53380674312a" + "reference": "59ac11d63ce030973c79d5b05797813761a0d58e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/influxdata/influxdb-client-php/zipball/3606b12214508f22126b7ed0565d53380674312a", - "reference": "3606b12214508f22126b7ed0565d53380674312a", + "url": "https://api.github.com/repos/influxdata/influxdb-client-php/zipball/59ac11d63ce030973c79d5b05797813761a0d58e", + "reference": "59ac11d63ce030973c79d5b05797813761a0d58e", "shasum": "" }, "require": { @@ -287,22 +337,22 @@ ], "support": { "issues": "https://github.com/influxdata/influxdb-client-php/issues", - "source": "https://github.com/influxdata/influxdb-client-php/tree/3.6.0" + "source": "https://github.com/influxdata/influxdb-client-php/tree/3.8.0" }, - "time": "2024-06-24T10:01:53+00:00" + "time": "2025-06-26T05:12:59+00:00" }, { "name": "paragonie/constant_time_encoding", - "version": "v2.7.0", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105" + "reference": "e30811f7bc69e4b5b6d5783e712c06c8eabf0226" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/52a0d99e69f56b9ec27ace92ba56897fe6993105", - "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/e30811f7bc69e4b5b6d5783e712c06c8eabf0226", + "reference": "e30811f7bc69e4b5b6d5783e712c06c8eabf0226", "shasum": "" }, "require": { @@ -356,7 +406,7 @@ "issues": "https://github.com/paragonie/constant_time_encoding/issues", "source": "https://github.com/paragonie/constant_time_encoding" }, - "time": "2024-05-08T12:18:48+00:00" + "time": "2025-09-24T15:12:37+00:00" }, { "name": "php-http/client-common", @@ -738,21 +788,21 @@ }, { "name": "pragmarx/google2fa-qrcode", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/antonioribeiro/google2fa-qrcode.git", - "reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b" + "reference": "c23ebcc3a50de0d1566016a6dd1486e183bb78e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/antonioribeiro/google2fa-qrcode/zipball/ce4d8a729b6c93741c607cfb2217acfffb5bf76b", - "reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b", + "url": "https://api.github.com/repos/antonioribeiro/google2fa-qrcode/zipball/c23ebcc3a50de0d1566016a6dd1486e183bb78e1", + "reference": "c23ebcc3a50de0d1566016a6dd1486e183bb78e1", "shasum": "" }, "require": { "php": ">=7.1", - "pragmarx/google2fa": ">=4.0" + "pragmarx/google2fa": "^4.0|^5.0|^6.0|^7.0|^8.0" }, "require-dev": { "bacon/bacon-qr-code": "^2.0", @@ -799,9 +849,9 @@ ], "support": { "issues": "https://github.com/antonioribeiro/google2fa-qrcode/issues", - "source": "https://github.com/antonioribeiro/google2fa-qrcode/tree/v3.0.0" + "source": "https://github.com/antonioribeiro/google2fa-qrcode/tree/v3.0.1" }, - "time": "2021-08-15T12:53:48+00:00" + "time": "2025-09-19T23:02:26+00:00" }, { "name": "psr/cache", @@ -1487,7 +1537,7 @@ }, { "name": "symfony/polyfill-php73", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", @@ -1543,7 +1593,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.33.0" }, "funding": [ { @@ -1554,6 +1604,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -1563,16 +1617,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { @@ -1623,7 +1677,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" }, "funding": [ { @@ -1634,12 +1688,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2025-01-02T08:10:11+00:00" }, { "name": "symfony/service-contracts", @@ -1796,64 +1854,6 @@ } ], "time": "2024-09-25T14:11:13+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" } ], "packages-dev": [], @@ -1869,5 +1869,5 @@ "platform-overrides": { "php": "7.4" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } From d40cf1270f7b72605573ecdaee34f8f3147e0ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= <1536036+zoic21@users.noreply.github.com> Date: Wed, 26 Nov 2025 09:01:59 +0100 Subject: [PATCH 05/24] Fix changelog with 4.4.20 version inplace of 4.4.19 for emergency restore cli --- docs/fr_FR/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fr_FR/changelog.md b/docs/fr_FR/changelog.md index 70127b1bdb..b627fe88e9 100644 --- a/docs/fr_FR/changelog.md +++ b/docs/fr_FR/changelog.md @@ -95,4 +95,4 @@ >**IMPORTANT** > -> La restauration d'un backup 4.4 peut dans certains cas finir par des erreurs dans l'interface web. Rien de grave cela peut facilement se corriger il suffit de faire : `cd /tmp;wget https://github.com/jeedom/core/archive/refs/tags/4.4.19.zip;unzip 4.4.19.zip;cd core-4.4.19;cp -rf * /var/www/html/;rm -rf /tmp/master.zip;rm -rf /tmp/core-4.4.19;`. Vous pouvez lancer cette commande depuis l'interface rescue de jeedom (ajouter `&rescue=1` dans l'url), ou directement en ssh. +> La restauration d'un backup 4.4 peut dans certains cas finir par des erreurs dans l'interface web. Rien de grave cela peut facilement se corriger il suffit de faire : `cd /tmp;wget https://github.com/jeedom/core/archive/refs/tags/4.4.20.zip;unzip 4.4.19.zip;cd core-4.4.20;cp -rf * /var/www/html/;rm -rf /tmp/master.zip;rm -rf /tmp/core-4.4.20;`. Vous pouvez lancer cette commande depuis l'interface rescue de jeedom (ajouter `&rescue=1` dans l'url), ou directement en ssh. From 1b54d4d33ca2085db4754a083081bbfe90c75086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= <1536036+zoic21@users.noreply.github.com> Date: Wed, 26 Nov 2025 10:31:46 +0100 Subject: [PATCH 06/24] Fix warning https://community.jeedom.com/t/jeedom-4-5-une-version-plus-moderne-et-plus-fluide/144863/64 --- core/class/system.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/class/system.class.php b/core/class/system.class.php index af5962d3d7..347876791f 100644 --- a/core/class/system.class.php +++ b/core/class/system.class.php @@ -793,7 +793,7 @@ public static function installPackageInProgress($_plugin = ''): bool { } return true; } - if (shell_exec('ls /tmp/jeedom_install_in_progress* | wc -l') > 0) { + if (shell_exec('ls /tmp/jeedom_install_in_progress* | wc -l 2> /dev/null') > 0) { return true; } return false; @@ -918,4 +918,4 @@ public static function checkInstallationLog($_plugin = ''): string { } return ''; } -} \ No newline at end of file +} From ce98afe0b85d5179cfcfd471ea73c5e8436e8308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= <1536036+zoic21@users.noreply.github.com> Date: Wed, 26 Nov 2025 14:13:08 +0100 Subject: [PATCH 07/24] Fix trigger name issue when it's a scenario --- core/class/scenario.class.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/class/scenario.class.php b/core/class/scenario.class.php index 2b96c67bec..96e81124c7 100644 --- a/core/class/scenario.class.php +++ b/core/class/scenario.class.php @@ -912,16 +912,20 @@ public function execute($instance_id = '') { return; } } - $cmd = cmd::byId(str_replace('#', '', $this->getTag('trigger_id'))); - if (is_object($cmd)) { - log::add('event', 'info', __('Exécution du scénario', __FILE__) . ' ' . $this->getHumanName() . ' ' . __('déclenché par :', __FILE__) . ' ' . $cmd->getHumanName()); + if($this->getTag('trigger') == 'scenario'){ + $obj_trigger = scenario::byId(str_replace('#', '', $this->getTag('trigger_id'))); + }else{ + $obj_trigger = cmd::byId(str_replace('#', '', $this->getTag('trigger_id'))); + } + if (is_object($obj_trigger)) { + log::add('event', 'info', __('Exécution du scénario', __FILE__) . ' ' . $this->getHumanName() . ' ' . __('déclenché par :', __FILE__) . ' ' . $obj_trigger->getHumanName()); if ($this->getConfiguration('timeline::enable')) { $timeline = new timeline(); $timeline->setType('scenario'); $timeline->setFolder($this->getConfiguration('timeline::folder')); $timeline->setLink_id($this->getId()); $timeline->setName($this->getHumanName(true, true, true, true)); - $timeline->setOptions(array('trigger' => $cmd->getHumanName(true))); + $timeline->setOptions(array('trigger' => $obj_trigger->getHumanName(true))); $timeline->save(); } } else { From 1fa2b6cb2021c7597f49ef870e7ceb028297746c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= <1536036+zoic21@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:29:20 +0100 Subject: [PATCH 08/24] Fix 500 error on delete of some device https://community.jeedom.com/t/probleme-lors-de-la-suppression-dun-equipement/144928 --- core/ajax/eqLogic.ajax.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ajax/eqLogic.ajax.php b/core/ajax/eqLogic.ajax.php index 99f30677e3..b9479ebc2e 100644 --- a/core/ajax/eqLogic.ajax.php +++ b/core/ajax/eqLogic.ajax.php @@ -425,7 +425,7 @@ } if (count($cmdData['node']) > 0) { foreach ($cmdData['node'] as $name => $data) { - if (cmd::byId(str_replace('cmd', '', $data['id']))->getEqLogic_id() == $eqLogic->getId()) { + if (is_object(cmd::byId(str_replace('cmd', '', $data['id']))) && cmd::byId(str_replace('cmd', '', $data['id']))->getEqLogic_id() == $eqLogic->getId()) { continue; } From 7924aa852842ab9251645c04200430e4e222d0d4 Mon Sep 17 00:00:00 2001 From: Salvialf Date: Tue, 2 Dec 2025 11:07:29 +0100 Subject: [PATCH 09/24] init 4.5.1 --- core/config/version | 2 +- docs/fr_FR/changelog.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/config/version b/core/config/version index 958d30d86d..4404a17bae 100644 --- a/core/config/version +++ b/core/config/version @@ -1 +1 @@ -4.5 \ No newline at end of file +4.5.1 diff --git a/docs/fr_FR/changelog.md b/docs/fr_FR/changelog.md index b627fe88e9..4eff13863a 100644 --- a/docs/fr_FR/changelog.md +++ b/docs/fr_FR/changelog.md @@ -1,5 +1,9 @@ # Changelog Jeedom V4.5 +# 4.5.1 + + + # 4.5 - [Développeurs] Ajout de la fonction `$listener->removeEvent($_id)` From 50088ee77497518d3e250c308023c52e666fede7 Mon Sep 17 00:00:00 2001 From: Salvialf Date: Tue, 2 Dec 2025 11:17:41 +0100 Subject: [PATCH 10/24] bump nodejs to v22 --- docs/fr_FR/changelog.md | 2 +- resources/install_nodejs.sh | 38 ++++++++++++++++++------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/fr_FR/changelog.md b/docs/fr_FR/changelog.md index 4eff13863a..a126e34f98 100644 --- a/docs/fr_FR/changelog.md +++ b/docs/fr_FR/changelog.md @@ -2,7 +2,7 @@ # 4.5.1 - +- Montée de version de nodejs 20 vers 22 ([Détails](https://github.com/jeedom/core/issues/3147)) # 4.5 diff --git a/resources/install_nodejs.sh b/resources/install_nodejs.sh index 695498469e..c83ccc1d9f 100644 --- a/resources/install_nodejs.sh +++ b/resources/install_nodejs.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -installVer='20' #NodeJS major version to be installed -minVer='20' #min NodeJS major version to be accepted +installVer='22' #NodeJS major version to be installed +minVer='22' #min NodeJS major version to be accepted # vérifier si toujours nécessaire, cette source traine encore sur certaines smart et si une source est invalide -> nodejs ne s'installera pas if ls /etc/apt/sources.list.d/deb-multimedia.list* &>/dev/null; then @@ -53,8 +53,8 @@ lsb_release -c | grep jessie if [ $? -eq 0 ] then today=$(date +%Y%m%d) - if [[ "$today" > "20200630" ]]; - then + if [[ "$today" > "20200630" ]]; + then echo "== ATTENTION Debian 8 Jessie n'est officiellement plus supportée depuis le 30 juin 2020, merci de mettre à jour votre distribution !!!" exit 1 fi @@ -65,8 +65,8 @@ lsb_release -c | grep stretch if [ $? -eq 0 ] then today=$(date +%Y%m%d) - if [[ "$today" > "20220630" ]]; - then + if [[ "$today" > "20220630" ]]; + then echo "== ATTENTION Debian 9 Stretch n'est officiellement plus supportée depuis le 30 juin 2022, merci de mettre à jour votre distribution !!!" exit 1 fi @@ -77,8 +77,8 @@ lsb_release -c | grep buster if [ $? -eq 0 ] then today=$(date +%Y%m%d) - if [[ "$today" > "20220630" ]]; - then + if [[ "$today" > "20220630" ]]; + then echo "== ATTENTION Debian 10 Buster n'est officiellement plus supportée depuis le 30 juin 2024, merci de mettre à jour votre distribution !!!" exit 1 fi @@ -87,9 +87,9 @@ fi #x86 32 bits not supported by nodesource anymore bits=$(getconf LONG_BIT) if { [ "$arch" = "i386" ] || [ "$arch" = "i686" ]; } && [ "$bits" -eq "32" ] -then +then echo "== ATTENTION Votre système est x86 en 32bits et NodeJS 12 n'y est pas supporté, merci de passer en 64bits !!!" -exit 1 +exit 1 fi @@ -104,7 +104,7 @@ then else echo "[ KO ]"; echo "Installation de NodeJS $installVer" - + #if npm exists type npm &>/dev/null if [ $? -eq 0 ]; then @@ -112,10 +112,10 @@ else else npmPrefix="/usr" fi - + sudo DEBIAN_FRONTEND=noninteractive apt-get -y --purge autoremove npm &>/dev/null sudo DEBIAN_FRONTEND=noninteractive apt-get -y --purge autoremove nodejs &>/dev/null - + if [[ $arch == "armv6l" ]] then #version to install for armv6 (to check on https://unofficial-builds.nodejs.org) @@ -152,13 +152,13 @@ else sudo apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs fi - + npm config set prefix ${npmPrefix} &>/dev/null - if [ $(which node | wc -l) -ne 0 ] && [ $(which nodejs | wc -l) -eq 0 ]; then + if [ $(which node | wc -l) -ne 0 ] && [ $(which nodejs | wc -l) -eq 0 ]; then ln -s $(which node) $(which node)js fi - + new=`nodejs -v`; echo -n "[Check Version NodeJS après install : ${new} : " testVerAfter=$(php -r "echo version_compare('${new}','v${minVer}','>=');") @@ -173,7 +173,7 @@ fi type npm &>/dev/null if [ $? -ne 0 ]; then # Installation de npm car non présent (par sécu) - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y npm + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y npm sudo npm install -g npm fi @@ -183,7 +183,7 @@ if [ $? -eq 0 ]; then npmPrefixSudo=`sudo npm prefix -g` npmPrefixwwwData=`sudo -u www-data npm prefix -g` echo -n "[Check Prefix : $npmPrefix and sudo prefix : $npmPrefixSudo and www-data prefix : $npmPrefixwwwData : " - if [[ "$npmPrefixSudo" != "/usr" ]] && [[ "$npmPrefixSudo" != "/usr/local" ]]; then + if [[ "$npmPrefixSudo" != "/usr" ]] && [[ "$npmPrefixSudo" != "/usr/local" ]]; then echo "[ KO ]" if [[ "$npmPrefixwwwData" == "/usr" ]] || [[ "$npmPrefixwwwData" == "/usr/local" ]]; then echo "Reset prefix ($npmPrefixwwwData) pour npm `sudo whoami`" @@ -202,7 +202,7 @@ if [ $? -eq 0 ]; then sudo npm config set prefix /usr/local fi fi - fi + fi else if [[ "$npmPrefixwwwData" == "/usr" ]] || [[ "$npmPrefixwwwData" == "/usr/local" ]]; then if [[ "$npmPrefixwwwData" == "$npmPrefixSudo" ]]; then From b790b117796fff64f4181a6b83432d3b708f1693 Mon Sep 17 00:00:00 2001 From: Salvialf Date: Tue, 2 Dec 2025 11:40:42 +0100 Subject: [PATCH 11/24] typo --- docs/fr_FR/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fr_FR/changelog.md b/docs/fr_FR/changelog.md index a126e34f98..bea6d93bff 100644 --- a/docs/fr_FR/changelog.md +++ b/docs/fr_FR/changelog.md @@ -14,7 +14,7 @@ - Les graphiques se mettent à jour automatiquement lors de l'arrivée de nouvelles valeurs [LIEN](https://github.com/jeedom/core/issues/2749) - Jeedom ajoute automatiquement la hauteur de l'image lors de la création des widgets pour éviter les soucis de chevauchement en mobile [LIEN](https://github.com/jeedom/core/issues/2539) - Refonte de la partie backup cloud [LIEN](https://github.com/jeedom/core/issues/2765) -- **DEV** Mise en place d'un système de queue pour l'exécution d'actions [LIEN](https://github.com/jeedom/core/issues/2489) +- [Développeurs] Mise en place d'un système de queue pour l'exécution d'actions [LIEN](https://github.com/jeedom/core/issues/2489) - Les tags des scénarios sont maintenant propres à l'instance du scénario (si vous avez deux lancements de scénarios très proches, les tags du dernier n'écrasent plus le premier) [LIEN](https://github.com/jeedom/core/issues/2763) - Changement sur la partie trigger des scénarios : [LIEN](https://github.com/jeedom/core/issues/2414) - ``triggerId()`` est maintenant deprecated et sera retiré dans les futures mises à jour du core. Si vous avez ``triggerId() == 587`` il faut le remplacer par ``#trigger_id# == 587`` From 08a2f4d6888066e3ea6abb42acb4d28dbb935675 Mon Sep 17 00:00:00 2001 From: Salvialf Date: Tue, 2 Dec 2025 15:17:17 +0100 Subject: [PATCH 12/24] typo trigger_value --- docs/fr_FR/scenario.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fr_FR/scenario.md b/docs/fr_FR/scenario.md index e002eafb7c..13d3c0d1e0 100644 --- a/docs/fr_FR/scenario.md +++ b/docs/fr_FR/scenario.md @@ -439,7 +439,7 @@ Une boîte à outils de fonctions génériques peut également servir à effectu - ``randText(texte1;texte2;texte…​..)`` : Permet de retourner un des textes aléatoirement (séparer les texte par un ; ). Il n’y a pas de limite dans le nombre de texte. - ``randomColor(min,max)`` : Donne une couleur aléatoire comprise entre 2 bornes ( 0 => rouge, 50 => vert, 100 => bleu). - ``trigger(commande)`` : Permet de connaître le déclencheur du scénario ou de savoir si c’est bien la commande passée en paramètre qui a déclenché le scénario. **=> Deprecated il vaut mieux utiliser le tag #trigger#** -- ``triggerValue()`` : Permet de connaître la valeur du déclencheur du scénario. **=> Deprecated il vaut mieux utiliser le tag #triggerValue#** +- ``triggerValue()`` : Permet de connaître la valeur du déclencheur du scénario. **=> Deprecated il vaut mieux utiliser le tag #trigger_value#** - ``round(valeur,[decimal])`` : Donne un arrondi au-dessus, [decimal] nombre de décimales après la virgule. - ``odd(valeur)`` : Permet de savoir si un nombre est impair ou non. Renvoie 1 si impair 0 sinon. - ``median(commande1,commande2…​.commandeN)`` : Renvoie la médiane des valeurs. From ea2acccb97b4c4051559fb5d42f4012e3fa28768 Mon Sep 17 00:00:00 2001 From: Salvialf Date: Sat, 6 Dec 2025 13:59:39 +0100 Subject: [PATCH 13/24] typo changelog --- docs/fr_FR/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fr_FR/changelog.md b/docs/fr_FR/changelog.md index bea6d93bff..4c4c0cfbc5 100644 --- a/docs/fr_FR/changelog.md +++ b/docs/fr_FR/changelog.md @@ -99,4 +99,4 @@ >**IMPORTANT** > -> La restauration d'un backup 4.4 peut dans certains cas finir par des erreurs dans l'interface web. Rien de grave cela peut facilement se corriger il suffit de faire : `cd /tmp;wget https://github.com/jeedom/core/archive/refs/tags/4.4.20.zip;unzip 4.4.19.zip;cd core-4.4.20;cp -rf * /var/www/html/;rm -rf /tmp/master.zip;rm -rf /tmp/core-4.4.20;`. Vous pouvez lancer cette commande depuis l'interface rescue de jeedom (ajouter `&rescue=1` dans l'url), ou directement en ssh. +> La restauration d'un backup 4.4 peut dans certains cas finir par des erreurs dans l'interface web. Rien de grave cela peut facilement se corriger il suffit de faire : `cd /tmp;wget https://github.com/jeedom/core/archive/refs/tags/4.4.20.zip;unzip 4.4.20.zip;cd core-4.4.20;cp -rf * /var/www/html/;rm -rf /tmp/master.zip;rm -rf /tmp/core-4.4.20;`. Vous pouvez lancer cette commande depuis l'interface rescue de jeedom (ajouter `&rescue=1` dans l'url), ou directement en ssh. From 1a7fa51b591708fe4ecddbb10e52bc3895347709 Mon Sep 17 00:00:00 2001 From: Salvialf Date: Thu, 11 Dec 2025 09:54:28 +0100 Subject: [PATCH 14/24] fix cd485a0 --- core/class/cmd.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/class/cmd.class.php b/core/class/cmd.class.php index 655509c8fb..c667a6fc09 100644 --- a/core/class/cmd.class.php +++ b/core/class/cmd.class.php @@ -1042,10 +1042,10 @@ public function formatValue($_value, $_quote = false) { return intval($binary xor boolval($this->getConfiguration('invertBinary', false))); case 'numeric': if ($this->getConfiguration('historizeRound') !== '' && is_numeric($this->getConfiguration('historizeRound')) && $this->getConfiguration('historizeRound') >= 0) { - if (!is_numeric($_value)) { - log::add('cmd', 'error', __('La formule de calcul doit retourner une valeur numérique uniquement : ', __FILE__) . $this->getHumanName() . ' => ' . $_value); - $_value = (float) (str_replace(',', '.', $_value)); - } + if (!is_numeric($_value)) { + log::add('cmd', 'error', __('La formule de calcul doit retourner une valeur numérique uniquement : ', __FILE__) . $this->getHumanName() . ' => ' . $_value); + $_value = (float) (str_replace(',', '.', $_value)); + } $_value = round($_value, $this->getConfiguration('historizeRound')); } if ($_value > $this->getConfiguration('maxValue', $_value)) { @@ -3070,8 +3070,8 @@ public function getDisplay($_key = '', $_default = '') { return utils::getJsonAttr($this->display, $_key, $_default); } - public function setDisplay($_key, $_value = null) { - if ($this->getDisplay($_key,null) !== $_value) { + public function setDisplay($_key, $_value) { + if ($this->getDisplay($_key, null) !== $_value) { $this->_needRefreshWidget = true; $this->_changed = true; } From 7815619a7a524dc2d766c13c466da430660fcf7b Mon Sep 17 00:00:00 2001 From: Salvialf Date: Sat, 13 Dec 2025 19:40:23 +0100 Subject: [PATCH 15/24] code format --- core/class/scenarioExpression.class.php | 76 ++++++++++++------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/core/class/scenarioExpression.class.php b/core/class/scenarioExpression.class.php index 952352df20..d58875ca5a 100644 --- a/core/class/scenarioExpression.class.php +++ b/core/class/scenarioExpression.class.php @@ -194,17 +194,17 @@ public static function getDatesFromPeriod($_period = '1 hour') { if ($_period == 'day') $_period = '1 day'; if (ctype_digit($_period[0]) && !stristr($_period, "ago")) { - $_startTime = date('Y-m-d H:i:s',(int) strtotime('-' . $_period)); + $_startTime = date('Y-m-d H:i:s', (int) strtotime('-' . $_period)); } else { - $_startTime = date('Y-m-d H:i:s',(int) strtotime($_period)); + $_startTime = date('Y-m-d H:i:s', (int) strtotime($_period)); } $_endTime = date('Y-m-d H:i:s'); if ($_period == 'today') { $_startTime = date('Y-m-d') . ' 00:00:00'; } elseif ($_period == 'yesterday') { - $_startTime = date('Y-m-d',(int) strtotime('-1 day')) . ' 00:00:00'; - $_endTime = date('Y-m-d',(int) strtotime('-1 day')) . ' 23:59:59'; + $_startTime = date('Y-m-d', (int) strtotime('-1 day')) . ' 00:00:00'; + $_endTime = date('Y-m-d', (int) strtotime('-1 day')) . ' 23:59:59'; } return array($_startTime, $_endTime); } @@ -303,8 +303,8 @@ public static function averageBetween($_cmd_id, $_startDate, $_endDate, $_round if (!is_object($cmd) || $cmd->getIsHistorized() == 0) { return ''; } - $_startTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_startDate))); - $_endTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_endDate))); + $_startTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_startDate))); + $_endTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_endDate))); $historyStatistique = $cmd->getStatistique($_startTime, $_endTime); if (!isset($historyStatistique['avg'])) { return ''; @@ -328,8 +328,8 @@ public static function averageTemporalBetween($_cmd_id, $_startDate, $_endDate, if (!is_object($cmd) || $cmd->getIsHistorized() == 0) { return ''; } - $_startTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_startDate))); - $_endTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_endDate))); + $_startTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_startDate))); + $_endTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_endDate))); return round($cmd->getTemporalAvg($_startTime, $_endTime), $_round); } @@ -458,8 +458,8 @@ public static function maxBetween($_cmd_id, $_startDate, $_endDate, $_round = 1) if (!is_object($cmd) || $cmd->getIsHistorized() == 0) { return ''; } - $_startTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_startDate))); - $_endTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_endDate))); + $_startTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_startDate))); + $_endTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_endDate))); $historyStatistique = $cmd->getStatistique($_startTime, $_endTime); if (!isset($historyStatistique['max'])) { return ''; @@ -489,8 +489,8 @@ public static function minBetween($_cmd_id, $_startDate, $_endDate, $_round = 1) if (!is_object($cmd) || $cmd->getIsHistorized() == 0) { return ''; } - $_startTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_startDate))); - $_endTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_endDate))); + $_startTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_startDate))); + $_endTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_endDate))); $historyStatistique = $cmd->getStatistique($_startTime, $_endTime); if (!isset($historyStatistique['min'])) { return ''; @@ -642,8 +642,8 @@ public static function stateChangesBetween($_cmd_id, $_value, $_startDate, $_end $_endDate = func_get_arg(2); $_value = null; } - $_startTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_startDate))); - $_endTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_endDate))); + $_startTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_startDate))); + $_endTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_endDate))); return history::stateChanges($cmd_id, $_value, $_startTime, $_endTime); } @@ -724,8 +724,8 @@ public static function durationBetween($_cmd_id, $_value, $_startDate, $_endDate $_endDate = date('Y-m-d H:i:s'); } - $_startTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_startDate))); - $_endTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_endDate))); + $_startTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_startDate))); + $_endTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_endDate))); $_value = str_replace(',', '.', $_value); $_decimal = strlen(substr(strrchr($_value, "."), 1)); @@ -769,8 +769,8 @@ public static function lastBetween($_cmd_id, $_startDate, $_endDate) { if (!is_object($cmd) || $cmd->getIsHistorized() == 0) { return ''; } - $_startTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_startDate))); - $_endTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_endDate))); + $_startTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_startDate))); + $_endTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_endDate))); $historyStatistique = $cmd->getStatistique($_startTime, $_endTime); if (!isset($historyStatistique['last']) || $historyStatistique['last'] === '') { return ''; @@ -802,8 +802,8 @@ public static function statisticsBetween($_cmd_id, $_calc, $_startDate, $_endDat return ''; } $_calc = str_replace(' ', '', $_calc); - $_startTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_startDate))); - $_endTime = date('Y-m-d H:i:s',(int) strtotime(self::setTags($_endDate))); + $_startTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_startDate))); + $_endTime = date('Y-m-d H:i:s', (int) strtotime(self::setTags($_endDate))); $historyStatistique = $cmd->getStatistique(self::setTags($_startTime), self::setTags($_endTime)); return $historyStatistique[$_calc]; } @@ -960,7 +960,7 @@ public static function trigger($_name = '', &$_scenario = null) { if (trim($_name) == '') { return $_scenario->getTag('trigger_name'); } - if (trim(jeedom::toHumanReadable($_name),'#') == $_scenario->getTag('trigger_name')) { + if (trim(jeedom::toHumanReadable($_name), '#') == $_scenario->getTag('trigger_name')) { return 1; } return 0; @@ -1038,8 +1038,8 @@ public static function time_diff($_date1, $_date2, $_format = 'd', $_rnd = 2) { if ($_date2 < 100) $_date2 = '00' . $_date2; if ($_date2 < 1000) $_date2 = '0' . $_date2; } - $d1 = str_replace(array('"','\'',"'"), '', self::setTags($_date1)); - $d2 = str_replace(array('"','\'',"'"), '', self::setTags($_date2)); + $d1 = str_replace(array('"', '\'', "'"), '', self::setTags($_date1)); + $d2 = str_replace(array('"', '\'', "'"), '', self::setTags($_date2)); $date1 = new DateTime($d1); $date2 = new DateTime($d2); $duree = $date2->getTimestamp() - $date1->getTimestamp(); @@ -1386,7 +1386,7 @@ public function execute(&$scenario = null) { } $this->checkBackground(); if ($this->getOptions('background', 0) == 1) { - $key = 'scenarioElement'.$this->getId().'::' . config::genKey(16).'::'.strtotime('now'); + $key = 'scenarioElement' . $this->getId() . '::' . config::genKey(16) . '::' . strtotime('now'); cache::set($key, array('scenarioExpression' => $this, 'scenario' => $scenario), 60); $cmd = __DIR__ . '/../php/jeeScenarioExpression.php'; $cmd .= ' key=' . $key; @@ -1571,14 +1571,14 @@ public function execute(&$scenario = null) { } $this->setLog($scenario, $GLOBALS['JEEDOM_SCLOG_TEXT']['launchScenario']['txt'] . $actionScenario->getName() . ' ' . __('options :', __FILE__) . ' ' . json_encode($actionScenario->getTags())); if ($scenario !== null) { - $actionScenario->addTag('trigger','scenario'); - $actionScenario->addTag('trigger_message',$GLOBALS['JEEDOM_SCLOG_TEXT']['startByScenario']['txt'] . $scenario->getHumanName()); - $actionScenario->addTag('trigger_name',trim($scenario->getHumanName(),'#')); - $actionScenario->addTag('trigger_id',$scenario->getId()); + $actionScenario->addTag('trigger', 'scenario'); + $actionScenario->addTag('trigger_message', $GLOBALS['JEEDOM_SCLOG_TEXT']['startByScenario']['txt'] . $scenario->getHumanName()); + $actionScenario->addTag('trigger_name', trim($scenario->getHumanName(), '#')); + $actionScenario->addTag('trigger_id', $scenario->getId()); return $actionScenario->launch(); } else { - $actionScenario->addTag('trigger','other'); - $actionScenario->addTag('trigger_message',$GLOBALS['JEEDOM_SCLOG_TEXT']['startCausedBy']['txt']); + $actionScenario->addTag('trigger', 'other'); + $actionScenario->addTag('trigger_message', $GLOBALS['JEEDOM_SCLOG_TEXT']['startCausedBy']['txt']); return $actionScenario->launch(); } break; @@ -1597,14 +1597,14 @@ public function execute(&$scenario = null) { } $this->setLog($scenario, $GLOBALS['JEEDOM_SCLOG_TEXT']['launchScenario']['txt'] . $actionScenario->getName() . ' ' . __('options :', __FILE__) . ' ' . json_encode($actionScenario->getTags())); if ($scenario !== null) { - $actionScenario->addTag('trigger','scenario'); - $actionScenario->addTag('trigger_message',$GLOBALS['JEEDOM_SCLOG_TEXT']['startByScenario']['txt'] . $scenario->getHumanName()); - $actionScenario->addTag('trigger_name',trim($scenario->getHumanName(),'#')); - $actionScenario->addTag('trigger_id',$scenario->getId()); + $actionScenario->addTag('trigger', 'scenario'); + $actionScenario->addTag('trigger_message', $GLOBALS['JEEDOM_SCLOG_TEXT']['startByScenario']['txt'] . $scenario->getHumanName()); + $actionScenario->addTag('trigger_name', trim($scenario->getHumanName(), '#')); + $actionScenario->addTag('trigger_id', $scenario->getId()); return $actionScenario->launch(true); } else { - $actionScenario->addTag('trigger','other'); - $actionScenario->addTag('trigger_message',$GLOBALS['JEEDOM_SCLOG_TEXT']['startCausedBy']['txt']); + $actionScenario->addTag('trigger', 'other'); + $actionScenario->addTag('trigger_message', $GLOBALS['JEEDOM_SCLOG_TEXT']['startCausedBy']['txt']); return $actionScenario->launch(true); } break; @@ -1791,8 +1791,8 @@ public function execute(&$scenario = null) { $tmp_file = jeedom::getTmpFolder('history_export') . '/' . $options['name'] . '.csv'; $cmd_parameters = array('files' => [$tmp_file], 'title' => $options['name'], 'message' => $options['name']); - $start = date('Y-m-d H:i:s',(int) strtotime($options['start'])); - $end = date('Y-m-d H:i:s',(int) strtotime($options['end'])); + $start = date('Y-m-d H:i:s', (int) strtotime($options['start'])); + $end = date('Y-m-d H:i:s', (int) strtotime($options['end'])); $this->setLog($scenario, __('Export de l\'historique du', __FILE__) . ' ' . $start . ' ' . __('au', __FILE__) . ' ' . $end); $histories = array(); From c2e061ef7373a09e0d03e2c63b876cd70278c99b Mon Sep 17 00:00:00 2001 From: Salvialf Date: Sat, 13 Dec 2025 19:40:42 +0100 Subject: [PATCH 16/24] $value must be a string --- core/class/scenarioExpression.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/core/class/scenarioExpression.class.php b/core/class/scenarioExpression.class.php index d58875ca5a..7fa2e9e653 100644 --- a/core/class/scenarioExpression.class.php +++ b/core/class/scenarioExpression.class.php @@ -1275,6 +1275,7 @@ public static function setTags(&$_expression, &$_scenario = null, $_quote = fals } if ($_quote) { foreach ($replace1 as &$value) { + $value = (string)$value; if (strpos($value, ' ') !== false || preg_match("/[a-zA-Z]/", $value) || $value === '') { $value = '"' . trim($value, '"') . '"'; } From e416ee5726f8c326f5780a14b4894c0e4c89bfdb Mon Sep 17 00:00:00 2001 From: Salvialf Date: Sat, 13 Dec 2025 20:38:30 +0100 Subject: [PATCH 17/24] improve color picker --- core/template/dashboard/cmd.action.color.picker.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/template/dashboard/cmd.action.color.picker.html b/core/template/dashboard/cmd.action.color.picker.html index 3c4bf73cca..62d1f17f5a 100644 --- a/core/template/dashboard/cmd.action.color.picker.html +++ b/core/template/dashboard/cmd.action.color.picker.html @@ -19,7 +19,13 @@ if ('#time#' == 'duration' || '#time#' == 'date') { jeedom.cmd.displayDuration(_options.valueDate, cmd.querySelector('.timeCmd'), '#time#') } - cmd.querySelector('.action_colorpicker_change').value = (_options.display_value != '') ? _options.display_value.substr(0, 7) : '#000000' + if (_options.display_value.length == 0) { + cmd.querySelector('.action_colorpicker_change').value = '#000000' + } else if (_options.display_value.startsWith('#')) { + cmd.querySelector('.action_colorpicker_change').value = _options.display_value.substr(0, 7) + } else { + cmd.querySelector('.action_colorpicker_change').value = '#' + _options.display_value.substr(0, 6) + } } }) From 476da3ce34c008ac726cc2410b0472c01404faf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= <1536036+zoic21@users.noreply.github.com> Date: Tue, 16 Dec 2025 09:13:45 +0100 Subject: [PATCH 18/24] Fix random backup hour --- install/consistency.php | 625 ++++++++++++++++++++-------------------- 1 file changed, 312 insertions(+), 313 deletions(-) diff --git a/install/consistency.php b/install/consistency.php index 3d3907538a..f432e2964d 100644 --- a/install/consistency.php +++ b/install/consistency.php @@ -128,333 +128,332 @@ if (is_object($cron)) { $cron->remove(); } - if (method_exists('utils', 'attrChanged')) { - $cron = cron::byClassAndFunction('plugin', 'cronDaily'); - if (!is_object($cron)) { - echo "Create plugin::cronDaily\n"; - $cron = new cron(); - } - $cron->setClass('plugin'); - $cron->setFunction('cronDaily'); - $cron->setSchedule('00 00 * * *'); - $cron->setTimeout(240); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('jeedom', 'backup'); - if (!is_object($cron)) { - echo "Create jeedom::backup\n"; - $cron = new cron(); - $cron->setClass('jeedom'); - $cron->setFunction('backup'); - $cron->setSchedule(rand(10, 59) . ' 0' . rand(0, 7) . ' * * *'); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->setTimeout(60); - $cron->save(); - } - - $cron = cron::byClassAndFunction('plugin', 'cronHourly'); - if (!is_object($cron)) { - echo "Create plugin::cronHourly\n"; - $cron = new cron(); - } - $cron->setClass('plugin'); - $cron->setFunction('cronHourly'); - $cron->setSchedule('00 * * * *'); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->setTimeout(60); - $cron->save(); - - $cron = cron::byClassAndFunction('scenario', 'check'); - if (!is_object($cron)) { - echo "Create scenario::check\n"; - $cron = new cron(); - } - $cron->setClass('scenario'); - $cron->setFunction('check'); - $cron->setSchedule('* * * * *'); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->setTimeout(30); - $cron->save(); - - $cron = cron::byClassAndFunction('scenario', 'control'); - if (!is_object($cron)) { - echo "Create scenario::control\n"; - $cron = new cron(); - } - $cron->setClass('scenario'); - $cron->setFunction('control'); - $cron->setSchedule('* * * * *'); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->setTimeout(30); - $cron->save(); - - $cron = cron::byClassAndFunction('jeedom', 'cronDaily'); - if (!is_object($cron)) { - echo "Create jeedom::cronDaily\n"; - $cron = new cron(); - } - $cron->setClass('jeedom'); - $cron->setFunction('cronDaily'); - $cron->setSchedule(rand(0, 59) . ' ' . rand(0, 3) . ' * * *'); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->setTimeout(240); - $cron->save(); - - $cron = cron::byClassAndFunction('jeedom', 'cronHourly'); - if (!is_object($cron)) { - echo "Create jeedom::cronHourly\n"; - $cron = new cron(); - } - $cron->setClass('jeedom'); - $cron->setFunction('cronHourly'); - $cron->setSchedule(rand(0, 59) . ' * * * *'); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->setTimeout(60); - $cron->save(); - - $cron = cron::byClassAndFunction('jeedom', 'cron5'); - if (!is_object($cron)) { - echo "Create jeedom::cron5\n"; - $cron = new cron(); - } - $cron->setClass('jeedom'); - $cron->setFunction('cron5'); - $cron->setSchedule('*/5 * * * *'); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->setTimeout(5); - $cron->save(); - - $cron = cron::byClassAndFunction('jeedom', 'cron10'); - if (!is_object($cron)) { - echo "Create jeedom::cron10\n"; - $cron = new cron(); - } - $cron->setClass('jeedom'); - $cron->setFunction('cron10'); - $cron->setSchedule('*/10 * * * *'); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->setTimeout(10); - $cron->save(); - - $cron = cron::byClassAndFunction('jeedom', 'cron'); - if (!is_object($cron)) { - echo "Create jeedom::cron\n"; - $cron = new cron(); - } - $cron->setClass('jeedom'); - $cron->setFunction('cron'); - $cron->setSchedule('* * * * *'); - $cron->setTimeout(2); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('plugin', 'cron'); - if (!is_object($cron)) { - echo "Create plugin::cron\n"; - $cron = new cron(); - } - $cron->setClass('plugin'); - $cron->setFunction('cron'); - $cron->setSchedule('* * * * *'); - $cron->setTimeout(2); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('queue', 'cron'); - if (!is_object($cron)) { - echo "Create queue::cron\n"; - $cron = new cron(); - } - $cron->setClass('queue'); - $cron->setFunction('cron'); - $cron->setSchedule('* * * * *'); - $cron->setTimeout(2); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('plugin', 'cron5'); - if (!is_object($cron)) { - echo "Create plugin::cron5\n"; - $cron = new cron(); - } - $cron->setClass('plugin'); - $cron->setFunction('cron5'); - $cron->setSchedule('*/5 * * * *'); - $cron->setTimeout(5); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('plugin', 'cron10'); - if (!is_object($cron)) { - echo "Create plugin::cron10\n"; - $cron = new cron(); - } - $cron->setClass('plugin'); + $cron = cron::byClassAndFunction('plugin', 'cronDaily'); + if (!is_object($cron)) { + echo "Create plugin::cronDaily\n"; + $cron = new cron(); + } + $cron->setClass('plugin'); + $cron->setFunction('cronDaily'); + $cron->setSchedule('00 00 * * *'); + $cron->setTimeout(240); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('jeedom', 'backup'); + if (!is_object($cron)) { + echo "Create jeedom::backup\n"; + $cron = new cron(); + } + $cron->setClass('jeedom'); + $cron->setFunction('backup'); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->setTimeout(60); + $cron->setSchedule(rand(10, 59) . ' 0' . rand(0, 9) . ' * * *'); + $cron->save(); + + $cron = cron::byClassAndFunction('plugin', 'cronHourly'); + if (!is_object($cron)) { + echo "Create plugin::cronHourly\n"; + $cron = new cron(); + } + $cron->setClass('plugin'); + $cron->setFunction('cronHourly'); + $cron->setSchedule('00 * * * *'); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->setTimeout(60); + $cron->save(); + + $cron = cron::byClassAndFunction('scenario', 'check'); + if (!is_object($cron)) { + echo "Create scenario::check\n"; + $cron = new cron(); + } + $cron->setClass('scenario'); + $cron->setFunction('check'); + $cron->setSchedule('* * * * *'); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->setTimeout(30); + $cron->save(); + + $cron = cron::byClassAndFunction('scenario', 'control'); + if (!is_object($cron)) { + echo "Create scenario::control\n"; + $cron = new cron(); + } + $cron->setClass('scenario'); + $cron->setFunction('control'); + $cron->setSchedule('* * * * *'); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->setTimeout(30); + $cron->save(); + + $cron = cron::byClassAndFunction('jeedom', 'cronDaily'); + if (!is_object($cron)) { + echo "Create jeedom::cronDaily\n"; + $cron = new cron(); + } + $cron->setClass('jeedom'); + $cron->setFunction('cronDaily'); + $cron->setSchedule(rand(0, 59) . ' ' . rand(0, 3) . ' * * *'); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->setTimeout(240); + $cron->save(); + + $cron = cron::byClassAndFunction('jeedom', 'cronHourly'); + if (!is_object($cron)) { + echo "Create jeedom::cronHourly\n"; + $cron = new cron(); + } + $cron->setClass('jeedom'); + $cron->setFunction('cronHourly'); + $cron->setSchedule(rand(0, 59) . ' * * * *'); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->setTimeout(60); + $cron->save(); + + $cron = cron::byClassAndFunction('jeedom', 'cron5'); + if (!is_object($cron)) { + echo "Create jeedom::cron5\n"; + $cron = new cron(); + } + $cron->setClass('jeedom'); + $cron->setFunction('cron5'); + $cron->setSchedule('*/5 * * * *'); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->setTimeout(5); + $cron->save(); + + $cron = cron::byClassAndFunction('jeedom', 'cron10'); + if (!is_object($cron)) { + echo "Create jeedom::cron10\n"; + $cron = new cron(); + } + $cron->setClass('jeedom'); + $cron->setFunction('cron10'); + $cron->setSchedule('*/10 * * * *'); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->setTimeout(10); + $cron->save(); + + $cron = cron::byClassAndFunction('jeedom', 'cron'); + if (!is_object($cron)) { + echo "Create jeedom::cron\n"; + $cron = new cron(); + } + $cron->setClass('jeedom'); + $cron->setFunction('cron'); + $cron->setSchedule('* * * * *'); + $cron->setTimeout(2); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('plugin', 'cron'); + if (!is_object($cron)) { + echo "Create plugin::cron\n"; + $cron = new cron(); + } + $cron->setClass('plugin'); + $cron->setFunction('cron'); + $cron->setSchedule('* * * * *'); + $cron->setTimeout(2); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('queue', 'cron'); + if (!is_object($cron)) { + echo "Create queue::cron\n"; + $cron = new cron(); + } + $cron->setClass('queue'); + $cron->setFunction('cron'); + $cron->setSchedule('* * * * *'); + $cron->setTimeout(2); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('plugin', 'cron5'); + if (!is_object($cron)) { + echo "Create plugin::cron5\n"; + $cron = new cron(); + } + $cron->setClass('plugin'); + $cron->setFunction('cron5'); + $cron->setSchedule('*/5 * * * *'); + $cron->setTimeout(5); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('plugin', 'cron10'); + if (!is_object($cron)) { + echo "Create plugin::cron10\n"; + $cron = new cron(); + } + $cron->setClass('plugin'); + $cron->setFunction('cron10'); + $cron->setSchedule('*/10 * * * *'); + $cron->setTimeout(10); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('plugin', 'cron15'); + if (!is_object($cron)) { + echo "Create plugin::cron15\n"; + $cron = new cron(); + } + $cron->setClass('plugin'); + $cron->setFunction('cron15'); + $cron->setSchedule('*/15 * * * *'); + $cron->setTimeout(15); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('plugin', 'cron30'); + if (!is_object($cron)) { + echo "Create plugin::cron30\n"; + $cron = new cron(); + } + $cron->setClass('plugin'); + $cron->setFunction('cron30'); + $cron->setSchedule('*/30 * * * *'); + $cron->setTimeout(30); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('plugin', 'checkDeamon'); + if (!is_object($cron)) { + echo "Create plugin::checkDeamon\n"; + $cron = new cron(); + } + $cron->setClass('plugin'); + $cron->setFunction('checkDeamon'); + $cron->setSchedule('*/5 * * * *'); + $cron->setTimeout(5); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('cache', 'persist'); + if (!is_object($cron)) { + echo "Create cache::persist\n"; + $cron = new cron(); + } + $cron->setClass('cache'); + $cron->setFunction('persist'); + $cron->setSchedule('*/30 * * * *'); + $cron->setTimeout(30); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('history', 'archive'); + if (!is_object($cron)) { + echo "Create history::archive\n"; + $cron = new cron(); + } + $cron->setClass('history'); + $cron->setFunction('archive'); + $cron->setSchedule('00 5 * * *'); + $cron->setTimeout(240); + $cron->setDeamon(0); + $cron->save(); + + $cron = cron::byClassAndFunction('plugin', 'heartbeat'); + if (!is_object($cron)) { + echo "Create plugin::heartbeat\n"; + $cron = new cron(); + } + $cron->setClass('plugin'); + $cron->setFunction('heartbeat'); + $cron->setSchedule('*/5 * * * *'); + $cron->setEnable(1); + $cron->setDeamon(0); + $cron->setTimeout(10); + $cron->save(); + + $cron = cron::byClassAndFunction('network', 'cron10'); + if (!is_object($cron)) { + echo "Create network::cron10\n"; + $cron = new cron(); + $cron->setClass('network'); $cron->setFunction('cron10'); - $cron->setSchedule('*/10 * * * *'); - $cron->setTimeout(10); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('plugin', 'cron15'); - if (!is_object($cron)) { - echo "Create plugin::cron15\n"; - $cron = new cron(); - } - $cron->setClass('plugin'); - $cron->setFunction('cron15'); - $cron->setSchedule('*/15 * * * *'); - $cron->setTimeout(15); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('plugin', 'cron30'); - if (!is_object($cron)) { - echo "Create plugin::cron30\n"; - $cron = new cron(); - } - $cron->setClass('plugin'); - $cron->setFunction('cron30'); - $cron->setSchedule('*/30 * * * *'); - $cron->setTimeout(30); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('plugin', 'checkDeamon'); - if (!is_object($cron)) { - echo "Create plugin::checkDeamon\n"; - $cron = new cron(); - } - $cron->setClass('plugin'); - $cron->setFunction('checkDeamon'); - $cron->setSchedule('*/5 * * * *'); - $cron->setTimeout(5); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('cache', 'persist'); - if (!is_object($cron)) { - echo "Create cache::persist\n"; - $cron = new cron(); - } - $cron->setClass('cache'); - $cron->setFunction('persist'); - $cron->setSchedule('*/30 * * * *'); - $cron->setTimeout(30); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('history', 'archive'); - if (!is_object($cron)) { - echo "Create history::archive\n"; - $cron = new cron(); + $rand_min = rand(0,9); + $cronString = ''; + for($i=0;$i<6;$i++){ + $cronString .= ($rand_min+($i*10)).','; } - $cron->setClass('history'); - $cron->setFunction('archive'); - $cron->setSchedule('00 5 * * *'); - $cron->setTimeout(240); - $cron->setDeamon(0); - $cron->save(); - - $cron = cron::byClassAndFunction('plugin', 'heartbeat'); - if (!is_object($cron)) { - echo "Create plugin::heartbeat\n"; - $cron = new cron(); - } - $cron->setClass('plugin'); - $cron->setFunction('heartbeat'); - $cron->setSchedule('*/5 * * * *'); + $cronString = trim($cronString,',').' * * * *'; + $cron->setSchedule($cronString); $cron->setEnable(1); $cron->setDeamon(0); - $cron->setTimeout(10); + $cron->setTimeout(60); $cron->save(); + } - $cron = cron::byClassAndFunction('network', 'cron10'); - if (!is_object($cron)) { - echo "Create network::cron10\n"; - $cron = new cron(); - $cron->setClass('network'); - $cron->setFunction('cron10'); - $rand_min = rand(0,9); - $cronString = ''; - for($i=0;$i<6;$i++){ - $cronString .= ($rand_min+($i*10)).','; - } - $cronString = trim($cronString,',').' * * * *'; - $cron->setSchedule($cronString); - $cron->setEnable(1); - $cron->setDeamon(0); - $cron->setTimeout(60); - $cron->save(); - } + if (!file_exists(__DIR__ . '/../plugins')) { + mkdir(__DIR__ . '/../plugins'); + } + try { + echo "\nCheck filesystem right..."; + jeedom::cleanFileSystemRight(); + echo "OK\n"; + } catch (Exception $e) { + echo "NOK\n"; + } - if (!file_exists(__DIR__ . '/../plugins')) { - mkdir(__DIR__ . '/../plugins'); - } + config::save('hardware_name', ''); + if (config::byKey('api') == '') { + echo "Fix default apikey...\n"; + config::save('api', config::genKey()); + } + if (file_exists(__DIR__ . '/../core/nodeJS')) { + echo "Remove unused nodejs folder...\n"; + shell_exec(system::getCmdSudo() . 'rm -rf ' . __DIR__ . '/../core/nodeJS'); + } + if (file_exists(__DIR__ . '/../script/ngrok')) { + echo "Remove unused ngrok folder...\n"; + shell_exec(system::getCmdSudo() . 'rm -rf ' . __DIR__ . '/../script/ngrok'); + } + + echo "Check jeedom object..."; + foreach (jeeObject::all() as $object) { try { - echo "\nCheck filesystem right..."; - jeedom::cleanFileSystemRight(); - echo "OK\n"; - } catch (Exception $e) { - echo "NOK\n"; + $object->save(); + } catch (Exception $exc) { } + } + echo "OK\n"; - config::save('hardware_name', ''); - if (config::byKey('api') == '') { - echo "Fix default apikey...\n"; - config::save('api', config::genKey()); - } - if (file_exists(__DIR__ . '/../core/nodeJS')) { - echo "Remove unused nodejs folder...\n"; - shell_exec(system::getCmdSudo() . 'rm -rf ' . __DIR__ . '/../core/nodeJS'); - } - if (file_exists(__DIR__ . '/../script/ngrok')) { - echo "Remove unused ngrok folder...\n"; - shell_exec(system::getCmdSudo() . 'rm -rf ' . __DIR__ . '/../script/ngrok'); - } - - echo "Check jeedom object..."; - foreach (jeeObject::all() as $object) { - try { - $object->save(); - } catch (Exception $exc) { + echo "Check jeedom cmd..."; + foreach (cmd::all() as $cmd) { + try { + $changed = false; + if ($cmd->getConfiguration('jeedomCheckCmdCmdActionId') != '') { + $cmd->setConfiguration('jeedomCheckCmdCmdActionId', ''); + $changed = true; } - } - echo "OK\n"; - - echo "Check jeedom cmd..."; - foreach (cmd::all() as $cmd) { - try { - $changed = false; - if ($cmd->getConfiguration('jeedomCheckCmdCmdActionId') != '') { - $cmd->setConfiguration('jeedomCheckCmdCmdActionId', ''); - $changed = true; - } - if (trim($cmd->getTemplate('dashboard')) != '' && strpos($cmd->getTemplate('dashboard'), '::') === false) { - $cmd->setTemplate('dashboard', 'core::' . $cmd->getTemplate('dashboard')); - $changed = true; - } - if (trim($cmd->getTemplate('mobile')) != '' && strpos($cmd->getTemplate('mobile'), '::') === false) { - $cmd->setTemplate('mobile', 'core::' . $cmd->getTemplate('mobile')); - $changed = true; - } - if ($changed) { - $cmd->save(true); - } - } catch (Exception $exc) { + if (trim($cmd->getTemplate('dashboard')) != '' && strpos($cmd->getTemplate('dashboard'), '::') === false) { + $cmd->setTemplate('dashboard', 'core::' . $cmd->getTemplate('dashboard')); + $changed = true; + } + if (trim($cmd->getTemplate('mobile')) != '' && strpos($cmd->getTemplate('mobile'), '::') === false) { + $cmd->setTemplate('mobile', 'core::' . $cmd->getTemplate('mobile')); + $changed = true; + } + if ($changed) { + $cmd->save(true); } + } catch (Exception $exc) { } } + echo "OK\n"; if (!file_exists(__DIR__ . '/../data/php/user.function.class.php')) { From 8f7dbdeeb6041fbaf157c513a146a3d9230902cd Mon Sep 17 00:00:00 2001 From: Salvialf Date: Tue, 16 Dec 2025 09:49:30 +0100 Subject: [PATCH 19/24] update doc & changelog #3109 --- docs/fr_FR/changelog.md | 1 + docs/fr_FR/scenario.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/fr_FR/changelog.md b/docs/fr_FR/changelog.md index 4c4c0cfbc5..8b7a330a54 100644 --- a/docs/fr_FR/changelog.md +++ b/docs/fr_FR/changelog.md @@ -2,6 +2,7 @@ # 4.5.1 +- Le déclencheur de scénarios `#user_connect#` inclut dorénavant le tag `#trigger_value#` qui renseigne le nom de l'utilisateur venant de se connecter ([Détails](https://github.com/jeedom/core/pull/3109)) - Montée de version de nodejs 20 vers 22 ([Détails](https://github.com/jeedom/core/issues/3147)) # 4.5 diff --git a/docs/fr_FR/scenario.md b/docs/fr_FR/scenario.md index 13d3c0d1e0..779d802487 100644 --- a/docs/fr_FR/scenario.md +++ b/docs/fr_FR/scenario.md @@ -236,7 +236,7 @@ Il existe des déclencheurs spécifiques (autre que ceux fournis par les command - ``#end_update#`` : Événement envoyé à la fin d’une mise à jour. - ``#begin_restore#`` : Événement envoyé au début d’une restauration. - ``#end_restore#`` : Événement envoyé à la fin d’une restauration. -- ``#user_connect#`` : Connexion d'un utilisateur +- ``#user_connect#`` : Connexion d'un utilisateur, le tag `#trigger_value#` contient le nom de l'utilisateur. - ``#variable(nom_variable)#`` : Changement de valeur de la variable nom_variable. - ``#genericType(GENERIC, #[Object]#)#`` : Changement d'une commande info de Type Generic GENERIC, dans l'objet Object. - ``#new_eqLogic#`` : Événement envoyé lors de la création d'un nouvelle équipement, vous avez dans les tags id (id de l'équipement crée), name (nom de l'équipement crée) et eqType (type/plugin de l'équipement crée) From 241cf2c5fb3b9040b34474d2b0e8ee6c8ad54b74 Mon Sep 17 00:00:00 2001 From: Salvialf Date: Tue, 16 Dec 2025 10:49:39 +0100 Subject: [PATCH 20/24] continue if value is null --- core/class/scenarioExpression.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/class/scenarioExpression.class.php b/core/class/scenarioExpression.class.php index 7fa2e9e653..4208bbcd78 100644 --- a/core/class/scenarioExpression.class.php +++ b/core/class/scenarioExpression.class.php @@ -1275,7 +1275,9 @@ public static function setTags(&$_expression, &$_scenario = null, $_quote = fals } if ($_quote) { foreach ($replace1 as &$value) { - $value = (string)$value; + if ($value === null) { + continue; + } if (strpos($value, ' ') !== false || preg_match("/[a-zA-Z]/", $value) || $value === '') { $value = '"' . trim($value, '"') . '"'; } From 3cf20ec1917d238729b5e0f6a0d651c7ed1daf23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= <1536036+zoic21@users.noreply.github.com> Date: Wed, 17 Dec 2025 10:10:39 +0100 Subject: [PATCH 21/24] Update changelog.md --- docs/fr_FR/changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/fr_FR/changelog.md b/docs/fr_FR/changelog.md index 8b7a330a54..dd8fc45589 100644 --- a/docs/fr_FR/changelog.md +++ b/docs/fr_FR/changelog.md @@ -4,6 +4,8 @@ - Le déclencheur de scénarios `#user_connect#` inclut dorénavant le tag `#trigger_value#` qui renseigne le nom de l'utilisateur venant de se connecter ([Détails](https://github.com/jeedom/core/pull/3109)) - Montée de version de nodejs 20 vers 22 ([Détails](https://github.com/jeedom/core/issues/3147)) +- La sauvegarde se fera maintenant a une heure aléatoire entre 00:10 et 9:59 +- Correction d'un warning sur les valeurs de tags null # 4.5 From de3a5c51b2d19e1867c3912fbac8aa4919715929 Mon Sep 17 00:00:00 2001 From: "Julien C." Date: Tue, 30 Dec 2025 16:51:25 +0100 Subject: [PATCH 22/24] Update market.display.repo.php --- core/repo/market.display.repo.php | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/core/repo/market.display.repo.php b/core/repo/market.display.repo.php index cb0aa4a257..551e03f3e6 100644 --- a/core/repo/market.display.repo.php +++ b/core/repo/market.display.repo.php @@ -114,21 +114,25 @@ ?>

getCertification() == 'Premium') { - echo '{{Nous Contacter}}'; + echo '{{Nous Contacter}}'; } else { - if ($market->getCost() > 0) { - if ($market->getPurchase() == 1 && isset($purchase_info['user_id']) && is_numeric($purchase_info['user_id'])) { - echo '{{Plugin deja acheté et/ou inclus dans votre service Pack}}'; - }else{ - if ($market->getCost() != $market->getRealCost()) { + if (isset($purchase_info['user_id']) && is_numeric($purchase_info['user_id']) && $market->getPurchase() == 1) { + echo '{{Plugin deja acheté et/ou inclus dans votre service Pack}}'; + } else { + if ($market->getCost() > 0) { + if ($market->getCost() != $market->getRealCost()) { echo '' . number_format($market->getRealCost(), 2) . ' € '; - } - echo '' . number_format($market->getCost(), 2) . ' € TTC'; - } - } else { - echo '{{Gratuit}}'; - } + } + echo '' . number_format($market->getCost(), 2) . ' € TTC'; + } else { + echo '{{Gratuit}}'; + } + } } ?> From 48720580f477f1e62f018933c2c1d83ea2bc045b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc?= <1536036+zoic21@users.noreply.github.com> Date: Thu, 1 Jan 2026 09:29:48 +0100 Subject: [PATCH 23/24] bugfix --- core/class/jeedom.class.php | 12 ------------ core/config/version | 2 +- docs/fr_FR/changelog.md | 4 ++++ 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/core/class/jeedom.class.php b/core/class/jeedom.class.php index d090860d81..b44d49f722 100644 --- a/core/class/jeedom.class.php +++ b/core/class/jeedom.class.php @@ -1036,18 +1036,6 @@ public static function isDateOk() { return false; } } - $minDateValue = new \DateTime('2020-01-01'); - $mindate = strtotime($minDateValue->format('Y-m-d 00:00:00')); - $maxDateValue = $minDateValue->modify('+6 year')->format('Y-m-d 00:00:00'); - $maxdate = strtotime($maxDateValue); - if (strtotime('now') < $mindate || strtotime('now') > $maxdate) { - self::forceSyncHour(); - sleep(3); - if (strtotime('now') < $mindate || strtotime('now') > $maxdate) { - log::add('core', 'error', __('La date du système est incorrecte (avant ' . $minDateValue . ' ou après ' . $maxDateValue . ') :', __FILE__) . ' ' . (new \DateTime())->format('Y-m-d H:i:s'), 'dateCheckFailed'); - return false; - } - } return true; } diff --git a/core/config/version b/core/config/version index 4404a17bae..689f7fbd33 100644 --- a/core/config/version +++ b/core/config/version @@ -1 +1 @@ -4.5.1 +4.5.2 \ No newline at end of file diff --git a/docs/fr_FR/changelog.md b/docs/fr_FR/changelog.md index dd8fc45589..ab2c7f8ea5 100644 --- a/docs/fr_FR/changelog.md +++ b/docs/fr_FR/changelog.md @@ -1,5 +1,9 @@ # Changelog Jeedom V4.5 +# 4.5.2 + +Mise à jour vivement recommandée, elle corrige un bug sur la verification de la date qui empeche tout lancement de scénario ou de tache planifiée. + # 4.5.1 - Le déclencheur de scénarios `#user_connect#` inclut dorénavant le tag `#trigger_value#` qui renseigne le nom de l'utilisateur venant de se connecter ([Détails](https://github.com/jeedom/core/pull/3109)) From 3b3a5608fc0be9c618568a877ca61a47429ec7fb Mon Sep 17 00:00:00 2001 From: aofc Date: Sat, 21 Feb 2026 15:37:15 -0500 Subject: [PATCH 24/24] Fix randText la fonction actuelle brise sur php8 evaluate attend un string donc lui passer le string pas l'array; et utiliser $result ensuite --- core/class/scenarioExpression.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/class/scenarioExpression.class.php b/core/class/scenarioExpression.class.php index 4208bbcd78..a8625c7b27 100644 --- a/core/class/scenarioExpression.class.php +++ b/core/class/scenarioExpression.class.php @@ -213,18 +213,18 @@ public static function randText($_sValue) { $_sValue = self::setTags($_sValue); $_aValue = explode(";", $_sValue); try { - $result = evaluate($_aValue); + $result = evaluate($_sValue); if (is_string($result)) { $result = $_aValue; } } catch (Exception $e) { $result = $_aValue; } - if (is_array($_aValue)) { - $nbr = mt_rand(0, count($_aValue) - 1); - return $_aValue[$nbr]; + if (is_array($result)) { + $nbr = mt_rand(0, count($result) - 1); + return $result[$nbr]; } else { - return $_aValue; + return $result; } }