From 95e941dd2380ec0146755fecd7a2edb6bbd42724 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 22 Feb 2026 17:33:26 +0100 Subject: [PATCH 1/4] Trans --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index bba715cd45d..62d084c93e1 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1035,7 +1035,7 @@ Permission2515=Setup documents directories Permission2610=Generate/modify users API key Permission2801=Use FTP client in read mode (browse and download only) Permission2802=Use FTP client in write mode (delete or upload files) -Permission3201=Read Unalterable Logs and signature +Permission3201=Read, Export and Control Immutable Logs and signature Permission3301=Generate new modules Permission4001=Read skill/job/position Permission4002=Create/modify skill/job/position From dd3709be29db9bf6ab82aa8088d45778bf10bc80 Mon Sep 17 00:00:00 2001 From: minimexat Date: Mon, 23 Feb 2026 01:36:32 +0100 Subject: [PATCH 2/4] fix: use ob_end_clean() instead of ob_end_flush() in readfileLowMemory() (#37298) * fix: use ob_end_clean() instead of ob_end_flush() in readfileLowMemory() (fixes #37239) * fix: use robust ob level cleanup loop per hregis review --------- Co-authored-by: f-hoedl Co-authored-by: Laurent Destailleur --- htdocs/core/lib/functions.lib.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index bba94b3f1bb..2dfa39b3165 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -15648,8 +15648,10 @@ function readfileLowMemory($fullpath_original_file_osencoded, $method = -1) } // Be sure we don't have output buffering enabled to have readfile working correctly - while (ob_get_level()) { - ob_end_flush(); + $level = ob_get_level(); + ob_start(); + while (ob_get_level() > $level) { + ob_end_clean(); } // Solution 0 From 08feb72c6cd4de169cd2f1f987dee89e36bf1b74 Mon Sep 17 00:00:00 2001 From: Erwan-Wiwit Date: Mon, 23 Feb 2026 01:43:25 +0100 Subject: [PATCH 3/4] Add hook stripeWebhookEvent in Stripe IPN for external modules (#37293) * Add hook stripeWebhookEvent in Stripe IPN for external modules Allow external modules to intercept and handle Stripe webhook events via the standard Dolibarr hook system. The hook is called before the built-in event processing, and modules can return >0 to stop default processing if they handled the event entirely. Hook context: stripeipn Hook method: stripeWebhookEvent Parameters: event (full Stripe event), servicestatus, service Co-Authored-By: Claude Opus 4.6 * Fix phpstan: instantiate HookManager before use in ipn.php Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 Co-authored-by: Laurent Destailleur --- htdocs/public/stripe/ipn.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index d8a88530bbd..839a67edc22 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -191,6 +191,18 @@ dol_syslog("***** Stripe IPN was called with event->type=".$event->type." servic sleep(2); +// Hook to allow external modules to handle Stripe webhook events +$hookmanager = new HookManager($db); +$hookmanager->initHooks(array('stripeipn')); +$parameters = array('event' => $event, 'servicestatus' => $servicestatus, 'service' => $service); +$reshook = $hookmanager->executeHooks('stripeWebhookEvent', $parameters, $event->data->object, $event->type); +if ($reshook > 0) { + // A hook handled the event entirely, stop processing + http_response_code(200); + return; +} + + if ($event->type == 'payout.created' && getDolGlobalString('STRIPE_AUTO_RECORD_PAYOUT')) { // When a payout is created by Stripe to transfer money to your account dol_syslog("object = ".formatLogObject($event->data)); From f15efe2ca808bef8eef1ab9ff090489ab1354fe6 Mon Sep 17 00:00:00 2001 From: William Mead Date: Mon, 23 Feb 2026 01:47:39 +0100 Subject: [PATCH 4/4] Added data pagination for index method (#37302) Co-authored-by: Laurent Destailleur --- htdocs/projet/class/api_tasks.class.php | 38 +++++++++++++++++++------ 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index 914148ffeeb..614a661da33 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -5,6 +5,7 @@ * Copyright (C) 2025 MDW * Copyright (C) 2025 Jessica Kowal * Copyright (C) 2025 Charlene Benke + * Copyright (C) 2026 William Mead * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -106,17 +107,18 @@ class Tasks extends DolibarrApi * * @since 5.0.0 Initial implementation * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Limit for list - * @param int $page Page number - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" - * @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names - * @return array Array of project objects + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names + * @param bool $pagination_data If this parameter is set to true the response will include pagination data. Default value is false. Page starts from 0 + * @return array Array of project objects * @phan-return Task[] * @phpstan-return Task[] */ - public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '', $properties = '') + public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '', $properties = '', $pagination_data = false) { global $db, $conf; @@ -160,6 +162,9 @@ class Tasks extends DolibarrApi } } + //this query will return total tasks with the filters given + $sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql); + $sql .= $this->db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) { @@ -189,6 +194,23 @@ class Tasks extends DolibarrApi throw new RestException(503, 'Error when retrieve task list : ' . $this->db->lasterror()); } + //if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit) + if ($pagination_data) { + $totalsResult = $this->db->query($sqlTotals); + $total = $this->db->fetch_object($totalsResult)->total; + + $tmp = $obj_ret; + $obj_ret = []; + + $obj_ret['data'] = $tmp; + $obj_ret['pagination'] = [ + 'total' => (int) $total, + 'page' => $page, //count starts from 0 + 'page_count' => ceil((int) $total / $limit), + 'limit' => $limit + ]; + } + return $obj_ret; }