Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
6d7fda1
FOUR-31727: Fix DevLink bundle listing and selector search
eiresendez Jun 30, 2026
ddb7844
FOUR-31359 Fix clipboard lookup for new users
eiresendez Jul 1, 2026
7614008
FOUR-31727: Stabilize remote backend select search
eiresendez Jul 1, 2026
91c877a
FOUR-31341: Respect non-filterable task columns
eiresendez Jul 1, 2026
eabaa22
FOUR-30920: Remove expected DevLink ping 401
eiresendez Jul 8, 2026
1a0e084
feat: add saved_search_advanced_configuration to filesystem configura…
devmiguelangel Sep 10, 2025
2445e0c
Add job validation and new scheduling method `scheduleDateJob`
caleeli Sep 16, 2025
4f14492
Bumped tag branch perfomance
pmPaulis Jul 9, 2026
0c7a58c
FOUR-29372: Show persisted multi-instance form data
eiresendez Jul 9, 2026
ea35fe0
Fixing issue composer version
pmPaulis Jul 9, 2026
880cdbf
Fixing issue composer version
pmPaulis Jul 9, 2026
ed93d73
Fixing issue composer version
pmPaulis Jul 9, 2026
d099c01
Add Microsoft Graph token provider and tests
sanjacornelius Jul 9, 2026
7271738
Inject HTTP client into token provider
sanjacornelius Jul 9, 2026
f621ec4
feat: fix TaskSchedulerManager to handle last_execution initializatio…
devmiguelangel Jul 10, 2026
b0d14ca
Use real PSR-7 Response in test
sanjacornelius Jul 10, 2026
c1ac2ad
Merge pull request #8901 from ProcessMaker/subtask/FOUR-32164
sanjacornelius Jul 13, 2026
a8f92f6
FOUR-27170
pmPaulis Jul 13, 2026
79347af
Add Microsoft Graph mail transport and config
sanjacornelius Jul 14, 2026
0bfa4d5
FOUR-32268: Add runtime Smart Extract configuration PoC
eiresendez Jul 15, 2026
91b80b6
Remove authorization badge from microsoft_graph
sanjacornelius Jul 15, 2026
f1ccc2a
Merge pull request #8907 from ProcessMaker/subtask/FOUR-32165
sanjacornelius Jul 15, 2026
fc31cdb
Remove caching from Microsoft Graph token provider
sanjacornelius Jul 16, 2026
49018d4
Merge branch 'epic/FOUR-32115' into observation/FOUR-32273
sanjacornelius Jul 16, 2026
3b82c61
Include file attachments in Graph payload
sanjacornelius Jul 16, 2026
5d99a66
Merge pull request #8910 from ProcessMaker/observation/FOUR-32273
sanjacornelius Jul 16, 2026
9932295
Merge pull request #8912 from ProcessMaker/observation/FOUR-32274
sanjacornelius Jul 17, 2026
656192c
feat: FOUR-30102 Command to update the timezone for the Anonymous user
pmPaulis Jul 20, 2026
e819c3c
FOUR-32333: Isolate DevLink progress by operation
eiresendez Jul 22, 2026
052f28c
FOUR-32329: Handle unavailable assets in DevLink bundles
eiresendez Jul 23, 2026
1d40282
Merge branch 'develop' into bugfix/FOUR-32333
eiresendez Jul 23, 2026
a633694
Merge branch 'develop' into bugfix/FOUR-30920
eiresendez Jul 23, 2026
8b915fa
Merge branch 'develop' into bugfix/FOUR-31727
eiresendez Jul 23, 2026
9f7f30f
Merge remote-tracking branch 'origin/develop' into epic/FOUR-26166
devmiguelangel Jul 24, 2026
c811f14
Merge remote-tracking branch 'origin/develop' into spike/FOUR-32268
eiresendez Jul 27, 2026
46df95a
FOUR-32397: Add Smart Extract configuration fallback
eiresendez Jul 27, 2026
5edb691
fix(FOUR-29427): Menu Style Discrepancy Between Homepage and Request …
rodriquelca Jul 27, 2026
cb7d527
FOUR-31416 Remove guided templates
julceslauhub Jul 27, 2026
8c8295a
FOUR-31416 Remove guided templates
julceslauhub Jul 27, 2026
5705c02
FOUR-31416 Remove guided templates
julceslauhub Jul 27, 2026
f43a71e
feat(FOUR-32405): add Database Indexes to Improve Saved Searches Perf…
rodriquelca Jul 27, 2026
d1df925
Merge remote-tracking branch 'origin/develop' into epic/FOUR-26166
devmiguelangel Jul 28, 2026
6714abf
FOUR-32393 REGRESSION>> The icon main disapperas with selections of t…
gproly Jul 28, 2026
6a0abd2
fix: screen were not properly exporting dependant collections and dat…
caleeli Jul 29, 2026
b80d225
fix: add missing Illuminate\Support\Arr import in DataSourcesInScreen…
caleeli Jul 29, 2026
72a14a7
fix: include path tracking for improved callback context
caleeli Jul 29, 2026
f2f9464
fix: update watcher script_id assignment to remove prefix for consist…
caleeli Aug 3, 2026
8ce6e46
Merge branch 'develop' into epic/FOUR-32115
sanjacornelius Aug 3, 2026
37212a1
Update security advisory
nolanpro Aug 3, 2026
aa1e8ab
Merge pull request #8905 from ProcessMaker/FOUR-27170
nolanpro Aug 3, 2026
a5df183
Merge pull request #8900 from ProcessMaker/bugfix/FOUR-29372
nolanpro Aug 3, 2026
0d11005
Merge pull request #8937 from ProcessMaker/bugfix/FOUR-29427
nolanpro Aug 3, 2026
fcf7ece
Merge pull request #8917 from ProcessMaker/FOUR-30102-p
nolanpro Aug 3, 2026
d819f09
Merge pull request #8897 from ProcessMaker/bugfix/FOUR-30920
nolanpro Aug 3, 2026
afb5a4b
Merge pull request #8892 from ProcessMaker/bugfix/FOUR-31341
nolanpro Aug 3, 2026
5ace4c8
Merge pull request #8890 from ProcessMaker/bugfix/FOUR-31359
nolanpro Aug 3, 2026
77ccd8f
Merge pull request #8938 from ProcessMaker/FOUR-31416
nolanpro Aug 3, 2026
9eee272
Merge pull request #8889 from ProcessMaker/bugfix/FOUR-31727
nolanpro Aug 3, 2026
7eb7716
Merge pull request #8906 from ProcessMaker/epic/FOUR-32115
nolanpro Aug 3, 2026
90ad112
Merge pull request #8927 from ProcessMaker/bugfix/FOUR-32333
nolanpro Aug 3, 2026
d504ade
Merge pull request #8944 from ProcessMaker/bugfix/FOUR-32393
nolanpro Aug 3, 2026
e314278
Merge pull request #8908 from ProcessMaker/spike/FOUR-32268
nolanpro Aug 3, 2026
dc2c190
Merge pull request #8940 from ProcessMaker/feature/FOUR-32405
nolanpro Aug 3, 2026
8b1e9ef
Merge pull request #8949 from ProcessMaker/FOUR-32416
nolanpro Aug 3, 2026
930f4b7
Merge branch 'develop' into bugfix/FOUR-32329
eiresendez Aug 3, 2026
6c4555f
Merge pull request #8930 from ProcessMaker/bugfix/FOUR-32329
nolanpro Aug 3, 2026
b0c3295
Update dependencies
nolanpro Aug 3, 2026
7a49a98
Version 2026.13.1
processmaker-bot Aug 3, 2026
c64b38b
debug tests
caleeli Aug 4, 2026
b66cf7c
Merge remote-tracking branch 'origin/develop' into epic/FOUR-26166
devmiguelangel Aug 4, 2026
b1bbb34
ci: debug tests
caleeli Aug 4, 2026
e7c35ab
Create custom executor in microservice after import
gusys Aug 4, 2026
c88af0f
Merge pull request #8972 from ProcessMaker/check-tests
nolanpro Aug 4, 2026
2fbb379
feat(FOUR-31695): solving conflicts
rodriquelca Jun 19, 2026
f4126fa
feat(FOUR-32024): review and fix the calculation of DB timing when lo…
rodriquelca Jun 26, 2026
1a44a4e
feat(FOUR-32353): solving conflicts
rodriquelca Jul 29, 2026
c7bb47d
feat(FOUR-32353): solving conflicts
rodriquelca Jul 29, 2026
c8a6a04
feat: add test for octane
rodriquelca Jul 29, 2026
a5a0358
add octane resetRequestState class
rodriquelca Jul 29, 2026
741db29
feat: update config/octane
rodriquelca Jul 31, 2026
0e0a60b
Fix security advisories
nolanpro Aug 7, 2026
a3aa9b3
Merge pull request #8979 from ProcessMaker/epic/FOUR-30918-octane
nolanpro Aug 10, 2026
5641792
Merge pull request #8899 from ProcessMaker/epic/FOUR-26166
nolanpro Aug 10, 2026
99b21a2
Merge pull request #8973 from ProcessMaker/FOUR-32503
nolanpro Aug 10, 2026
aee6f73
Update dependencies
nolanpro Aug 10, 2026
18bbc29
Version 2026.13.2
processmaker-bot Aug 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ storage/ssl
storage/api/*
storage/data-sources/logs/*
storage/decision-tables/*
storage/saved_search_advanced_configuration/*
npm.sh
laravel-echo-server.lock
public/.htaccess
Expand All @@ -51,4 +52,7 @@ devhub/pm-font/dist
test-db-snapshot.db
snapshot_*.db
storage/transitions
.envrc
.envrc
**/caddy
frankenphp
frankenphp-worker.php
72 changes: 72 additions & 0 deletions ProcessMaker/Assets/DataSourcesInProcess.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace ProcessMaker\Assets;

