drupflare/worker - v1.0.4
    Preparing search index...

    Variable RENDER_FRAGMENTS_PHPConst

    RENDER_FRAGMENTS_PHP: "\nuse Drupal\\Component\\Utility\\Html;\nuse Drupal\\Core\\DrupalKernel;\nuse Drupal\\Core\\Site\\Settings;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n// __CFW_FIBER_SHIM__\n// __CFW_HOST_HELPERS__\n// __CFW_PW_SERVE_INLINE__\nchdir('/drupal');\n\n$path = json_decode(__CFW_PATH__);\n$cookie = json_decode(__CFW_COOKIE__);\n$origin = json_decode(__CFW_ORIGIN__);\n$recipes = json_decode(__CFW_RECIPES__, true);\n$out = ['ok' => false, 'path' => $path, 'fragments' => [], 'fragmentTags' => [], 'failed' => []];\n$clock = function () {\n\treturn microtime(true) * 1000;\n};\n\ntry {\n\tif (!isset($GLOBALS['__pw_autoloader']) || !is_object($GLOBALS['__pw_autoloader'])) {\n\t\t$GLOBALS['__pw_autoloader'] = require '/drupal/autoload.php';\n\t}\n\t$autoloader = $GLOBALS['__pw_autoloader'];\n\tif (!isset($GLOBALS['__pw_kernel'])) {\n\t\t$boot = Request::create('/', 'GET');\n\t\t$kernel = new DrupalKernel('prod', $autoloader);\n\t\tDrupalKernel::bootEnvironment();\n\t\t$sitePath = DrupalKernel::findSitePath($boot);\n\t\t$kernel->setSitePath($sitePath);\n\t\tSettings::initialize('/drupal', $sitePath, $autoloader);\n\t\t$kernel->boot();\n\t\t$GLOBALS['__pw_kernel'] = $kernel;\n\t}\n\n\t$t0 = $clock();\n\n\tif (function_exists('header_remove')) {\n\t\theader_remove();\n\t}\n\n\t$cookies = [];\n\tforeach (explode(';', $cookie) as $pair) {\n\t\t$pair = trim($pair);\n\t\tif ($pair === '') {\n\t\t\tcontinue;\n\t\t}\n\t\t$split = strpos($pair, '=');\n\t\tif ($split === false) {\n\t\t\tcontinue;\n\t\t}\n\t\t$cookies[urldecode(substr($pair, 0, $split))] = urldecode(substr($pair, $split + 1));\n\t}\n\t$server = $cookie === '' ? [] : ['HTTP_COOKIE' => $cookie];\n\t$url = $origin === '' ? $path : rtrim($origin, '/') . $path;\n\t$request = Request::create($url, 'GET', [], $cookies, [], $server);\n\n\t// THE SUPERGLOBALS ARE NOT DECORATION HERE. session_start() reads its id out of $_COOKIE, not out\n\t// of the Request object, so without this the fragment renders as whoever the interpreter served\n\t// last -- measured: one visitor's cookie came back uid 1 because admin had rendered before\n\t$_SERVER['HTTP_HOST'] = $request->getHttpHost();\n\t$_SERVER['SERVER_NAME'] = $request->getHost();\n\t$_SERVER['SERVER_PORT'] = (string) $request->getPort();\n\tif ($request->isSecure()) {\n\t\t$_SERVER['HTTPS'] = 'on';\n\t} else {\n\t\tunset($_SERVER['HTTPS']);\n\t}\n\t$_SERVER['REQUEST_METHOD'] = 'GET';\n\t$_SERVER['REQUEST_URI'] = $path;\n\t$_POST = [];\n\t$_GET = [];\n\t$_FILES = [];\n\t$_REQUEST = [];\n\t$_COOKIE = $cookies;\n\tif ($cookie !== '') {\n\t\t$_SERVER['HTTP_COOKIE'] = $cookie;\n\t} else {\n\t\tunset($_SERVER['HTTP_COOKIE']);\n\t}\n\n\t// AFTER the superglobals and BEFORE the session starts, which is the order cfw_serve() uses and\n\t// the order that matters: the resetter closes the previous session, and a reset that runs before\n\t// $_COOKIE is replaced closes one session and reopens the same one\n\ttry {\n\t\t$container = Drupal::getContainer();\n\t\tif ($container !== null && $container->has('drupflare.request_resetter')) {\n\t\t\t$GLOBALS['__pw_reset'] = $container->get('drupflare.request_resetter')->reset();\n\t\t} elseif (function_exists('session_status') && session_status() === PHP_SESSION_ACTIVE) {\n\t\t\t@session_write_close();\n\t\t\t$_SESSION = [];\n\t\t}\n\t} catch (Throwable $e) {\n\t}\n\n\t$stack = Drupal::service('request_stack');\n\twhile ($stack->getCurrentRequest() !== null) {\n\t\t$stack->pop();\n\t}\n\t$stack->push($request);\n\n\t// ids are deduplicated per RENDER, and this interpreter is where \"per render\" stops being\n\t// automatic; without it the second fragment of a session gets id--2 suffixes\n\tif ((new ReflectionClass(Html::class))->hasMethod('resetSeenIds')) {\n\t\tHtml::resetSeenIds();\n\t}\n\n\t// and the ajax flag beside it, which resetSeenIds() does not clear; left true it sends\n\t// getUniqueId() down its random branch for the rest of the incarnation\n\tif ((new ReflectionClass(Html::class))->hasMethod('setIsAjax')) {\n\t\tHtml::setIsAjax(false);\n\t}\n\n\t// THE ID IS SET EXPLICITLY, and skipping it is a session HANDOVER rather than a missing session.\n\t// session_write_close() leaves session_id() holding the previous visitor's id, and session_start()\n\t// prefers that id over $_COOKIE -- so without this, bob's cookie loaded admin's row and the\n\t// fragment rendered as uid 1 with no error anywhere. Measured; the middleware never has to do it\n\t// because a real SAPI starts each request with no id at all.\n\t$session = Drupal::service('session');\n\t// matched by SHAPE rather than asked of session_configuration, whose getName() is protected:\n\t// Drupal names the cookie SESS/SSESS + md5 of the site url, and that is the only cookie with it\n\t$sessionName = '';\n\tforeach (array_keys($cookies) as $name) {\n\t\tif (preg_match('/^S?SESS[0-9a-f]{32}$/', $name) === 1) {\n\t\t\t$sessionName = $name;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (function_exists('session_status') && session_status() === PHP_SESSION_ACTIVE) {\n\t\t@session_write_close();\n\t}\n\tif (isset($cookies[$sessionName])) {\n\t\ttry {\n\t\t\t$session->setId($cookies[$sessionName]);\n\t\t} catch (Throwable $e) {\n\t\t\t$out['setIdError'] = $e->getMessage();\n\t\t}\n\t}\n\t$request->setSession($session);\n\ttry {\n\t\t$session->start();\n\t} catch (Throwable $e) {\n\t\t$out['sessionError'] = $e->getMessage();\n\t}\n\n\t$account = Drupal::service('authentication')->authenticate($request);\n\tif ($account !== null) {\n\t\tDrupal::service('current_user')->setAccount($account);\n\t}\n\t$out['uid'] = (int) Drupal::currentUser()->id();\n\n\ttry {\n\t\t$request->attributes->add(Drupal::service('router')->matchRequest($request));\n\t} catch (Throwable $e) {\n\t\t$out['routeError'] = get_class($e) . ': ' . $e->getMessage();\n\t}\n\n\t$renderer = Drupal::service('renderer');\n\t$out['contextMs'] = round($clock() - $t0, 2);\n\n\t// the values normaliseShell() slots out of the stored shell, read for THIS session. Free here\n\t// -- the context is already built -- and unobtainable at the edge, which has no PHP\n\t$identity = ['uid' => (string) Drupal::currentUser()->id()];\n\ttry {\n\t\t$identity['permissionsHash'] = Drupal::service('user_permissions_hash_generator')->generate(\n\t\t\tDrupal::currentUser(),\n\t\t);\n\t} catch (Throwable $e) {\n\t}\n\ttry {\n\t\t$identity['csrf'] = ['user/logout' => Drupal::csrfToken()->get('user/logout')];\n\t} catch (Throwable $e) {\n\t}\n\t// the edge plan is keyed on this and a shell response carried none, so a path the shell tier\n\t// answered could never collect a sample and the plan tier starved for the whole session\n\ttry {\n\t\t$roles = array_values(Drupal::currentUser()->getRoles());\n\t\tsort($roles);\n\t\t$out['roles'] = $roles;\n\t} catch (Throwable $e) {\n\t}\n\t$out['identity'] = $identity;\n\n\t$t1 = $clock();\n\tforeach ($recipes as $id => $recipe) {\n\t\tif (!is_array($recipe)) {\n\t\t\t$out['failed'][] = $id;\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\t$elements = ['#markup' => $id, '#attached' => ['placeholders' => [$id => $recipe]]];\n\t\t\t$rendered = $renderer->renderPlaceholder($id, $elements);\n\t\t\t$out['fragments'][$id] = (string) ($rendered['#markup'] ?? '');\n\t\t\t// renderPlaceholder() merges the placeholder bubbleable metadata into $elements, so this is\n\t\t\t// the fragment own dependency set rather than the page one\n\t\t\t$out['fragmentTags'][$id] = array_values($rendered['#cache']['tags'] ?? []);\n\t\t} catch (Throwable $e) {\n\t\t\t$out['failed'][] = $id;\n\t\t\t$out['failure'][$id] = get_class($e) . ': ' . $e->getMessage();\n\t\t}\n\t}\n\t$out['renderMs'] = round($clock() - $t1, 2);\n\t$out['totalMs'] = round($clock() - $t0, 2);\n\t$out['ok'] = count($out['failed']) === 0;\n} catch (Throwable $e) {\n\t$out['error'] = get_class($e) . ': ' . $e->getMessage();\n\t$out['trace'] = substr($e->getTraceAsString(), 0, 900);\n}\n\necho json_encode($out);\n"