diff -u b/core/includes/update.inc b/core/includes/update.inc --- b/core/includes/update.inc +++ b/core/includes/update.inc @@ -586,6 +586,51 @@ } } + // A function returning all the updates which directly or indirectly have a + // specific update as an edge. + $get_all_parents = function($update) use ($graph, &$get_all_parents) { + $parents = []; + foreach ($graph as $func => $data) { + if (isset($data['edges'][$update])) { + $parents[] = $func; + $parents = array_merge($parents, $get_all_parents($func)); + } + } + return $parents; + }; + // If an update U2 has an edge to a system update S then add S as an edge to + // all updates having U2 as an edge. This ensures that the chain U1->U2->S + // will be executed in that particular order. + foreach ($graph as $non_system_func => $data) { + if ($data['module'] !== 'system') { + if (!empty($data['edges'])) { + $sys_updates = []; + foreach (array_keys($data['edges']) as $edge) { + if ($graph[$edge]['module'] === 'system') { + $sys_updates[$edge] = TRUE; + } + } + if ($sys_updates) { + foreach ($get_all_parents($non_system_func) as $parent_edge) { + $graph[$parent_edge]['edges'] = empty($graph[$parent_edge]['edges']) ? $sys_updates : array_merge($graph[$parent_edge]['edges'], $sys_updates); + } + } + } + } + } + // Find update functions without edges to the system update and add such + // updates as edges to the system update as they have to be executed after the + // system update. + foreach ($graph as $system_function => &$system_data) { + if ($system_data['module'] === 'system') { + foreach ($graph as $non_system_function => $non_system_data) { + if (($non_system_data['module'] !== 'system') && !isset($non_system_data['edges'][$system_function])) { + $system_data['edges'][$non_system_function] = TRUE; + } + } + } + } + return $graph; }