use DOMXPath;
use ProcessMaker\Models\Process;
use ProcessMaker\Providers\WorkflowServiceProvider;

class DataSourcesInProcess
{
public $type = 'ProcessMaker\Packages\Connectors\DataSources\Models\DataSource';

public $owner = Process::class;

/**
* Get the data sources used in a process
*
* @param Process $process
* @param array $dataSources
*
* @return array
*/
public function referencesToExport(Process $process, array $dataSources = [])
{
// Data Sources used in BPMN Service Tasks
$xpath = new DOMXPath($process->getDefinitions());
$xpath->registerNamespace('pm', WorkflowServiceProvider::PROCESS_MAKER_NS);

// Find all nodes with pm:config
$nodes = $xpath->query("//*[@pm:config!='']");
foreach ($nodes as $node) {
$configString = $node->getAttributeNS(WorkflowServiceProvider::PROCESS_MAKER_NS, 'config');
$config = json_decode($configString, true);
if (isset($config['dataSource']) && is_numeric($config['dataSource'])) {
$dataSources[] = [$this->type, (int) $config['dataSource']];
}
}

return $dataSources;
}

/**
* Update references used in an imported process
*
* @param Process $process
* @param array $references
*
* @return void
*/
public function updateReferences(Process $process, array $references = [])
{
$definitions = $process->getDefinitions();
$xpath = new DOMXPath($definitions);
$xpath->registerNamespace('pm', WorkflowServiceProvider::PROCESS_MAKER_NS);

$nodes = $xpath->query("//*[@pm:config!='']");
foreach ($nodes as $node) {
$configString = $node->getAttributeNS(WorkflowServiceProvider::PROCESS_MAKER_NS, 'config');
$config = json_decode($configString, true);
if (isset($config['dataSource']) && is_numeric($config['dataSource'])) {
$oldRef = $config['dataSource'];
if (isset($references[$this->type][$oldRef])) {
$newRef = $references[$this->type][$oldRef]->getKey();
$config['dataSource'] = $newRef;
$node->setAttributeNS(WorkflowServiceProvider::PROCESS_MAKER_NS, 'config', json_encode($config));
}
}
}
$process->bpmn = $definitions->saveXML();
$process->save();
}
}
131 changes: 131 additions & 0 deletions ProcessMaker/Assets/DataSourcesInScreen.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

