ID => entry as arrays, without allowedActions, without the customizer fonts and the * group "colors" (both are not stored there), empty groups left out. * * @return array>> */ public function read(): array { $data = []; foreach (GlobalData::get_global_variables() as $type => $items) { if ($type === 'colors' || (! is_array($items) && ! is_object($items))) { continue; } foreach ((array) $items as $id => $item) { // Divi's sanitizing keeps gvid- IDs only; the customizer fonts (--et_global_*_font) are not stored. if (! str_starts_with((string) $id, 'gvid-') || (! is_array($item) && ! is_object($item))) { continue; } $entry = (array) $item; unset($entry['allowedActions']); $data[(string) $type][(string) $id] = $entry; } } return $data; } /** * @param array>> $data The whole new inventory (stored form). * @param array>> $expected The inventory the change was planned on. * @throws DiviLocked When variable-write is not released – before anything is written. * @throws RuntimeException When Divi refuses the inventory (stale, missing IDs, invalid entries). */ public function save(array $data, array $expected): void { ReleaseGate::assertFeature(DiviFeature::VariableWrite); $refusal = GlobalData::set_global_variables($data, $expected); if ($refusal instanceof WP_Error) { throw new RuntimeException('global variables refused: ' . $refusal->get_error_code() . ' ' . $refusal->get_error_message()); } } /** Divi's role right "Variables Manager"; fail closed without Divi. */ public function canManage(): bool { return function_exists('et_pb_is_allowed') && (bool) et_pb_is_allowed('variables_manager'); } /** * Audit L5: GlobalData keeps a static copy of the variables that can be older than another writer's finished * save (the option cache is dropped by DesignLock). Called under the lock, before reading. */ public function refresh(): void { self::forgetCached('variables'); } /** Resets one entry of GlobalData's static runtime cache (private, so by reflection; gone = nothing to reset). */ private static function forgetCached(string $key): void { try { $cache = new \ReflectionProperty(GlobalData::class, '_cached_data'); $data = $cache->getValue(); if (is_array($data) && array_key_exists($key, $data)) { $data[$key] = null; $cache->setValue(null, $data); } } catch (\ReflectionException) { // Divi without that property: its reads are not cached this way. } } }