namespace ProcessMaker\Assets;

use ProcessMaker\Managers\ExportManager;
use ProcessMaker\Models\Screen;
use Illuminate\Support\Arr;

class DataSourcesInScreen
{
public $type = 'ProcessMaker\Packages\Connectors\DataSources\Models\DataSource';

public $owner = Screen::class;

/**
* Get the data sources (ex. watchers) used in a screen
*
* @param Screen $screen
* @param array $dataSources
*
* @return array
*/
public function referencesToExport(Screen $screen, array $dataSources = [])
{
$watchers = $screen->watchers;
if (is_array($watchers)) {
$this->findInArray($watchers, function ($item) use (&$dataSources) {
if (is_array($item)) {
$scriptId = (string) ($item['script_id'] ?? '');
$id = (string) ($item['script']['id'] ?? '');
if (str_starts_with($scriptId, 'data_source-') || str_starts_with($id, 'data_source-')) {
$numericId = str_replace('data_source-', '', str_starts_with($scriptId, 'data_source-') ? $scriptId : $id);
if (is_numeric($numericId)) {
$dataSources[] = [$this->type, (int) $numericId];
}
}
}
});
}

$config = $screen->versionFor(null)->config;
if (is_array($config)) {
$this->findInArray($config, function ($item) use (&$dataSources) {
if (is_array($item) && isset($item['component']) && $item['component'] === 'FormSelectList' && !empty($item['config']['options']['selectedDataSource'])) {
$dataSources[] = [$this->type, (int) $item['config']['options']['selectedDataSource']];
}
});
}

return $dataSources;
}

/**
* Update references used in an imported screen
*
* @param Screen $screen
* @param array $references
* @param ExportManager $exportManager
*
* @return void
*/
public function updateReferences(Screen $screen, array $references, ExportManager $exportManager)
{
$watches = $screen->watchers;
if (is_array($watches)) {
foreach ($watches as &$watcher) {
$id = (string) ($watcher['script']['id'] ?? '');
if (str_starts_with($id, 'data_source-')) {
$oldRef = str_replace('data_source-', '', $id);
if (isset($references[$this->type][$oldRef])) {
$newRef = $references[$this->type][$oldRef]->getKey();
} else {
$newRef = null;
$exportManager->addLogMessage(
'DataSourcesInScreen:references',
__(
'Imported file does not contain the data source #:dataSource assigned to a watcher',
['dataSource' => $oldRef]
),
false,
__("Missing watcher's data source")
);
}
if ($newRef) {
$watcher['script_id'] = $newRef;
$watcher['script']['id'] = "data_source-$newRef";
$watcher['script']['title'] = $references[$this->type][$oldRef]->name;
}
}
}
}
$screen->watchers = $watches;

$config = $screen->config;
if (is_array($config)) {
$this->findInArray($config, function ($item, $keyDotNotation) use ($references, &$config) {
if (is_array($item) && isset($item['component']) && $item['component'] === 'FormSelectList' && !empty($item['config']['options']['selectedDataSource'])) {
$oldRef = $item['config']['options']['selectedDataSource'];
if (isset($references[$this->type][$oldRef])) {
$newRef = $references[$this->type][$oldRef]->getKey();
Arr::set($config, "$keyDotNotation.config.options.selectedDataSource", $newRef);
}
}
});
$screen->config = $config;
}

$screen->save();
}

/**
* Find recursively in an array
*
* @param array $array
* @param callable $callback
* @param array $path
*
* @return void
*/
private function findInArray(array $array, callable $callback, array $path = [])
{
call_user_func($callback, $array, implode('.', $path));
foreach ($array as $key => $item) {
if (is_array($item)) {
$this->findInArray($item, $callback, array_merge($path, [$key]));
} else {
call_user_func($callback, $item, implode('.', array_merge($path, [$key])));
}
}
}
}
8 changes: 7 additions & 1 deletion ProcessMaker/Assets/ScriptsInProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ public function referencesToExport(Process $process, array $scripts = [])
// Used in scriptRef
$nodes = $xpath->query("//*[@pm:scriptRef!='']");
foreach ($nodes as $node) {
$scripts[] = [Script::class, $node->getAttributeNS(WorkflowServiceProvider::PROCESS_MAKER_NS, 'scriptRef')];
$scriptId = $node->getAttributeNS(WorkflowServiceProvider::PROCESS_MAKER_NS, 'scriptRef');
if (!str_starts_with((string) $scriptId, 'data_source-')) {
$scripts[] = [Script::class, $scriptId];
}
}

return $scripts;
Expand All @@ -54,6 +57,9 @@ public function updateReferences(Process $process, array $references = [])
$nodes = $xpath->query("//*[@pm:scriptRef!='']");
foreach ($nodes as $node) {
$oldRef = $node->getAttributeNS(WorkflowServiceProvider::PROCESS_MAKER_NS, 'scriptRef');
if (str_starts_with((string) $oldRef, 'data_source-')) {
continue;
}
$newRef = $references[Script::class][$oldRef]->getKey();
$node->setAttributeNS(WorkflowServiceProvider::PROCESS_MAKER_NS, 'scriptRef', $newRef);
}
Expand Down
24 changes: 15 additions & 9 deletions ProcessMaker/Assets/ScriptsInScreen.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ public function referencesToExport(Screen $screen, array $scripts = [])
if (is_array($config)) {
$this->findInArray($config, function ($item) use (&$scripts) {
if (is_array($item) && !empty($item['script_id'])) {
$scripts[] = [Script::class, $item['script_id']];
$scriptId = (string) $item['script_id'];
$id = (string) ($item['script']['id'] ?? '');
if (!str_starts_with($scriptId, 'data_source-') && !str_starts_with($id, 'data_source-')) {
$scripts[] = [Script::class, $item['script_id']];
}
}
});
}
Expand All @@ -47,11 +51,12 @@ public function updateReferences(Screen $screen, array $references, ExportManage
$watches = $screen->watchers;
if (is_array($watches)) {
foreach ($watches as &$watcher) {
$refParts = explode('-', $watcher['script_id']);
if ($refParts[0] === 'data_source') {
$scriptId = (string) ($watcher['script_id'] ?? '');
$id = (string) ($watcher['script']['id'] ?? '');
if (str_starts_with($scriptId, 'data_source-') || str_starts_with($id, 'data_source-')) {
continue;
}
$oldRef = $refParts[1];
$oldRef = $scriptId;
if (isset($references[Script::class][$oldRef])) {
$newRef = $references[Script::class][$oldRef]->getKey();
} else {
Expand Down Expand Up @@ -82,17 +87,18 @@ public function updateReferences(Screen $screen, array $references, ExportManage
*
* @param array $array
* @param callable $callback
* @param array $path
*
* @return void
*/
private function findInArray(array $array, callable $callback)
private function findInArray(array $array, callable $callback, array $path = [])
{
call_user_func($callback, $array);
foreach ($array as $item) {
call_user_func($callback, $array, implode('.', $path));
foreach ($array as $key => $item) {
if (is_array($item)) {
$this->findInArray($item, $callback);
$this->findInArray($item, $callback, array_merge($path, [$key]));
} else {
call_user_func($callback, $item);
call_user_func($callback, $item, implode('.', array_merge($path, [$key])));
}
}
}
Expand Down
41 changes: 0 additions & 41 deletions ProcessMaker/Console/Commands/SyncGuidedTemplates.php

This file was deleted.

55 changes: 55 additions & 0 deletions ProcessMaker/Console/Commands/UpdateAnonymousUserTimezone.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace ProcessMaker\Console\Commands;

use Illuminate\Console\Command;
use ProcessMaker\Models\AnonymousUser;
use ProcessMaker\Models\User;

class UpdateAnonymousUserTimezone extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'processmaker:update-anonymous-user-timezone
{--timezone= : Timezone to assign. Defaults to config app.anonymous_user_timezone}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Update the anonymous user timezone from config (safe to run multiple times)';

/**
* Execute the console command.
*/
public function handle(): int
{
$timezone = $this->option('timezone') ?: config('app.anonymous_user_timezone', 'UTC');

$user = User::where('username', AnonymousUser::ANONYMOUS_USERNAME)->first();

if (!$user) {
$this->error('Anonymous user not found.');

return self::FAILURE;
}

if ($user->timezone === $timezone) {
$this->info("Anonymous user timezone is already set to [{$timezone}].");

return self::SUCCESS;
}

$previousTimezone = $user->timezone;
$user->timezone = $timezone;
$user->save();

$this->info("Anonymous user timezone updated from [{$previousTimezone}] to [{$timezone}].");

return self::SUCCESS;
}
}
Loading
Loading