diff --git a/runtime/history/SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3.json b/runtime/history/SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3.json new file mode 100644 index 00000000..4b61ff7b --- /dev/null +++ b/runtime/history/SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3", + "status": "OK", + "rc": 0, + "host": "pve01", + "mode": "read-only", + "component": "gram-support-codevipe-error-requeststate-rca-readonly", + "started_at_utc": "2026-09-18T06:12:40Z", + "finished_at_utc": "2026-09-18T06:12:41Z", + "reference_register_checked": true, + "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", + "error_register_checked": true, + "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", + "command_sha256": "af3e7b5d91ef4c593cbdf0d032ab8022f0bfb2da04c29aafb6bd450f1e99caf7", + "duplicate_failed_command_blocked": false, + "block_reason": null, + "execution_started": true, + "change_declared": false, + "result_contract_valid": true, + "result_contract_status": null, + "result_contract_error": null, + "command_rc": 0, + "changes_made": false, + "rollback_started": false, + "rollback_restored": null, + "mutation_outcome": "NO_MUTATION", + "sanitized": true, + "secrets_included": false, + "private_addresses_included": false, + "raw_evidence_retained_locally": true, + "raw_evidence_sha256": "7de025dbfa44e4f0c49d03b4428121cbefb1c0b7b624db402a0f60b938a6ec98", + "sanitized_output_sha256": "7de025dbfa44e4f0c49d03b4428121cbefb1c0b7b624db402a0f60b938a6ec98", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "GRAM516R5RCA3_SAFE_REPORT={\"err_truncated\":false,\"guest\":{\"error\":null,\"ok\":true,\"php_rc\":0,\"php_stderr_bytes\":0,\"php_stderr_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"runtime\":{\"error\":null,\"error_count\":4,\"error_max\":4,\"ok\":true,\"rows\":[{\"error_id\":4,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state\":{\"bytes\":160,\"collection_keys\":{\"_GET\":[\"/support/service-worker\"],\"_POST\":[]},\"fields\":{\"referrer\":{\"host\":\"codevipe.ru\",\"path\":\"/support/staff/ticket\"},\"url\":{\"host\":null,\"path\":\"/support/service-worker\"}},\"format\":\"json\",\"sha256\":\"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf\",\"top_keys\":[\"url\",\"referrer\",\"_GET\",\"_POST\"]},\"time_utc\":\"2026-09-18T05:58:47+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"},{\"error_id\":3,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state\":{\"bytes\":160,\"collection_keys\":{\"_GET\":[\"/support/service-worker\"],\"_POST\":[]},\"fields\":{\"referrer\":{\"host\":\"codevipe.ru\",\"path\":\"/support/staff/ticket\"},\"url\":{\"host\":null,\"path\":\"/support/service-worker\"}},\"format\":\"json\",\"sha256\":\"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf\",\"top_keys\":[\"url\",\"referrer\",\"_GET\",\"_POST\"]},\"time_utc\":\"2026-09-18T05:58:32+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"},{\"error_id\":2,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state\":{\"bytes\":160,\"collection_keys\":{\"_GET\":[\"/support/service-worker\"],\"_POST\":[]},\"fields\":{\"referrer\":{\"host\":\"codevipe.ru\",\"path\":\"/support/staff/ticket\"},\"url\":{\"host\":null,\"path\":\"/support/service-worker\"}},\"format\":\"json\",\"sha256\":\"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf\",\"top_keys\":[\"url\",\"referrer\",\"_GET\",\"_POST\"]},\"time_utc\":\"2026-09-18T05:58:26+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"},{\"error_id\":1,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state\":{\"bytes\":137,\"collection_keys\":{\"_GET\":[\"/support/service-worker\"],\"_POST\":[]},\"fields\":{\"referrer\":{\"host\":\"codevipe.ru\",\"path\":\"/support/staff\"},\"url\":{\"host\":null,\"path\":\"/support/service-worker\"}},\"format\":\"json\",\"sha256\":\"c809fa5b352e5cabae7067d8626171f788a8dd768fe250455dae052ff2489348\",\"top_keys\":[\"url\",\"referrer\",\"_GET\",\"_POST\"]},\"time_utc\":\"2026-09-18T05:54:03+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"}]},\"source\":{\"Gram/Support/Pub/Controller/StaffSupport.php\":{\"basename\":\"StaffSupport.php\",\"matches\":[{\"sep\":true},{\"line\":20,\"text\":\"\"},{\"line\":21,\"text\":\" if (!$visitor->user_id || !$allowed)\"},{\"line\":22,\"text\":\" {\"},{\"line\":23,\"text\":\" throw $this->exception($this->noPermission());\"},{\"line\":24,\"text\":\" }\"},{\"line\":25,\"text\":\" }\"},{\"line\":26,\"text\":\"\"},{\"line\":27,\"text\":\" public function actionIndex()\"},{\"line\":28,\"text\":\" {\"},{\"line\":29,\"text\":\" $this->assertStaff(false);\"},{\"line\":30,\"text\":\"\"},{\"line\":31,\"text\":\" $tickets = $this->repository('Gram\\\\Support:Ticket')\"},{\"line\":32,\"text\":\" ->findStaffQueue()\"},{\"line\":33,\"text\":\" ->fetch();\"},{\"line\":34,\"text\":\"\"},{\"line\":35,\"text\":\" return $this->view(\"},{\"line\":36,\"text\":\" 'Gram\\\\Support:StaffQueue',\"},{\"line\":37,\"text\":\" 'gram_support_staff_queue',\"},{\"line\":38,\"text\":\" ['tickets' => $tickets]\"},{\"line\":39,\"text\":\" );\"},{\"line\":40,\"text\":\" }\"},{\"line\":41,\"text\":\"\"},{\"line\":42,\"text\":\" public function actionTicket()\"},{\"line\":43,\"text\":\" {\"},{\"line\":44,\"text\":\" $this->assertStaff(false);\"},{\"line\":45,\"text\":\" $ticket = $this->assertTicket();\"},{\"line\":46,\"text\":\"\"},{\"line\":47,\"text\":\" $messages = $this->repository('Gram\\\\Support:Message')\"},{\"line\":48,\"text\":\" ->findAllForTicket((int)$ticket->ticket_id)\"},{\"line\":49,\"text\":\" ->fetch();\"},{\"line\":50,\"text\":\"\"},{\"line\":51,\"text\":\" return $this->view(\"},{\"line\":52,\"text\":\" 'Gram\\\\Support:StaffTicket',\"},{\"line\":53,\"text\":\" 'gram_support_staff_ticket',\"},{\"line\":54,\"text\":\" [\"},{\"line\":55,\"text\":\" 'ticket' => $ticket,\"},{\"line\":56,\"text\":\" 'messages' => $messages,\"},{\"line\":57,\"text\":\" 'statusOptions' => StatusPolicy::all()\"},{\"line\":58,\"text\":\" ]\"},{\"line\":59,\"text\":\" );\"},{\"line\":60,\"text\":\" }\"},{\"line\":61,\"text\":\"\"},{\"line\":62,\"text\":\" public function actionReply()\"},{\"line\":63,\"text\":\" {\"},{\"line\":64,\"text\":\" $this->assertPostOnly();\"},{\"line\":65,\"text\":\" $this->assertStaff(true);\"},{\"line\":66,\"text\":\"\"},{\"line\":67,\"text\":\" $ticket = $this->assertTicket();\"},{\"line\":68,\"text\":\" $isInternal = (bool)$this->filter('is_internal', 'bool');\"},{\"line\":69,\"text\":\"\"},{\"line\":70,\"text\":\" if ($isInternal\"},{\"line\":71,\"text\":\" && !\\\\XF::visitor()->hasPermission('gramSupport', 'internalNotes'))\"},{\"line\":72,\"text\":\" {\"},{\"line\":73,\"text\":\" return $this->noPermission();\"},{\"line\":74,\"text\":\" }\"},{\"line\":75,\"text\":\"\"},{\"line\":76,\"text\":\" /** @var Reply $reply */\"},{\"line\":77,\"text\":\" $reply = $this->service(Reply::class);\"},{\"line\":78,\"text\":\" $reply->add(\"},{\"line\":79,\"text\":\" $ticket,\"},{\"line\":80,\"text\":\" $this->filter('message', 'str'),\"},{\"line\":81,\"text\":\" true,\"},{\"line\":82,\"text\":\" $isInternal\"},{\"line\":83,\"text\":\" );\"},{\"line\":84,\"text\":\"\"},{\"line\":85,\"text\":\" return $this->redirect(\"},{\"line\":86,\"text\":\" $this->buildLink('support/staff/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":87,\"text\":\" );\"},{\"line\":88,\"text\":\" }\"},{\"line\":89,\"text\":\"\"},{\"line\":90,\"text\":\" public function actionUpdate()\"},{\"line\":91,\"text\":\" {\"},{\"line\":92,\"text\":\" $this->assertPostOnly();\"},{\"line\":93,\"text\":\" $this->assertStaff(true);\"},{\"line\":94,\"text\":\"\"},{\"line\":95,\"text\":\" $ticket = $this->assertTicket();\"},{\"line\":96,\"text\":\" $newStatus = trim($this->filter('status', 'str'));\"},{\"line\":97,\"text\":\" $assignedUserId = (int)$this->filter('assigned_user_id', 'uint');\"},{\"sep\":true},{\"line\":100,\"text\":\" $staffUpdate = $this->service(StaffUpdate::class);\"},{\"line\":101,\"text\":\" $staffUpdate->validateTransition((string)$ticket->status, $newStatus);\"},{\"line\":102,\"text\":\"\"},{\"line\":103,\"text\":\" if ($assignedUserId > 0)\"},{\"line\":104,\"text\":\" {\"},{\"line\":105,\"text\":\" if (!\\\\XF::visitor()->hasPermission('gramSupport', 'assign'))\"},{\"line\":106,\"text\":\" {\"},{\"line\":107,\"text\":\" return $this->noPermission();\"},{\"line\":108,\"text\":\" }\"},{\"line\":109,\"text\":\"\"},{\"line\":110,\"text\":\" $assigned = \\\\XF::em()->find('XF:User', $assignedUserId);\"},{\"line\":111,\"text\":\" if (!$assigned\"},{\"line\":112,\"text\":\" || (!$assigned->hasPermission('gramSupport', 'viewAll')\"},{\"line\":113,\"text\":\" && !$assigned->hasPermission('gramSupport', 'manage')))\"},{\"line\":114,\"text\":\" {\"},{\"line\":115,\"text\":\" return $this->error(\\\\XF::phrase('gram_support_assignee_invalid'));\"},{\"line\":116,\"text\":\" }\"},{\"line\":117,\"text\":\" }\"},{\"line\":118,\"text\":\"\"},{\"line\":119,\"text\":\" $oldStatus = (string)$ticket->status;\"},{\"line\":120,\"text\":\" $oldAssigned = (int)$ticket->assigned_user_id;\"},{\"line\":121,\"text\":\"\"},{\"line\":122,\"text\":\" $db = \\\\XF::db();\"},{\"sep\":true},{\"line\":154,\"text\":\" {\"},{\"line\":155,\"text\":\" $db->rollback();\"},{\"line\":156,\"text\":\" throw $e;\"},{\"line\":157,\"text\":\" }\"},{\"line\":158,\"text\":\"\"},{\"line\":159,\"text\":\" (new EventDispatcher())->dispatchSafely($event, $ticket);\"},{\"line\":160,\"text\":\"\"},{\"line\":161,\"text\":\" return $this->redirect(\"},{\"line\":162,\"text\":\" $this->buildLink('support/staff/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":163,\"text\":\" );\"},{\"line\":164,\"text\":\" }\"},{\"line\":165,\"text\":\"\"},{\"line\":166,\"text\":\" private function assertTicket()\"},{\"line\":167,\"text\":\" {\"},{\"line\":168,\"text\":\" $ticket = $this->repository('Gram\\\\Support:Ticket')\"},{\"line\":169,\"text\":\" ->findByPublicRef($this->filter('ref', 'str'));\"},{\"line\":170,\"text\":\"\"},{\"line\":171,\"text\":\" if (!$ticket)\"},{\"line\":172,\"text\":\" {\"},{\"line\":173,\"text\":\" throw $this->exception($this->notFound());\"},{\"line\":174,\"text\":\" }\"},{\"line\":175,\"text\":\"\"},{\"line\":176,\"text\":\" return $ticket;\"},{\"line\":177,\"text\":\" }\"},{\"line\":178,\"text\":\"}\"}],\"present\":true},\"Gram/Support/Pub/Controller/Support.php\":{\"basename\":\"Support.php\",\"matches\":[{\"sep\":true},{\"line\":10,\"text\":\"use Gram\\\\Support\\\\Service\\\\Ticket\\\\Creator;\"},{\"line\":11,\"text\":\"use Gram\\\\Support\\\\Service\\\\Ticket\\\\Reply;\"},{\"line\":12,\"text\":\"use Gram\\\\Support\\\\Util\\\\SiteConfig;\"},{\"line\":13,\"text\":\"use XF\\\\Mvc\\\\ParameterBag;\"},{\"line\":14,\"text\":\"\"},{\"line\":15,\"text\":\"final class Support extends \\\\XF\\\\Pub\\\\Controller\\\\AbstractController\"},{\"line\":16,\"text\":\"{\"},{\"line\":17,\"text\":\" public function actionIndex()\"},{\"line\":18,\"text\":\" {\"},{\"line\":19,\"text\":\" if (\\\\XF::visitor()->user_id)\"},{\"line\":20,\"text\":\" {\"},{\"line\":21,\"text\":\" return $this->redirect($this->buildLink('account/support'));\"},{\"line\":22,\"text\":\" }\"},{\"line\":23,\"text\":\"\"},{\"line\":24,\"text\":\" return $this->redirect($this->buildLink('support/create'));\"},{\"line\":25,\"text\":\" }\"},{\"line\":26,\"text\":\"\"},{\"line\":27,\"text\":\" public function actionCreate()\"},{\"line\":28,\"text\":\" {\"},{\"line\":29,\"text\":\" $visitor = \\\\XF::visitor();\"},{\"line\":30,\"text\":\"\"},{\"line\":31,\"text\":\" if ($visitor->user_id && !$visitor->hasPermission('gramSupport', 'create'))\"},{\"line\":32,\"text\":\" {\"},{\"line\":33,\"text\":\" return $this->noPermission();\"},{\"line\":34,\"text\":\" }\"},{\"line\":35,\"text\":\"\"},{\"line\":36,\"text\":\" if ($this->isPost())\"},{\"line\":37,\"text\":\" {\"},{\"line\":38,\"text\":\" $this->assertPostOnly();\"},{\"line\":39,\"text\":\"\"},{\"line\":40,\"text\":\" $email = $this->filter('email', 'str');\"},{\"sep\":true},{\"line\":42,\"text\":\" $subject = $this->filter('subject', 'str');\"},{\"line\":43,\"text\":\" $message = $this->filter('message', 'str');\"},{\"line\":44,\"text\":\"\"},{\"line\":45,\"text\":\" if (!$visitor->user_id)\"},{\"line\":46,\"text\":\" {\"},{\"line\":47,\"text\":\" if (!$this->captchaIsValid(true))\"},{\"line\":48,\"text\":\" {\"},{\"line\":49,\"text\":\" return $this->error(\"},{\"line\":50,\"text\":\" \\\\XF::phrase('did_not_complete_the_captcha_verification_properly')\"},{\"line\":51,\"text\":\" );\"},{\"line\":52,\"text\":\" }\"},{\"line\":53,\"text\":\"\"},{\"line\":54,\"text\":\" /** @var RateLimiter $rateLimiter */\"},{\"line\":55,\"text\":\" $rateLimiter = $this->service(RateLimiter::class);\"},{\"line\":56,\"text\":\" $allowed = $rateLimiter->consumeGuest(\"},{\"sep\":true},{\"line\":58,\"text\":\" $email,\"},{\"line\":59,\"text\":\" SiteConfig::guestRateLimitCount(),\"},{\"line\":60,\"text\":\" SiteConfig::guestRateLimitWindowSeconds()\"},{\"line\":61,\"text\":\" );\"},{\"line\":62,\"text\":\"\"},{\"line\":63,\"text\":\" if (!$allowed)\"},{\"line\":64,\"text\":\" {\"},{\"line\":65,\"text\":\" return $this->error(\\\\XF::phrase('gram_support_rate_limited'));\"},{\"line\":66,\"text\":\" }\"},{\"line\":67,\"text\":\" }\"},{\"line\":68,\"text\":\"\"},{\"line\":69,\"text\":\" $upload = $this->request->getFile('screenshot', false, false);\"},{\"line\":70,\"text\":\" $tempHash = bin2hex(random_bytes(16));\"},{\"line\":71,\"text\":\" $attachmentFlow = new GuestTicketCreateAttachmentFlow();\"},{\"line\":72,\"text\":\"\"},{\"sep\":true},{\"line\":106,\"text\":\" }\"},{\"line\":107,\"text\":\" }\"},{\"line\":108,\"text\":\"\"},{\"line\":109,\"text\":\" if ($created['guest_secret'])\"},{\"line\":110,\"text\":\" {\"},{\"line\":111,\"text\":\" $secret = (string)$created['guest_secret'];\"},{\"line\":112,\"text\":\"\"},{\"line\":113,\"text\":\" return $this->view(\"},{\"line\":114,\"text\":\" 'Gram\\\\Support:CreatedGuest',\"},{\"line\":115,\"text\":\" 'gram_support_created_guest',\"},{\"line\":116,\"text\":\" [\"},{\"line\":117,\"text\":\" 'ticket' => $ticket,\"},{\"line\":118,\"text\":\" 'accessCode' => $secret,\"},{\"line\":119,\"text\":\" 'magicLink' => $this->buildLink('canonical:support/access') . '#token=' . rawurlencode($secret)\"},{\"line\":120,\"text\":\" ]\"},{\"line\":121,\"text\":\" );\"},{\"line\":122,\"text\":\" }\"},{\"line\":123,\"text\":\"\"},{\"line\":124,\"text\":\" return $this->redirect(\"},{\"line\":125,\"text\":\" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":126,\"text\":\" );\"},{\"line\":127,\"text\":\" }\"},{\"line\":128,\"text\":\"\"},{\"line\":129,\"text\":\" return $this->view(\"},{\"line\":130,\"text\":\" 'Gram\\\\Support:Create',\"},{\"line\":131,\"text\":\" 'gram_support_create',\"},{\"line\":132,\"text\":\" ['forceCaptcha' => !$visitor->user_id]\"},{\"line\":133,\"text\":\" );\"},{\"line\":134,\"text\":\" }\"},{\"line\":135,\"text\":\"\"},{\"line\":136,\"text\":\" public function actionAccess()\"},{\"line\":137,\"text\":\" {\"},{\"line\":138,\"text\":\" if ($this->isPost())\"},{\"line\":139,\"text\":\" {\"},{\"line\":140,\"text\":\" $this->assertPostOnly();\"},{\"line\":141,\"text\":\"\"},{\"line\":142,\"text\":\" $secret = trim($this->filter('access_code', 'str'));\"},{\"line\":143,\"text\":\" if ($secret === '')\"},{\"line\":144,\"text\":\" {\"},{\"line\":145,\"text\":\" return $this->error(\\\\XF::phrase('gram_support_access_code_required'));\"},{\"line\":146,\"text\":\" }\"},{\"line\":147,\"text\":\"\"},{\"line\":148,\"text\":\" $ticket = $this->repository('Gram\\\\Support:Ticket')\"},{\"line\":149,\"text\":\" ->findGuestAccessibleBySecret($secret, \\\\XF::$time);\"},{\"line\":150,\"text\":\"\"},{\"line\":151,\"text\":\" if (!$ticket)\"},{\"line\":152,\"text\":\" {\"},{\"line\":153,\"text\":\" return $this->error(\\\\XF::phrase('gram_support_access_invalid'));\"},{\"line\":154,\"text\":\" }\"},{\"line\":155,\"text\":\"\"},{\"line\":156,\"text\":\" GuestTicketSession::grant($ticket);\"},{\"line\":157,\"text\":\"\"},{\"line\":158,\"text\":\" return $this->redirect(\"},{\"line\":159,\"text\":\" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":160,\"text\":\" );\"},{\"line\":161,\"text\":\" }\"},{\"line\":162,\"text\":\"\"},{\"line\":163,\"text\":\" return $this->view(\"},{\"line\":164,\"text\":\" 'Gram\\\\Support:Access',\"},{\"line\":165,\"text\":\" 'gram_support_access',\"},{\"line\":166,\"text\":\" []\"},{\"line\":167,\"text\":\" );\"},{\"line\":168,\"text\":\" }\"},{\"line\":169,\"text\":\"\"},{\"line\":170,\"text\":\" public function actionTicket()\"},{\"line\":171,\"text\":\" {\"},{\"line\":172,\"text\":\" $ticket = $this->assertViewableTicketByRef($this->filter('ref', 'str'));\"},{\"line\":173,\"text\":\"\"},{\"line\":174,\"text\":\" $messages = $this->repository('Gram\\\\Support:Message')\"},{\"line\":175,\"text\":\" ->findPublicForTicket((int)$ticket->ticket_id)\"},{\"line\":176,\"text\":\" ->fetch();\"},{\"line\":177,\"text\":\"\"},{\"line\":178,\"text\":\" return $this->view(\"},{\"line\":179,\"text\":\" 'Gram\\\\Support:Ticket',\"},{\"line\":180,\"text\":\" 'gram_support_ticket',\"},{\"line\":181,\"text\":\" [\"},{\"line\":182,\"text\":\" 'ticket' => $ticket,\"},{\"line\":183,\"text\":\" 'messages' => $messages\"},{\"line\":184,\"text\":\" ]\"},{\"line\":185,\"text\":\" );\"},{\"line\":186,\"text\":\" }\"},{\"line\":187,\"text\":\"\"},{\"line\":188,\"text\":\" public function actionReply()\"},{\"line\":189,\"text\":\" {\"},{\"line\":190,\"text\":\" $this->assertPostOnly();\"},{\"line\":191,\"text\":\"\"},{\"line\":192,\"text\":\" $ticket = $this->assertViewableTicketByRef($this->filter('ref', 'str'));\"},{\"line\":193,\"text\":\" $visitor = \\\\XF::visitor();\"},{\"line\":194,\"text\":\"\"},{\"line\":195,\"text\":\" if ($visitor->user_id)\"},{\"line\":196,\"text\":\" {\"},{\"line\":197,\"text\":\" if ((int)$ticket->user_id !== (int)$visitor->user_id\"},{\"line\":198,\"text\":\" || !$visitor->hasPermission('gramSupport', 'replyOwn'))\"},{\"line\":199,\"text\":\" {\"},{\"line\":200,\"text\":\" return $this->noPermission();\"},{\"line\":201,\"text\":\" }\"},{\"line\":202,\"text\":\" }\"},{\"line\":203,\"text\":\" elseif (!GuestTicketSession::hasGrant($ticket))\"},{\"line\":204,\"text\":\" {\"},{\"line\":205,\"text\":\" return $this->noPermission();\"},{\"line\":206,\"text\":\" }\"},{\"line\":207,\"text\":\"\"},{\"line\":208,\"text\":\" $message = $this->filter('message', 'str');\"},{\"line\":209,\"text\":\"\"},{\"line\":210,\"text\":\" /** @var Reply $reply */\"},{\"line\":211,\"text\":\" $reply = $this->service(Reply::class);\"},{\"line\":212,\"text\":\" $reply->add($ticket, $message, false, false);\"},{\"line\":213,\"text\":\"\"},{\"line\":214,\"text\":\" return $this->redirect(\"},{\"line\":215,\"text\":\" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":216,\"text\":\" );\"},{\"line\":217,\"text\":\" }\"},{\"line\":218,\"text\":\"\"},{\"line\":219,\"text\":\" private function assertViewableTicketByRef(string $publicRef)\"},{\"line\":220,\"text\":\" {\"}],\"present\":true},\"XF/Http/Response.php\":{\"basename\":\"Response.php\",\"matches\":[{\"sep\":true},{\"line\":240,\"text\":\"\\t\\treturn $name;\"},{\"line\":241,\"text\":\"\\t}\"},{\"line\":242,\"text\":\"\"},{\"line\":243,\"text\":\"\\tpublic function body($body = null)\"},{\"line\":244,\"text\":\"\\t{\"},{\"line\":245,\"text\":\"\\t\\tif ($body === null)\"},{\"line\":246,\"text\":\"\\t\\t{\"},{\"line\":247,\"text\":\"\\t\\t\\treturn $this->body;\"},{\"line\":248,\"text\":\"\\t\\t}\"},{\"line\":249,\"text\":\"\"},{\"line\":250,\"text\":\"\\t\\t$this->body = $body;\"},{\"line\":251,\"text\":\"\"},{\"line\":252,\"text\":\"\\t\\treturn $this;\"},{\"line\":253,\"text\":\"\\t}\"},{\"line\":254,\"text\":\"\"},{\"line\":255,\"text\":\"\\tpublic function responseFile($fileName)\"},{\"line\":256,\"text\":\"\\t{\"},{\"line\":257,\"text\":\"\\t\\treturn new ResponseFile($fileName);\"},{\"sep\":true},{\"line\":282,\"text\":\"\\t\\t}\"},{\"line\":283,\"text\":\"\"},{\"line\":284,\"text\":\"\\t\\t$this->includeContentLength = (bool) $use;\"},{\"line\":285,\"text\":\"\"},{\"line\":286,\"text\":\"\\t\\treturn $this;\"},{\"line\":287,\"text\":\"\\t}\"},{\"line\":288,\"text\":\"\"},{\"line\":289,\"text\":\"\\tpublic function send(?Request $request = null)\"},{\"line\":290,\"text\":\"\\t{\"},{\"line\":291,\"text\":\"\\t\\t$this->prepareForOutput($request);\"},{\"line\":292,\"text\":\"\\t\\t$this->sendHeaders();\"},{\"line\":293,\"text\":\"\\t\\t$this->sendBody();\"},{\"line\":294,\"text\":\"\\t}\"},{\"line\":295,\"text\":\"\"},{\"line\":296,\"text\":\"\\tpublic function prepareForOutput(?Request $request = null)\"},{\"sep\":true},{\"line\":381,\"text\":\"\\tpublic function removeCookie($name)\"},{\"line\":382,\"text\":\"\\t{\"},{\"line\":383,\"text\":\"\\t\\tunset($this->cookies[$name]);\"},{\"line\":384,\"text\":\"\"},{\"line\":385,\"text\":\"\\t\\treturn $this;\"},{\"line\":386,\"text\":\"\\t}\"},{\"line\":387,\"text\":\"\"},{\"line\":388,\"text\":\"\\tpublic function sendHeaders()\"},{\"line\":389,\"text\":\"\\t{\"},{\"line\":390,\"text\":\"\\t\\tforeach ($this->headers AS $key => $value)\"},{\"line\":391,\"text\":\"\\t\\t{\"},{\"line\":392,\"text\":\"\\t\\t\\tif (is_array($value))\"},{\"line\":393,\"text\":\"\\t\\t\\t{\"},{\"line\":394,\"text\":\"\\t\\t\\t\\tforeach ($value AS $innerValue)\"},{\"line\":395,\"text\":\"\\t\\t\\t\\t{\"},{\"sep\":true},{\"line\":446,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":447,\"text\":\"\"},{\"line\":448,\"text\":\"\\t\\t\\t\\tcall_user_func('setcookie', $name, $value, $options);\"},{\"line\":449,\"text\":\"\\t\\t\\t}\"},{\"line\":450,\"text\":\"\\t\\t}\"},{\"line\":451,\"text\":\"\\t}\"},{\"line\":452,\"text\":\"\"},{\"line\":453,\"text\":\"\\tpublic function sendBody()\"},{\"line\":454,\"text\":\"\\t{\"},{\"line\":455,\"text\":\"\\t\\tif ($this->body instanceof ResponseFile)\"},{\"line\":456,\"text\":\"\\t\\t{\"},{\"line\":457,\"text\":\"\\t\\t\\tif ($this->includeContentLength)\"},{\"line\":458,\"text\":\"\\t\\t\\t{\"},{\"line\":459,\"text\":\"\\t\\t\\t\\theader('Content-Length: ' . $this->body->getLength());\"},{\"line\":460,\"text\":\"\\t\\t\\t}\"},{\"line\":461,\"text\":\"\"},{\"line\":462,\"text\":\"\\t\\t\\t$this->body->output();\"},{\"line\":463,\"text\":\"\\t\\t}\"},{\"line\":464,\"text\":\"\\t\\telse if ($this->body instanceof ResponseStream)\"},{\"line\":465,\"text\":\"\\t\\t{\"},{\"line\":466,\"text\":\"\\t\\t\\tif ($this->includeContentLength)\"},{\"line\":467,\"text\":\"\\t\\t\\t{\"},{\"line\":468,\"text\":\"\\t\\t\\t\\t$length = $this->body->getLength();\"},{\"line\":469,\"text\":\"\\t\\t\\t\\tif ($length !== null)\"},{\"line\":470,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":471,\"text\":\"\\t\\t\\t\\t\\theader('Content-Length: ' . $length);\"},{\"line\":472,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":473,\"text\":\"\\t\\t\\t}\"},{\"line\":474,\"text\":\"\"},{\"line\":475,\"text\":\"\\t\\t\\t$this->body->output();\"},{\"line\":476,\"text\":\"\\t\\t}\"},{\"line\":477,\"text\":\"\\t\\telse\"},{\"line\":478,\"text\":\"\\t\\t{\"},{\"line\":479,\"text\":\"\\t\\t\\tif ($this->compress)\"},{\"line\":480,\"text\":\"\\t\\t\\t{\"},{\"line\":481,\"text\":\"\\t\\t\\t\\t$toPrint = gzencode($this->body, 9);\"},{\"line\":482,\"text\":\"\\t\\t\\t}\"},{\"line\":483,\"text\":\"\\t\\t\\telse\"},{\"line\":484,\"text\":\"\\t\\t\\t{\"},{\"line\":485,\"text\":\"\\t\\t\\t\\t$toPrint = $this->body;\"},{\"line\":486,\"text\":\"\\t\\t\\t}\"},{\"line\":487,\"text\":\"\"},{\"line\":488,\"text\":\"\\t\\t\\tif ($this->includeContentLength)\"},{\"line\":489,\"text\":\"\\t\\t\\t{\"},{\"line\":490,\"text\":\"\\t\\t\\t\\theader('Content-Length: ' . strlen($toPrint));\"},{\"line\":491,\"text\":\"\\t\\t\\t}\"},{\"line\":492,\"text\":\"\"},{\"line\":493,\"text\":\"\\t\\t\\techo $toPrint;\"},{\"line\":494,\"text\":\"\\t\\t}\"},{\"line\":495,\"text\":\"\\t}\"},{\"line\":496,\"text\":\"\"},{\"line\":497,\"text\":\"\\tpublic function contentIsCompressible(Request $request)\"},{\"line\":498,\"text\":\"\\t{\"},{\"line\":499,\"text\":\"\\t\\tif (\"},{\"line\":500,\"text\":\"\\t\\t\\t!is_string($this->body)\"},{\"line\":501,\"text\":\"\\t\\t\\t|| !preg_match('#^(?:text/|application/(?:json|xml|rss\\\\+xml)$)#i', $this->contentType)\"},{\"line\":502,\"text\":\"\\t\\t\\t|| strpos($request->getServer('HTTP_ACCEPT_ENCODING', ''), 'gzip') === false\"},{\"line\":503,\"text\":\"\\t\\t)\"},{\"line\":504,\"text\":\"\\t\\t{\"},{\"line\":505,\"text\":\"\\t\\t\\treturn false;\"},{\"line\":506,\"text\":\"\\t\\t}\"},{\"line\":507,\"text\":\"\"},{\"line\":508,\"text\":\"\\t\\tif (!function_exists('gzencode'))\"},{\"line\":509,\"text\":\"\\t\\t{\"},{\"line\":510,\"text\":\"\\t\\t\\treturn false;\"},{\"line\":511,\"text\":\"\\t\\t}\"},{\"line\":512,\"text\":\"\"},{\"line\":513,\"text\":\"\\t\\treturn (strlen($this->body) >= 20);\"},{\"line\":514,\"text\":\"\\t}\"},{\"line\":515,\"text\":\"}\"}],\"present\":true}}},\"guest_stderr_present\":false,\"inner_rc\":0,\"ok\":true,\"out_truncated\":false,\"transport_rc\":0,\"transport_stderr_bytes\":0,\"transport_stderr_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"}\nGRAM516R5RCA3_DECISION=PASS_ERROR_REQUESTSTATE_AND_SOURCE_CAPTURED\nGRAM516R5RCA3_NEXT_GATE=CLASSIFY_CURRENT_RUNTIME_DEFECT\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\n" +} diff --git a/runtime/history/SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3.txt b/runtime/history/SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3.txt new file mode 100644 index 00000000..4091590c --- /dev/null +++ b/runtime/history/SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3.txt @@ -0,0 +1,36 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3 +STATUS=OK +RC=0 +HOST=pve01 +MODE=read-only +COMPONENT=gram-support-codevipe-error-requeststate-rca-readonly +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 +COMMAND_SHA256=af3e7b5d91ef4c593cbdf0d032ab8022f0bfb2da04c29aafb6bd450f1e99caf7 +DUPLICATE_FAILED_COMMAND_BLOCKED=false +EXECUTION_STARTED=true +CHANGE_DECLARED=false +RESULT_CONTRACT_VALID=true +RESULT_CONTRACT_STATUS=NOT_APPLICABLE +RESULT_CONTRACT_ERROR=NONE +COMMAND_RC=0 +CHANGES_MADE=false +ROLLBACK_STARTED=false +ROLLBACK_RESTORED=null +MUTATION_OUTCOME=NO_MUTATION +SANITIZED=yes +SECRETS_INCLUDED=no +PRIVATE_ADDRESSES_INCLUDED=no +RAW_EVIDENCE_SHA256=7de025dbfa44e4f0c49d03b4428121cbefb1c0b7b624db402a0f60b938a6ec98 +SANITIZED_OUTPUT_SHA256=7de025dbfa44e4f0c49d03b4428121cbefb1c0b7b624db402a0f60b938a6ec98 +OUTPUT_BEGIN +GRAM516R5RCA3_SAFE_REPORT={"err_truncated":false,"guest":{"error":null,"ok":true,"php_rc":0,"php_stderr_bytes":0,"php_stderr_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","runtime":{"error":null,"error_count":4,"error_max":4,"ok":true,"rows":[{"error_id":4,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state":{"bytes":160,"collection_keys":{"_GET":["/support/service-worker"],"_POST":[]},"fields":{"referrer":{"host":"codevipe.ru","path":"/support/staff/ticket"},"url":{"host":null,"path":"/support/service-worker"}},"format":"json","sha256":"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf","top_keys":["url","referrer","_GET","_POST"]},"time_utc":"2026-09-18T05:58:47+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"},{"error_id":3,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state":{"bytes":160,"collection_keys":{"_GET":["/support/service-worker"],"_POST":[]},"fields":{"referrer":{"host":"codevipe.ru","path":"/support/staff/ticket"},"url":{"host":null,"path":"/support/service-worker"}},"format":"json","sha256":"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf","top_keys":["url","referrer","_GET","_POST"]},"time_utc":"2026-09-18T05:58:32+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"},{"error_id":2,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state":{"bytes":160,"collection_keys":{"_GET":["/support/service-worker"],"_POST":[]},"fields":{"referrer":{"host":"codevipe.ru","path":"/support/staff/ticket"},"url":{"host":null,"path":"/support/service-worker"}},"format":"json","sha256":"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf","top_keys":["url","referrer","_GET","_POST"]},"time_utc":"2026-09-18T05:58:26+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"},{"error_id":1,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state":{"bytes":137,"collection_keys":{"_GET":["/support/service-worker"],"_POST":[]},"fields":{"referrer":{"host":"codevipe.ru","path":"/support/staff"},"url":{"host":null,"path":"/support/service-worker"}},"format":"json","sha256":"c809fa5b352e5cabae7067d8626171f788a8dd768fe250455dae052ff2489348","top_keys":["url","referrer","_GET","_POST"]},"time_utc":"2026-09-18T05:54:03+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"}]},"source":{"Gram/Support/Pub/Controller/StaffSupport.php":{"basename":"StaffSupport.php","matches":[{"sep":true},{"line":20,"text":""},{"line":21,"text":" if (!$visitor->user_id || !$allowed)"},{"line":22,"text":" {"},{"line":23,"text":" throw $this->exception($this->noPermission());"},{"line":24,"text":" }"},{"line":25,"text":" }"},{"line":26,"text":""},{"line":27,"text":" public function actionIndex()"},{"line":28,"text":" {"},{"line":29,"text":" $this->assertStaff(false);"},{"line":30,"text":""},{"line":31,"text":" $tickets = $this->repository('Gram\\Support:Ticket')"},{"line":32,"text":" ->findStaffQueue()"},{"line":33,"text":" ->fetch();"},{"line":34,"text":""},{"line":35,"text":" return $this->view("},{"line":36,"text":" 'Gram\\Support:StaffQueue',"},{"line":37,"text":" 'gram_support_staff_queue',"},{"line":38,"text":" ['tickets' => $tickets]"},{"line":39,"text":" );"},{"line":40,"text":" }"},{"line":41,"text":""},{"line":42,"text":" public function actionTicket()"},{"line":43,"text":" {"},{"line":44,"text":" $this->assertStaff(false);"},{"line":45,"text":" $ticket = $this->assertTicket();"},{"line":46,"text":""},{"line":47,"text":" $messages = $this->repository('Gram\\Support:Message')"},{"line":48,"text":" ->findAllForTicket((int)$ticket->ticket_id)"},{"line":49,"text":" ->fetch();"},{"line":50,"text":""},{"line":51,"text":" return $this->view("},{"line":52,"text":" 'Gram\\Support:StaffTicket',"},{"line":53,"text":" 'gram_support_staff_ticket',"},{"line":54,"text":" ["},{"line":55,"text":" 'ticket' => $ticket,"},{"line":56,"text":" 'messages' => $messages,"},{"line":57,"text":" 'statusOptions' => StatusPolicy::all()"},{"line":58,"text":" ]"},{"line":59,"text":" );"},{"line":60,"text":" }"},{"line":61,"text":""},{"line":62,"text":" public function actionReply()"},{"line":63,"text":" {"},{"line":64,"text":" $this->assertPostOnly();"},{"line":65,"text":" $this->assertStaff(true);"},{"line":66,"text":""},{"line":67,"text":" $ticket = $this->assertTicket();"},{"line":68,"text":" $isInternal = (bool)$this->filter('is_internal', 'bool');"},{"line":69,"text":""},{"line":70,"text":" if ($isInternal"},{"line":71,"text":" && !\\XF::visitor()->hasPermission('gramSupport', 'internalNotes'))"},{"line":72,"text":" {"},{"line":73,"text":" return $this->noPermission();"},{"line":74,"text":" }"},{"line":75,"text":""},{"line":76,"text":" /** @var Reply $reply */"},{"line":77,"text":" $reply = $this->service(Reply::class);"},{"line":78,"text":" $reply->add("},{"line":79,"text":" $ticket,"},{"line":80,"text":" $this->filter('message', 'str'),"},{"line":81,"text":" true,"},{"line":82,"text":" $isInternal"},{"line":83,"text":" );"},{"line":84,"text":""},{"line":85,"text":" return $this->redirect("},{"line":86,"text":" $this->buildLink('support/staff/ticket', null, ['ref' => $ticket->public_ref])"},{"line":87,"text":" );"},{"line":88,"text":" }"},{"line":89,"text":""},{"line":90,"text":" public function actionUpdate()"},{"line":91,"text":" {"},{"line":92,"text":" $this->assertPostOnly();"},{"line":93,"text":" $this->assertStaff(true);"},{"line":94,"text":""},{"line":95,"text":" $ticket = $this->assertTicket();"},{"line":96,"text":" $newStatus = trim($this->filter('status', 'str'));"},{"line":97,"text":" $assignedUserId = (int)$this->filter('assigned_user_id', 'uint');"},{"sep":true},{"line":100,"text":" $staffUpdate = $this->service(StaffUpdate::class);"},{"line":101,"text":" $staffUpdate->validateTransition((string)$ticket->status, $newStatus);"},{"line":102,"text":""},{"line":103,"text":" if ($assignedUserId > 0)"},{"line":104,"text":" {"},{"line":105,"text":" if (!\\XF::visitor()->hasPermission('gramSupport', 'assign'))"},{"line":106,"text":" {"},{"line":107,"text":" return $this->noPermission();"},{"line":108,"text":" }"},{"line":109,"text":""},{"line":110,"text":" $assigned = \\XF::em()->find('XF:User', $assignedUserId);"},{"line":111,"text":" if (!$assigned"},{"line":112,"text":" || (!$assigned->hasPermission('gramSupport', 'viewAll')"},{"line":113,"text":" && !$assigned->hasPermission('gramSupport', 'manage')))"},{"line":114,"text":" {"},{"line":115,"text":" return $this->error(\\XF::phrase('gram_support_assignee_invalid'));"},{"line":116,"text":" }"},{"line":117,"text":" }"},{"line":118,"text":""},{"line":119,"text":" $oldStatus = (string)$ticket->status;"},{"line":120,"text":" $oldAssigned = (int)$ticket->assigned_user_id;"},{"line":121,"text":""},{"line":122,"text":" $db = \\XF::db();"},{"sep":true},{"line":154,"text":" {"},{"line":155,"text":" $db->rollback();"},{"line":156,"text":" throw $e;"},{"line":157,"text":" }"},{"line":158,"text":""},{"line":159,"text":" (new EventDispatcher())->dispatchSafely($event, $ticket);"},{"line":160,"text":""},{"line":161,"text":" return $this->redirect("},{"line":162,"text":" $this->buildLink('support/staff/ticket', null, ['ref' => $ticket->public_ref])"},{"line":163,"text":" );"},{"line":164,"text":" }"},{"line":165,"text":""},{"line":166,"text":" private function assertTicket()"},{"line":167,"text":" {"},{"line":168,"text":" $ticket = $this->repository('Gram\\Support:Ticket')"},{"line":169,"text":" ->findByPublicRef($this->filter('ref', 'str'));"},{"line":170,"text":""},{"line":171,"text":" if (!$ticket)"},{"line":172,"text":" {"},{"line":173,"text":" throw $this->exception($this->notFound());"},{"line":174,"text":" }"},{"line":175,"text":""},{"line":176,"text":" return $ticket;"},{"line":177,"text":" }"},{"line":178,"text":"}"}],"present":true},"Gram/Support/Pub/Controller/Support.php":{"basename":"Support.php","matches":[{"sep":true},{"line":10,"text":"use Gram\\Support\\Service\\Ticket\\Creator;"},{"line":11,"text":"use Gram\\Support\\Service\\Ticket\\Reply;"},{"line":12,"text":"use Gram\\Support\\Util\\SiteConfig;"},{"line":13,"text":"use XF\\Mvc\\ParameterBag;"},{"line":14,"text":""},{"line":15,"text":"final class Support extends \\XF\\Pub\\Controller\\AbstractController"},{"line":16,"text":"{"},{"line":17,"text":" public function actionIndex()"},{"line":18,"text":" {"},{"line":19,"text":" if (\\XF::visitor()->user_id)"},{"line":20,"text":" {"},{"line":21,"text":" return $this->redirect($this->buildLink('account/support'));"},{"line":22,"text":" }"},{"line":23,"text":""},{"line":24,"text":" return $this->redirect($this->buildLink('support/create'));"},{"line":25,"text":" }"},{"line":26,"text":""},{"line":27,"text":" public function actionCreate()"},{"line":28,"text":" {"},{"line":29,"text":" $visitor = \\XF::visitor();"},{"line":30,"text":""},{"line":31,"text":" if ($visitor->user_id && !$visitor->hasPermission('gramSupport', 'create'))"},{"line":32,"text":" {"},{"line":33,"text":" return $this->noPermission();"},{"line":34,"text":" }"},{"line":35,"text":""},{"line":36,"text":" if ($this->isPost())"},{"line":37,"text":" {"},{"line":38,"text":" $this->assertPostOnly();"},{"line":39,"text":""},{"line":40,"text":" $email = $this->filter('email', 'str');"},{"sep":true},{"line":42,"text":" $subject = $this->filter('subject', 'str');"},{"line":43,"text":" $message = $this->filter('message', 'str');"},{"line":44,"text":""},{"line":45,"text":" if (!$visitor->user_id)"},{"line":46,"text":" {"},{"line":47,"text":" if (!$this->captchaIsValid(true))"},{"line":48,"text":" {"},{"line":49,"text":" return $this->error("},{"line":50,"text":" \\XF::phrase('did_not_complete_the_captcha_verification_properly')"},{"line":51,"text":" );"},{"line":52,"text":" }"},{"line":53,"text":""},{"line":54,"text":" /** @var RateLimiter $rateLimiter */"},{"line":55,"text":" $rateLimiter = $this->service(RateLimiter::class);"},{"line":56,"text":" $allowed = $rateLimiter->consumeGuest("},{"sep":true},{"line":58,"text":" $email,"},{"line":59,"text":" SiteConfig::guestRateLimitCount(),"},{"line":60,"text":" SiteConfig::guestRateLimitWindowSeconds()"},{"line":61,"text":" );"},{"line":62,"text":""},{"line":63,"text":" if (!$allowed)"},{"line":64,"text":" {"},{"line":65,"text":" return $this->error(\\XF::phrase('gram_support_rate_limited'));"},{"line":66,"text":" }"},{"line":67,"text":" }"},{"line":68,"text":""},{"line":69,"text":" $upload = $this->request->getFile('screenshot', false, false);"},{"line":70,"text":" $tempHash = bin2hex(random_bytes(16));"},{"line":71,"text":" $attachmentFlow = new GuestTicketCreateAttachmentFlow();"},{"line":72,"text":""},{"sep":true},{"line":106,"text":" }"},{"line":107,"text":" }"},{"line":108,"text":""},{"line":109,"text":" if ($created['guest_secret'])"},{"line":110,"text":" {"},{"line":111,"text":" $secret = (string)$created['guest_secret'];"},{"line":112,"text":""},{"line":113,"text":" return $this->view("},{"line":114,"text":" 'Gram\\Support:CreatedGuest',"},{"line":115,"text":" 'gram_support_created_guest',"},{"line":116,"text":" ["},{"line":117,"text":" 'ticket' => $ticket,"},{"line":118,"text":" 'accessCode' => $secret,"},{"line":119,"text":" 'magicLink' => $this->buildLink('canonical:support/access') . '#token=' . rawurlencode($secret)"},{"line":120,"text":" ]"},{"line":121,"text":" );"},{"line":122,"text":" }"},{"line":123,"text":""},{"line":124,"text":" return $this->redirect("},{"line":125,"text":" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])"},{"line":126,"text":" );"},{"line":127,"text":" }"},{"line":128,"text":""},{"line":129,"text":" return $this->view("},{"line":130,"text":" 'Gram\\Support:Create',"},{"line":131,"text":" 'gram_support_create',"},{"line":132,"text":" ['forceCaptcha' => !$visitor->user_id]"},{"line":133,"text":" );"},{"line":134,"text":" }"},{"line":135,"text":""},{"line":136,"text":" public function actionAccess()"},{"line":137,"text":" {"},{"line":138,"text":" if ($this->isPost())"},{"line":139,"text":" {"},{"line":140,"text":" $this->assertPostOnly();"},{"line":141,"text":""},{"line":142,"text":" $secret = trim($this->filter('access_code', 'str'));"},{"line":143,"text":" if ($secret === '')"},{"line":144,"text":" {"},{"line":145,"text":" return $this->error(\\XF::phrase('gram_support_access_code_required'));"},{"line":146,"text":" }"},{"line":147,"text":""},{"line":148,"text":" $ticket = $this->repository('Gram\\Support:Ticket')"},{"line":149,"text":" ->findGuestAccessibleBySecret($secret, \\XF::$time);"},{"line":150,"text":""},{"line":151,"text":" if (!$ticket)"},{"line":152,"text":" {"},{"line":153,"text":" return $this->error(\\XF::phrase('gram_support_access_invalid'));"},{"line":154,"text":" }"},{"line":155,"text":""},{"line":156,"text":" GuestTicketSession::grant($ticket);"},{"line":157,"text":""},{"line":158,"text":" return $this->redirect("},{"line":159,"text":" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])"},{"line":160,"text":" );"},{"line":161,"text":" }"},{"line":162,"text":""},{"line":163,"text":" return $this->view("},{"line":164,"text":" 'Gram\\Support:Access',"},{"line":165,"text":" 'gram_support_access',"},{"line":166,"text":" []"},{"line":167,"text":" );"},{"line":168,"text":" }"},{"line":169,"text":""},{"line":170,"text":" public function actionTicket()"},{"line":171,"text":" {"},{"line":172,"text":" $ticket = $this->assertViewableTicketByRef($this->filter('ref', 'str'));"},{"line":173,"text":""},{"line":174,"text":" $messages = $this->repository('Gram\\Support:Message')"},{"line":175,"text":" ->findPublicForTicket((int)$ticket->ticket_id)"},{"line":176,"text":" ->fetch();"},{"line":177,"text":""},{"line":178,"text":" return $this->view("},{"line":179,"text":" 'Gram\\Support:Ticket',"},{"line":180,"text":" 'gram_support_ticket',"},{"line":181,"text":" ["},{"line":182,"text":" 'ticket' => $ticket,"},{"line":183,"text":" 'messages' => $messages"},{"line":184,"text":" ]"},{"line":185,"text":" );"},{"line":186,"text":" }"},{"line":187,"text":""},{"line":188,"text":" public function actionReply()"},{"line":189,"text":" {"},{"line":190,"text":" $this->assertPostOnly();"},{"line":191,"text":""},{"line":192,"text":" $ticket = $this->assertViewableTicketByRef($this->filter('ref', 'str'));"},{"line":193,"text":" $visitor = \\XF::visitor();"},{"line":194,"text":""},{"line":195,"text":" if ($visitor->user_id)"},{"line":196,"text":" {"},{"line":197,"text":" if ((int)$ticket->user_id !== (int)$visitor->user_id"},{"line":198,"text":" || !$visitor->hasPermission('gramSupport', 'replyOwn'))"},{"line":199,"text":" {"},{"line":200,"text":" return $this->noPermission();"},{"line":201,"text":" }"},{"line":202,"text":" }"},{"line":203,"text":" elseif (!GuestTicketSession::hasGrant($ticket))"},{"line":204,"text":" {"},{"line":205,"text":" return $this->noPermission();"},{"line":206,"text":" }"},{"line":207,"text":""},{"line":208,"text":" $message = $this->filter('message', 'str');"},{"line":209,"text":""},{"line":210,"text":" /** @var Reply $reply */"},{"line":211,"text":" $reply = $this->service(Reply::class);"},{"line":212,"text":" $reply->add($ticket, $message, false, false);"},{"line":213,"text":""},{"line":214,"text":" return $this->redirect("},{"line":215,"text":" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])"},{"line":216,"text":" );"},{"line":217,"text":" }"},{"line":218,"text":""},{"line":219,"text":" private function assertViewableTicketByRef(string $publicRef)"},{"line":220,"text":" {"}],"present":true},"XF/Http/Response.php":{"basename":"Response.php","matches":[{"sep":true},{"line":240,"text":"\t\treturn $name;"},{"line":241,"text":"\t}"},{"line":242,"text":""},{"line":243,"text":"\tpublic function body($body = null)"},{"line":244,"text":"\t{"},{"line":245,"text":"\t\tif ($body === null)"},{"line":246,"text":"\t\t{"},{"line":247,"text":"\t\t\treturn $this->body;"},{"line":248,"text":"\t\t}"},{"line":249,"text":""},{"line":250,"text":"\t\t$this->body = $body;"},{"line":251,"text":""},{"line":252,"text":"\t\treturn $this;"},{"line":253,"text":"\t}"},{"line":254,"text":""},{"line":255,"text":"\tpublic function responseFile($fileName)"},{"line":256,"text":"\t{"},{"line":257,"text":"\t\treturn new ResponseFile($fileName);"},{"sep":true},{"line":282,"text":"\t\t}"},{"line":283,"text":""},{"line":284,"text":"\t\t$this->includeContentLength = (bool) $use;"},{"line":285,"text":""},{"line":286,"text":"\t\treturn $this;"},{"line":287,"text":"\t}"},{"line":288,"text":""},{"line":289,"text":"\tpublic function send(?Request $request = null)"},{"line":290,"text":"\t{"},{"line":291,"text":"\t\t$this->prepareForOutput($request);"},{"line":292,"text":"\t\t$this->sendHeaders();"},{"line":293,"text":"\t\t$this->sendBody();"},{"line":294,"text":"\t}"},{"line":295,"text":""},{"line":296,"text":"\tpublic function prepareForOutput(?Request $request = null)"},{"sep":true},{"line":381,"text":"\tpublic function removeCookie($name)"},{"line":382,"text":"\t{"},{"line":383,"text":"\t\tunset($this->cookies[$name]);"},{"line":384,"text":""},{"line":385,"text":"\t\treturn $this;"},{"line":386,"text":"\t}"},{"line":387,"text":""},{"line":388,"text":"\tpublic function sendHeaders()"},{"line":389,"text":"\t{"},{"line":390,"text":"\t\tforeach ($this->headers AS $key => $value)"},{"line":391,"text":"\t\t{"},{"line":392,"text":"\t\t\tif (is_array($value))"},{"line":393,"text":"\t\t\t{"},{"line":394,"text":"\t\t\t\tforeach ($value AS $innerValue)"},{"line":395,"text":"\t\t\t\t{"},{"sep":true},{"line":446,"text":"\t\t\t\t}"},{"line":447,"text":""},{"line":448,"text":"\t\t\t\tcall_user_func('setcookie', $name, $value, $options);"},{"line":449,"text":"\t\t\t}"},{"line":450,"text":"\t\t}"},{"line":451,"text":"\t}"},{"line":452,"text":""},{"line":453,"text":"\tpublic function sendBody()"},{"line":454,"text":"\t{"},{"line":455,"text":"\t\tif ($this->body instanceof ResponseFile)"},{"line":456,"text":"\t\t{"},{"line":457,"text":"\t\t\tif ($this->includeContentLength)"},{"line":458,"text":"\t\t\t{"},{"line":459,"text":"\t\t\t\theader('Content-Length: ' . $this->body->getLength());"},{"line":460,"text":"\t\t\t}"},{"line":461,"text":""},{"line":462,"text":"\t\t\t$this->body->output();"},{"line":463,"text":"\t\t}"},{"line":464,"text":"\t\telse if ($this->body instanceof ResponseStream)"},{"line":465,"text":"\t\t{"},{"line":466,"text":"\t\t\tif ($this->includeContentLength)"},{"line":467,"text":"\t\t\t{"},{"line":468,"text":"\t\t\t\t$length = $this->body->getLength();"},{"line":469,"text":"\t\t\t\tif ($length !== null)"},{"line":470,"text":"\t\t\t\t{"},{"line":471,"text":"\t\t\t\t\theader('Content-Length: ' . $length);"},{"line":472,"text":"\t\t\t\t}"},{"line":473,"text":"\t\t\t}"},{"line":474,"text":""},{"line":475,"text":"\t\t\t$this->body->output();"},{"line":476,"text":"\t\t}"},{"line":477,"text":"\t\telse"},{"line":478,"text":"\t\t{"},{"line":479,"text":"\t\t\tif ($this->compress)"},{"line":480,"text":"\t\t\t{"},{"line":481,"text":"\t\t\t\t$toPrint = gzencode($this->body, 9);"},{"line":482,"text":"\t\t\t}"},{"line":483,"text":"\t\t\telse"},{"line":484,"text":"\t\t\t{"},{"line":485,"text":"\t\t\t\t$toPrint = $this->body;"},{"line":486,"text":"\t\t\t}"},{"line":487,"text":""},{"line":488,"text":"\t\t\tif ($this->includeContentLength)"},{"line":489,"text":"\t\t\t{"},{"line":490,"text":"\t\t\t\theader('Content-Length: ' . strlen($toPrint));"},{"line":491,"text":"\t\t\t}"},{"line":492,"text":""},{"line":493,"text":"\t\t\techo $toPrint;"},{"line":494,"text":"\t\t}"},{"line":495,"text":"\t}"},{"line":496,"text":""},{"line":497,"text":"\tpublic function contentIsCompressible(Request $request)"},{"line":498,"text":"\t{"},{"line":499,"text":"\t\tif ("},{"line":500,"text":"\t\t\t!is_string($this->body)"},{"line":501,"text":"\t\t\t|| !preg_match('#^(?:text/|application/(?:json|xml|rss\\+xml)$)#i', $this->contentType)"},{"line":502,"text":"\t\t\t|| strpos($request->getServer('HTTP_ACCEPT_ENCODING', ''), 'gzip') === false"},{"line":503,"text":"\t\t)"},{"line":504,"text":"\t\t{"},{"line":505,"text":"\t\t\treturn false;"},{"line":506,"text":"\t\t}"},{"line":507,"text":""},{"line":508,"text":"\t\tif (!function_exists('gzencode'))"},{"line":509,"text":"\t\t{"},{"line":510,"text":"\t\t\treturn false;"},{"line":511,"text":"\t\t}"},{"line":512,"text":""},{"line":513,"text":"\t\treturn (strlen($this->body) >= 20);"},{"line":514,"text":"\t}"},{"line":515,"text":"}"}],"present":true}}},"guest_stderr_present":false,"inner_rc":0,"ok":true,"out_truncated":false,"transport_rc":0,"transport_stderr_bytes":0,"transport_stderr_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"} +GRAM516R5RCA3_DECISION=PASS_ERROR_REQUESTSTATE_AND_SOURCE_CAPTURED +GRAM516R5RCA3_NEXT_GATE=CLASSIFY_CURRENT_RUNTIME_DEFECT +HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index f08bc89c..4b61ff7b 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,19 +1,19 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-RCA-SCHEMAFIX-READONLY-516R5RCA2", + "command_id": "SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3", "status": "OK", "rc": 0, "host": "pve01", "mode": "read-only", - "component": "gram-support-codevipe-error-rca-schemafix-readonly", - "started_at_utc": "2026-09-18T06:08:03Z", - "finished_at_utc": "2026-09-18T06:08:05Z", + "component": "gram-support-codevipe-error-requeststate-rca-readonly", + "started_at_utc": "2026-09-18T06:12:40Z", + "finished_at_utc": "2026-09-18T06:12:41Z", "reference_register_checked": true, "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", "error_register_checked": true, "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", - "command_sha256": "d03fe519c60ba324db49df11a3d84cf9981f7b5ea5fc72be91fb57f292993254", + "command_sha256": "af3e7b5d91ef4c593cbdf0d032ab8022f0bfb2da04c29aafb6bd450f1e99caf7", "duplicate_failed_command_blocked": false, "block_reason": null, "execution_started": true, @@ -30,9 +30,9 @@ "secrets_included": false, "private_addresses_included": false, "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "0a2826d00f35aeafdd94160e3bf5316cfd5c402c3d1719dee51f19fa1a1af44b", - "sanitized_output_sha256": "0a2826d00f35aeafdd94160e3bf5316cfd5c402c3d1719dee51f19fa1a1af44b", + "raw_evidence_sha256": "7de025dbfa44e4f0c49d03b4428121cbefb1c0b7b624db402a0f60b938a6ec98", + "sanitized_output_sha256": "7de025dbfa44e4f0c49d03b4428121cbefb1c0b7b624db402a0f60b938a6ec98", "output_truncated_in_json": false, "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", - "output": "GRAM516R5RCA2_SAFE_REPORT={\"err_truncated\":false,\"guest\":{\"error\":null,\"ok\":true,\"php_rc\":0,\"php_stderr_bytes\":0,\"php_stderr_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"runtime\":{\"columns\":[\"error_id\",\"exception_date\",\"user_id\",\"ip_address\",\"exception_type\",\"message\",\"filename\",\"line\",\"trace_string\",\"request_state\"],\"error\":null,\"error_count\":4,\"error_max\":4,\"ok\":true,\"rows\":[{\"error_id\":4,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state_sha256\":\"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf\",\"time_raw_type\":\"integer\",\"time_utc\":\"2026-09-18T05:58:47+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"},{\"error_id\":3,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state_sha256\":\"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf\",\"time_raw_type\":\"integer\",\"time_utc\":\"2026-09-18T05:58:32+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"},{\"error_id\":2,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state_sha256\":\"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf\",\"time_raw_type\":\"integer\",\"time_utc\":\"2026-09-18T05:58:26+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"},{\"error_id\":1,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state_sha256\":\"c809fa5b352e5cabae7067d8626171f788a8dd768fe250455dae052ff2489348\",\"time_raw_type\":\"integer\",\"time_utc\":\"2026-09-18T05:54:03+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"}],\"time_column\":\"exception_date\"}},\"guest_stderr_present\":false,\"inner_rc\":0,\"ok\":true,\"out_truncated\":false,\"transport_rc\":0,\"transport_stderr_bytes\":0,\"transport_stderr_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"}\nGRAM516R5RCA2_DECISION=PASS_CODEVIPE_ERROR_ROWS_CAPTURED\nGRAM516R5RCA2_NEXT_GATE=CLASSIFY_ERRORS_AND_RESUME_FOOTER_CONTACT_REMOVAL_IF_SAFE\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-RCA-SCHEMAFIX-READONLY-516R5RCA2\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\n" + "output": "GRAM516R5RCA3_SAFE_REPORT={\"err_truncated\":false,\"guest\":{\"error\":null,\"ok\":true,\"php_rc\":0,\"php_stderr_bytes\":0,\"php_stderr_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"runtime\":{\"error\":null,\"error_count\":4,\"error_max\":4,\"ok\":true,\"rows\":[{\"error_id\":4,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state\":{\"bytes\":160,\"collection_keys\":{\"_GET\":[\"/support/service-worker\"],\"_POST\":[]},\"fields\":{\"referrer\":{\"host\":\"codevipe.ru\",\"path\":\"/support/staff/ticket\"},\"url\":{\"host\":null,\"path\":\"/support/service-worker\"}},\"format\":\"json\",\"sha256\":\"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf\",\"top_keys\":[\"url\",\"referrer\",\"_GET\",\"_POST\"]},\"time_utc\":\"2026-09-18T05:58:47+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"},{\"error_id\":3,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state\":{\"bytes\":160,\"collection_keys\":{\"_GET\":[\"/support/service-worker\"],\"_POST\":[]},\"fields\":{\"referrer\":{\"host\":\"codevipe.ru\",\"path\":\"/support/staff/ticket\"},\"url\":{\"host\":null,\"path\":\"/support/service-worker\"}},\"format\":\"json\",\"sha256\":\"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf\",\"top_keys\":[\"url\",\"referrer\",\"_GET\",\"_POST\"]},\"time_utc\":\"2026-09-18T05:58:32+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"},{\"error_id\":2,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state\":{\"bytes\":160,\"collection_keys\":{\"_GET\":[\"/support/service-worker\"],\"_POST\":[]},\"fields\":{\"referrer\":{\"host\":\"codevipe.ru\",\"path\":\"/support/staff/ticket\"},\"url\":{\"host\":null,\"path\":\"/support/service-worker\"}},\"format\":\"json\",\"sha256\":\"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf\",\"top_keys\":[\"url\",\"referrer\",\"_GET\",\"_POST\"]},\"time_utc\":\"2026-09-18T05:58:26+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"},{\"error_id\":1,\"exception_type\":\"TypeError\",\"filename_basename\":\"Response.php\",\"line\":490,\"message\":\"strlen(): Argument #1 ($string) must be of type string, XF\\\\Http\\\\Response given\",\"request_state\":{\"bytes\":137,\"collection_keys\":{\"_GET\":[\"/support/service-worker\"],\"_POST\":[]},\"fields\":{\"referrer\":{\"host\":\"codevipe.ru\",\"path\":\"/support/staff\"},\"url\":{\"host\":null,\"path\":\"/support/service-worker\"}},\"format\":\"json\",\"sha256\":\"c809fa5b352e5cabae7067d8626171f788a8dd768fe250455dae052ff2489348\",\"top_keys\":[\"url\",\"referrer\",\"_GET\",\"_POST\"]},\"time_utc\":\"2026-09-18T05:54:03+00:00\",\"trace_head\":\"#0 src/XF/Http/Response.php(293): XF\\\\Http\\\\Response->sendBody()\\n#1 src/XF.php(894): XF\\\\Http\\\\Response->send(Object(XF\\\\Http\\\\Request))\\n#2 index.php(23): XF::runApp('XF\\\\\\\\Pub\\\\\\\\App')\\n#3 {main}\"}]},\"source\":{\"Gram/Support/Pub/Controller/StaffSupport.php\":{\"basename\":\"StaffSupport.php\",\"matches\":[{\"sep\":true},{\"line\":20,\"text\":\"\"},{\"line\":21,\"text\":\" if (!$visitor->user_id || !$allowed)\"},{\"line\":22,\"text\":\" {\"},{\"line\":23,\"text\":\" throw $this->exception($this->noPermission());\"},{\"line\":24,\"text\":\" }\"},{\"line\":25,\"text\":\" }\"},{\"line\":26,\"text\":\"\"},{\"line\":27,\"text\":\" public function actionIndex()\"},{\"line\":28,\"text\":\" {\"},{\"line\":29,\"text\":\" $this->assertStaff(false);\"},{\"line\":30,\"text\":\"\"},{\"line\":31,\"text\":\" $tickets = $this->repository('Gram\\\\Support:Ticket')\"},{\"line\":32,\"text\":\" ->findStaffQueue()\"},{\"line\":33,\"text\":\" ->fetch();\"},{\"line\":34,\"text\":\"\"},{\"line\":35,\"text\":\" return $this->view(\"},{\"line\":36,\"text\":\" 'Gram\\\\Support:StaffQueue',\"},{\"line\":37,\"text\":\" 'gram_support_staff_queue',\"},{\"line\":38,\"text\":\" ['tickets' => $tickets]\"},{\"line\":39,\"text\":\" );\"},{\"line\":40,\"text\":\" }\"},{\"line\":41,\"text\":\"\"},{\"line\":42,\"text\":\" public function actionTicket()\"},{\"line\":43,\"text\":\" {\"},{\"line\":44,\"text\":\" $this->assertStaff(false);\"},{\"line\":45,\"text\":\" $ticket = $this->assertTicket();\"},{\"line\":46,\"text\":\"\"},{\"line\":47,\"text\":\" $messages = $this->repository('Gram\\\\Support:Message')\"},{\"line\":48,\"text\":\" ->findAllForTicket((int)$ticket->ticket_id)\"},{\"line\":49,\"text\":\" ->fetch();\"},{\"line\":50,\"text\":\"\"},{\"line\":51,\"text\":\" return $this->view(\"},{\"line\":52,\"text\":\" 'Gram\\\\Support:StaffTicket',\"},{\"line\":53,\"text\":\" 'gram_support_staff_ticket',\"},{\"line\":54,\"text\":\" [\"},{\"line\":55,\"text\":\" 'ticket' => $ticket,\"},{\"line\":56,\"text\":\" 'messages' => $messages,\"},{\"line\":57,\"text\":\" 'statusOptions' => StatusPolicy::all()\"},{\"line\":58,\"text\":\" ]\"},{\"line\":59,\"text\":\" );\"},{\"line\":60,\"text\":\" }\"},{\"line\":61,\"text\":\"\"},{\"line\":62,\"text\":\" public function actionReply()\"},{\"line\":63,\"text\":\" {\"},{\"line\":64,\"text\":\" $this->assertPostOnly();\"},{\"line\":65,\"text\":\" $this->assertStaff(true);\"},{\"line\":66,\"text\":\"\"},{\"line\":67,\"text\":\" $ticket = $this->assertTicket();\"},{\"line\":68,\"text\":\" $isInternal = (bool)$this->filter('is_internal', 'bool');\"},{\"line\":69,\"text\":\"\"},{\"line\":70,\"text\":\" if ($isInternal\"},{\"line\":71,\"text\":\" && !\\\\XF::visitor()->hasPermission('gramSupport', 'internalNotes'))\"},{\"line\":72,\"text\":\" {\"},{\"line\":73,\"text\":\" return $this->noPermission();\"},{\"line\":74,\"text\":\" }\"},{\"line\":75,\"text\":\"\"},{\"line\":76,\"text\":\" /** @var Reply $reply */\"},{\"line\":77,\"text\":\" $reply = $this->service(Reply::class);\"},{\"line\":78,\"text\":\" $reply->add(\"},{\"line\":79,\"text\":\" $ticket,\"},{\"line\":80,\"text\":\" $this->filter('message', 'str'),\"},{\"line\":81,\"text\":\" true,\"},{\"line\":82,\"text\":\" $isInternal\"},{\"line\":83,\"text\":\" );\"},{\"line\":84,\"text\":\"\"},{\"line\":85,\"text\":\" return $this->redirect(\"},{\"line\":86,\"text\":\" $this->buildLink('support/staff/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":87,\"text\":\" );\"},{\"line\":88,\"text\":\" }\"},{\"line\":89,\"text\":\"\"},{\"line\":90,\"text\":\" public function actionUpdate()\"},{\"line\":91,\"text\":\" {\"},{\"line\":92,\"text\":\" $this->assertPostOnly();\"},{\"line\":93,\"text\":\" $this->assertStaff(true);\"},{\"line\":94,\"text\":\"\"},{\"line\":95,\"text\":\" $ticket = $this->assertTicket();\"},{\"line\":96,\"text\":\" $newStatus = trim($this->filter('status', 'str'));\"},{\"line\":97,\"text\":\" $assignedUserId = (int)$this->filter('assigned_user_id', 'uint');\"},{\"sep\":true},{\"line\":100,\"text\":\" $staffUpdate = $this->service(StaffUpdate::class);\"},{\"line\":101,\"text\":\" $staffUpdate->validateTransition((string)$ticket->status, $newStatus);\"},{\"line\":102,\"text\":\"\"},{\"line\":103,\"text\":\" if ($assignedUserId > 0)\"},{\"line\":104,\"text\":\" {\"},{\"line\":105,\"text\":\" if (!\\\\XF::visitor()->hasPermission('gramSupport', 'assign'))\"},{\"line\":106,\"text\":\" {\"},{\"line\":107,\"text\":\" return $this->noPermission();\"},{\"line\":108,\"text\":\" }\"},{\"line\":109,\"text\":\"\"},{\"line\":110,\"text\":\" $assigned = \\\\XF::em()->find('XF:User', $assignedUserId);\"},{\"line\":111,\"text\":\" if (!$assigned\"},{\"line\":112,\"text\":\" || (!$assigned->hasPermission('gramSupport', 'viewAll')\"},{\"line\":113,\"text\":\" && !$assigned->hasPermission('gramSupport', 'manage')))\"},{\"line\":114,\"text\":\" {\"},{\"line\":115,\"text\":\" return $this->error(\\\\XF::phrase('gram_support_assignee_invalid'));\"},{\"line\":116,\"text\":\" }\"},{\"line\":117,\"text\":\" }\"},{\"line\":118,\"text\":\"\"},{\"line\":119,\"text\":\" $oldStatus = (string)$ticket->status;\"},{\"line\":120,\"text\":\" $oldAssigned = (int)$ticket->assigned_user_id;\"},{\"line\":121,\"text\":\"\"},{\"line\":122,\"text\":\" $db = \\\\XF::db();\"},{\"sep\":true},{\"line\":154,\"text\":\" {\"},{\"line\":155,\"text\":\" $db->rollback();\"},{\"line\":156,\"text\":\" throw $e;\"},{\"line\":157,\"text\":\" }\"},{\"line\":158,\"text\":\"\"},{\"line\":159,\"text\":\" (new EventDispatcher())->dispatchSafely($event, $ticket);\"},{\"line\":160,\"text\":\"\"},{\"line\":161,\"text\":\" return $this->redirect(\"},{\"line\":162,\"text\":\" $this->buildLink('support/staff/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":163,\"text\":\" );\"},{\"line\":164,\"text\":\" }\"},{\"line\":165,\"text\":\"\"},{\"line\":166,\"text\":\" private function assertTicket()\"},{\"line\":167,\"text\":\" {\"},{\"line\":168,\"text\":\" $ticket = $this->repository('Gram\\\\Support:Ticket')\"},{\"line\":169,\"text\":\" ->findByPublicRef($this->filter('ref', 'str'));\"},{\"line\":170,\"text\":\"\"},{\"line\":171,\"text\":\" if (!$ticket)\"},{\"line\":172,\"text\":\" {\"},{\"line\":173,\"text\":\" throw $this->exception($this->notFound());\"},{\"line\":174,\"text\":\" }\"},{\"line\":175,\"text\":\"\"},{\"line\":176,\"text\":\" return $ticket;\"},{\"line\":177,\"text\":\" }\"},{\"line\":178,\"text\":\"}\"}],\"present\":true},\"Gram/Support/Pub/Controller/Support.php\":{\"basename\":\"Support.php\",\"matches\":[{\"sep\":true},{\"line\":10,\"text\":\"use Gram\\\\Support\\\\Service\\\\Ticket\\\\Creator;\"},{\"line\":11,\"text\":\"use Gram\\\\Support\\\\Service\\\\Ticket\\\\Reply;\"},{\"line\":12,\"text\":\"use Gram\\\\Support\\\\Util\\\\SiteConfig;\"},{\"line\":13,\"text\":\"use XF\\\\Mvc\\\\ParameterBag;\"},{\"line\":14,\"text\":\"\"},{\"line\":15,\"text\":\"final class Support extends \\\\XF\\\\Pub\\\\Controller\\\\AbstractController\"},{\"line\":16,\"text\":\"{\"},{\"line\":17,\"text\":\" public function actionIndex()\"},{\"line\":18,\"text\":\" {\"},{\"line\":19,\"text\":\" if (\\\\XF::visitor()->user_id)\"},{\"line\":20,\"text\":\" {\"},{\"line\":21,\"text\":\" return $this->redirect($this->buildLink('account/support'));\"},{\"line\":22,\"text\":\" }\"},{\"line\":23,\"text\":\"\"},{\"line\":24,\"text\":\" return $this->redirect($this->buildLink('support/create'));\"},{\"line\":25,\"text\":\" }\"},{\"line\":26,\"text\":\"\"},{\"line\":27,\"text\":\" public function actionCreate()\"},{\"line\":28,\"text\":\" {\"},{\"line\":29,\"text\":\" $visitor = \\\\XF::visitor();\"},{\"line\":30,\"text\":\"\"},{\"line\":31,\"text\":\" if ($visitor->user_id && !$visitor->hasPermission('gramSupport', 'create'))\"},{\"line\":32,\"text\":\" {\"},{\"line\":33,\"text\":\" return $this->noPermission();\"},{\"line\":34,\"text\":\" }\"},{\"line\":35,\"text\":\"\"},{\"line\":36,\"text\":\" if ($this->isPost())\"},{\"line\":37,\"text\":\" {\"},{\"line\":38,\"text\":\" $this->assertPostOnly();\"},{\"line\":39,\"text\":\"\"},{\"line\":40,\"text\":\" $email = $this->filter('email', 'str');\"},{\"sep\":true},{\"line\":42,\"text\":\" $subject = $this->filter('subject', 'str');\"},{\"line\":43,\"text\":\" $message = $this->filter('message', 'str');\"},{\"line\":44,\"text\":\"\"},{\"line\":45,\"text\":\" if (!$visitor->user_id)\"},{\"line\":46,\"text\":\" {\"},{\"line\":47,\"text\":\" if (!$this->captchaIsValid(true))\"},{\"line\":48,\"text\":\" {\"},{\"line\":49,\"text\":\" return $this->error(\"},{\"line\":50,\"text\":\" \\\\XF::phrase('did_not_complete_the_captcha_verification_properly')\"},{\"line\":51,\"text\":\" );\"},{\"line\":52,\"text\":\" }\"},{\"line\":53,\"text\":\"\"},{\"line\":54,\"text\":\" /** @var RateLimiter $rateLimiter */\"},{\"line\":55,\"text\":\" $rateLimiter = $this->service(RateLimiter::class);\"},{\"line\":56,\"text\":\" $allowed = $rateLimiter->consumeGuest(\"},{\"sep\":true},{\"line\":58,\"text\":\" $email,\"},{\"line\":59,\"text\":\" SiteConfig::guestRateLimitCount(),\"},{\"line\":60,\"text\":\" SiteConfig::guestRateLimitWindowSeconds()\"},{\"line\":61,\"text\":\" );\"},{\"line\":62,\"text\":\"\"},{\"line\":63,\"text\":\" if (!$allowed)\"},{\"line\":64,\"text\":\" {\"},{\"line\":65,\"text\":\" return $this->error(\\\\XF::phrase('gram_support_rate_limited'));\"},{\"line\":66,\"text\":\" }\"},{\"line\":67,\"text\":\" }\"},{\"line\":68,\"text\":\"\"},{\"line\":69,\"text\":\" $upload = $this->request->getFile('screenshot', false, false);\"},{\"line\":70,\"text\":\" $tempHash = bin2hex(random_bytes(16));\"},{\"line\":71,\"text\":\" $attachmentFlow = new GuestTicketCreateAttachmentFlow();\"},{\"line\":72,\"text\":\"\"},{\"sep\":true},{\"line\":106,\"text\":\" }\"},{\"line\":107,\"text\":\" }\"},{\"line\":108,\"text\":\"\"},{\"line\":109,\"text\":\" if ($created['guest_secret'])\"},{\"line\":110,\"text\":\" {\"},{\"line\":111,\"text\":\" $secret = (string)$created['guest_secret'];\"},{\"line\":112,\"text\":\"\"},{\"line\":113,\"text\":\" return $this->view(\"},{\"line\":114,\"text\":\" 'Gram\\\\Support:CreatedGuest',\"},{\"line\":115,\"text\":\" 'gram_support_created_guest',\"},{\"line\":116,\"text\":\" [\"},{\"line\":117,\"text\":\" 'ticket' => $ticket,\"},{\"line\":118,\"text\":\" 'accessCode' => $secret,\"},{\"line\":119,\"text\":\" 'magicLink' => $this->buildLink('canonical:support/access') . '#token=' . rawurlencode($secret)\"},{\"line\":120,\"text\":\" ]\"},{\"line\":121,\"text\":\" );\"},{\"line\":122,\"text\":\" }\"},{\"line\":123,\"text\":\"\"},{\"line\":124,\"text\":\" return $this->redirect(\"},{\"line\":125,\"text\":\" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":126,\"text\":\" );\"},{\"line\":127,\"text\":\" }\"},{\"line\":128,\"text\":\"\"},{\"line\":129,\"text\":\" return $this->view(\"},{\"line\":130,\"text\":\" 'Gram\\\\Support:Create',\"},{\"line\":131,\"text\":\" 'gram_support_create',\"},{\"line\":132,\"text\":\" ['forceCaptcha' => !$visitor->user_id]\"},{\"line\":133,\"text\":\" );\"},{\"line\":134,\"text\":\" }\"},{\"line\":135,\"text\":\"\"},{\"line\":136,\"text\":\" public function actionAccess()\"},{\"line\":137,\"text\":\" {\"},{\"line\":138,\"text\":\" if ($this->isPost())\"},{\"line\":139,\"text\":\" {\"},{\"line\":140,\"text\":\" $this->assertPostOnly();\"},{\"line\":141,\"text\":\"\"},{\"line\":142,\"text\":\" $secret = trim($this->filter('access_code', 'str'));\"},{\"line\":143,\"text\":\" if ($secret === '')\"},{\"line\":144,\"text\":\" {\"},{\"line\":145,\"text\":\" return $this->error(\\\\XF::phrase('gram_support_access_code_required'));\"},{\"line\":146,\"text\":\" }\"},{\"line\":147,\"text\":\"\"},{\"line\":148,\"text\":\" $ticket = $this->repository('Gram\\\\Support:Ticket')\"},{\"line\":149,\"text\":\" ->findGuestAccessibleBySecret($secret, \\\\XF::$time);\"},{\"line\":150,\"text\":\"\"},{\"line\":151,\"text\":\" if (!$ticket)\"},{\"line\":152,\"text\":\" {\"},{\"line\":153,\"text\":\" return $this->error(\\\\XF::phrase('gram_support_access_invalid'));\"},{\"line\":154,\"text\":\" }\"},{\"line\":155,\"text\":\"\"},{\"line\":156,\"text\":\" GuestTicketSession::grant($ticket);\"},{\"line\":157,\"text\":\"\"},{\"line\":158,\"text\":\" return $this->redirect(\"},{\"line\":159,\"text\":\" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":160,\"text\":\" );\"},{\"line\":161,\"text\":\" }\"},{\"line\":162,\"text\":\"\"},{\"line\":163,\"text\":\" return $this->view(\"},{\"line\":164,\"text\":\" 'Gram\\\\Support:Access',\"},{\"line\":165,\"text\":\" 'gram_support_access',\"},{\"line\":166,\"text\":\" []\"},{\"line\":167,\"text\":\" );\"},{\"line\":168,\"text\":\" }\"},{\"line\":169,\"text\":\"\"},{\"line\":170,\"text\":\" public function actionTicket()\"},{\"line\":171,\"text\":\" {\"},{\"line\":172,\"text\":\" $ticket = $this->assertViewableTicketByRef($this->filter('ref', 'str'));\"},{\"line\":173,\"text\":\"\"},{\"line\":174,\"text\":\" $messages = $this->repository('Gram\\\\Support:Message')\"},{\"line\":175,\"text\":\" ->findPublicForTicket((int)$ticket->ticket_id)\"},{\"line\":176,\"text\":\" ->fetch();\"},{\"line\":177,\"text\":\"\"},{\"line\":178,\"text\":\" return $this->view(\"},{\"line\":179,\"text\":\" 'Gram\\\\Support:Ticket',\"},{\"line\":180,\"text\":\" 'gram_support_ticket',\"},{\"line\":181,\"text\":\" [\"},{\"line\":182,\"text\":\" 'ticket' => $ticket,\"},{\"line\":183,\"text\":\" 'messages' => $messages\"},{\"line\":184,\"text\":\" ]\"},{\"line\":185,\"text\":\" );\"},{\"line\":186,\"text\":\" }\"},{\"line\":187,\"text\":\"\"},{\"line\":188,\"text\":\" public function actionReply()\"},{\"line\":189,\"text\":\" {\"},{\"line\":190,\"text\":\" $this->assertPostOnly();\"},{\"line\":191,\"text\":\"\"},{\"line\":192,\"text\":\" $ticket = $this->assertViewableTicketByRef($this->filter('ref', 'str'));\"},{\"line\":193,\"text\":\" $visitor = \\\\XF::visitor();\"},{\"line\":194,\"text\":\"\"},{\"line\":195,\"text\":\" if ($visitor->user_id)\"},{\"line\":196,\"text\":\" {\"},{\"line\":197,\"text\":\" if ((int)$ticket->user_id !== (int)$visitor->user_id\"},{\"line\":198,\"text\":\" || !$visitor->hasPermission('gramSupport', 'replyOwn'))\"},{\"line\":199,\"text\":\" {\"},{\"line\":200,\"text\":\" return $this->noPermission();\"},{\"line\":201,\"text\":\" }\"},{\"line\":202,\"text\":\" }\"},{\"line\":203,\"text\":\" elseif (!GuestTicketSession::hasGrant($ticket))\"},{\"line\":204,\"text\":\" {\"},{\"line\":205,\"text\":\" return $this->noPermission();\"},{\"line\":206,\"text\":\" }\"},{\"line\":207,\"text\":\"\"},{\"line\":208,\"text\":\" $message = $this->filter('message', 'str');\"},{\"line\":209,\"text\":\"\"},{\"line\":210,\"text\":\" /** @var Reply $reply */\"},{\"line\":211,\"text\":\" $reply = $this->service(Reply::class);\"},{\"line\":212,\"text\":\" $reply->add($ticket, $message, false, false);\"},{\"line\":213,\"text\":\"\"},{\"line\":214,\"text\":\" return $this->redirect(\"},{\"line\":215,\"text\":\" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])\"},{\"line\":216,\"text\":\" );\"},{\"line\":217,\"text\":\" }\"},{\"line\":218,\"text\":\"\"},{\"line\":219,\"text\":\" private function assertViewableTicketByRef(string $publicRef)\"},{\"line\":220,\"text\":\" {\"}],\"present\":true},\"XF/Http/Response.php\":{\"basename\":\"Response.php\",\"matches\":[{\"sep\":true},{\"line\":240,\"text\":\"\\t\\treturn $name;\"},{\"line\":241,\"text\":\"\\t}\"},{\"line\":242,\"text\":\"\"},{\"line\":243,\"text\":\"\\tpublic function body($body = null)\"},{\"line\":244,\"text\":\"\\t{\"},{\"line\":245,\"text\":\"\\t\\tif ($body === null)\"},{\"line\":246,\"text\":\"\\t\\t{\"},{\"line\":247,\"text\":\"\\t\\t\\treturn $this->body;\"},{\"line\":248,\"text\":\"\\t\\t}\"},{\"line\":249,\"text\":\"\"},{\"line\":250,\"text\":\"\\t\\t$this->body = $body;\"},{\"line\":251,\"text\":\"\"},{\"line\":252,\"text\":\"\\t\\treturn $this;\"},{\"line\":253,\"text\":\"\\t}\"},{\"line\":254,\"text\":\"\"},{\"line\":255,\"text\":\"\\tpublic function responseFile($fileName)\"},{\"line\":256,\"text\":\"\\t{\"},{\"line\":257,\"text\":\"\\t\\treturn new ResponseFile($fileName);\"},{\"sep\":true},{\"line\":282,\"text\":\"\\t\\t}\"},{\"line\":283,\"text\":\"\"},{\"line\":284,\"text\":\"\\t\\t$this->includeContentLength = (bool) $use;\"},{\"line\":285,\"text\":\"\"},{\"line\":286,\"text\":\"\\t\\treturn $this;\"},{\"line\":287,\"text\":\"\\t}\"},{\"line\":288,\"text\":\"\"},{\"line\":289,\"text\":\"\\tpublic function send(?Request $request = null)\"},{\"line\":290,\"text\":\"\\t{\"},{\"line\":291,\"text\":\"\\t\\t$this->prepareForOutput($request);\"},{\"line\":292,\"text\":\"\\t\\t$this->sendHeaders();\"},{\"line\":293,\"text\":\"\\t\\t$this->sendBody();\"},{\"line\":294,\"text\":\"\\t}\"},{\"line\":295,\"text\":\"\"},{\"line\":296,\"text\":\"\\tpublic function prepareForOutput(?Request $request = null)\"},{\"sep\":true},{\"line\":381,\"text\":\"\\tpublic function removeCookie($name)\"},{\"line\":382,\"text\":\"\\t{\"},{\"line\":383,\"text\":\"\\t\\tunset($this->cookies[$name]);\"},{\"line\":384,\"text\":\"\"},{\"line\":385,\"text\":\"\\t\\treturn $this;\"},{\"line\":386,\"text\":\"\\t}\"},{\"line\":387,\"text\":\"\"},{\"line\":388,\"text\":\"\\tpublic function sendHeaders()\"},{\"line\":389,\"text\":\"\\t{\"},{\"line\":390,\"text\":\"\\t\\tforeach ($this->headers AS $key => $value)\"},{\"line\":391,\"text\":\"\\t\\t{\"},{\"line\":392,\"text\":\"\\t\\t\\tif (is_array($value))\"},{\"line\":393,\"text\":\"\\t\\t\\t{\"},{\"line\":394,\"text\":\"\\t\\t\\t\\tforeach ($value AS $innerValue)\"},{\"line\":395,\"text\":\"\\t\\t\\t\\t{\"},{\"sep\":true},{\"line\":446,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":447,\"text\":\"\"},{\"line\":448,\"text\":\"\\t\\t\\t\\tcall_user_func('setcookie', $name, $value, $options);\"},{\"line\":449,\"text\":\"\\t\\t\\t}\"},{\"line\":450,\"text\":\"\\t\\t}\"},{\"line\":451,\"text\":\"\\t}\"},{\"line\":452,\"text\":\"\"},{\"line\":453,\"text\":\"\\tpublic function sendBody()\"},{\"line\":454,\"text\":\"\\t{\"},{\"line\":455,\"text\":\"\\t\\tif ($this->body instanceof ResponseFile)\"},{\"line\":456,\"text\":\"\\t\\t{\"},{\"line\":457,\"text\":\"\\t\\t\\tif ($this->includeContentLength)\"},{\"line\":458,\"text\":\"\\t\\t\\t{\"},{\"line\":459,\"text\":\"\\t\\t\\t\\theader('Content-Length: ' . $this->body->getLength());\"},{\"line\":460,\"text\":\"\\t\\t\\t}\"},{\"line\":461,\"text\":\"\"},{\"line\":462,\"text\":\"\\t\\t\\t$this->body->output();\"},{\"line\":463,\"text\":\"\\t\\t}\"},{\"line\":464,\"text\":\"\\t\\telse if ($this->body instanceof ResponseStream)\"},{\"line\":465,\"text\":\"\\t\\t{\"},{\"line\":466,\"text\":\"\\t\\t\\tif ($this->includeContentLength)\"},{\"line\":467,\"text\":\"\\t\\t\\t{\"},{\"line\":468,\"text\":\"\\t\\t\\t\\t$length = $this->body->getLength();\"},{\"line\":469,\"text\":\"\\t\\t\\t\\tif ($length !== null)\"},{\"line\":470,\"text\":\"\\t\\t\\t\\t{\"},{\"line\":471,\"text\":\"\\t\\t\\t\\t\\theader('Content-Length: ' . $length);\"},{\"line\":472,\"text\":\"\\t\\t\\t\\t}\"},{\"line\":473,\"text\":\"\\t\\t\\t}\"},{\"line\":474,\"text\":\"\"},{\"line\":475,\"text\":\"\\t\\t\\t$this->body->output();\"},{\"line\":476,\"text\":\"\\t\\t}\"},{\"line\":477,\"text\":\"\\t\\telse\"},{\"line\":478,\"text\":\"\\t\\t{\"},{\"line\":479,\"text\":\"\\t\\t\\tif ($this->compress)\"},{\"line\":480,\"text\":\"\\t\\t\\t{\"},{\"line\":481,\"text\":\"\\t\\t\\t\\t$toPrint = gzencode($this->body, 9);\"},{\"line\":482,\"text\":\"\\t\\t\\t}\"},{\"line\":483,\"text\":\"\\t\\t\\telse\"},{\"line\":484,\"text\":\"\\t\\t\\t{\"},{\"line\":485,\"text\":\"\\t\\t\\t\\t$toPrint = $this->body;\"},{\"line\":486,\"text\":\"\\t\\t\\t}\"},{\"line\":487,\"text\":\"\"},{\"line\":488,\"text\":\"\\t\\t\\tif ($this->includeContentLength)\"},{\"line\":489,\"text\":\"\\t\\t\\t{\"},{\"line\":490,\"text\":\"\\t\\t\\t\\theader('Content-Length: ' . strlen($toPrint));\"},{\"line\":491,\"text\":\"\\t\\t\\t}\"},{\"line\":492,\"text\":\"\"},{\"line\":493,\"text\":\"\\t\\t\\techo $toPrint;\"},{\"line\":494,\"text\":\"\\t\\t}\"},{\"line\":495,\"text\":\"\\t}\"},{\"line\":496,\"text\":\"\"},{\"line\":497,\"text\":\"\\tpublic function contentIsCompressible(Request $request)\"},{\"line\":498,\"text\":\"\\t{\"},{\"line\":499,\"text\":\"\\t\\tif (\"},{\"line\":500,\"text\":\"\\t\\t\\t!is_string($this->body)\"},{\"line\":501,\"text\":\"\\t\\t\\t|| !preg_match('#^(?:text/|application/(?:json|xml|rss\\\\+xml)$)#i', $this->contentType)\"},{\"line\":502,\"text\":\"\\t\\t\\t|| strpos($request->getServer('HTTP_ACCEPT_ENCODING', ''), 'gzip') === false\"},{\"line\":503,\"text\":\"\\t\\t)\"},{\"line\":504,\"text\":\"\\t\\t{\"},{\"line\":505,\"text\":\"\\t\\t\\treturn false;\"},{\"line\":506,\"text\":\"\\t\\t}\"},{\"line\":507,\"text\":\"\"},{\"line\":508,\"text\":\"\\t\\tif (!function_exists('gzencode'))\"},{\"line\":509,\"text\":\"\\t\\t{\"},{\"line\":510,\"text\":\"\\t\\t\\treturn false;\"},{\"line\":511,\"text\":\"\\t\\t}\"},{\"line\":512,\"text\":\"\"},{\"line\":513,\"text\":\"\\t\\treturn (strlen($this->body) >= 20);\"},{\"line\":514,\"text\":\"\\t}\"},{\"line\":515,\"text\":\"}\"}],\"present\":true}}},\"guest_stderr_present\":false,\"inner_rc\":0,\"ok\":true,\"out_truncated\":false,\"transport_rc\":0,\"transport_stderr_bytes\":0,\"transport_stderr_sha256\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"}\nGRAM516R5RCA3_DECISION=PASS_ERROR_REQUESTSTATE_AND_SOURCE_CAPTURED\nGRAM516R5RCA3_NEXT_GATE=CLASSIFY_CURRENT_RUNTIME_DEFECT\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\n" } diff --git a/runtime/latest.txt b/runtime/latest.txt index 487a2357..4091590c 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,15 +1,15 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-RCA-SCHEMAFIX-READONLY-516R5RCA2 +COMMAND_ID=SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3 STATUS=OK RC=0 HOST=pve01 MODE=read-only -COMPONENT=gram-support-codevipe-error-rca-schemafix-readonly +COMPONENT=gram-support-codevipe-error-requeststate-rca-readonly REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 -COMMAND_SHA256=d03fe519c60ba324db49df11a3d84cf9981f7b5ea5fc72be91fb57f292993254 +COMMAND_SHA256=af3e7b5d91ef4c593cbdf0d032ab8022f0bfb2da04c29aafb6bd450f1e99caf7 DUPLICATE_FAILED_COMMAND_BLOCKED=false EXECUTION_STARTED=true CHANGE_DECLARED=false @@ -24,13 +24,13 @@ MUTATION_OUTCOME=NO_MUTATION SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=0a2826d00f35aeafdd94160e3bf5316cfd5c402c3d1719dee51f19fa1a1af44b -SANITIZED_OUTPUT_SHA256=0a2826d00f35aeafdd94160e3bf5316cfd5c402c3d1719dee51f19fa1a1af44b +RAW_EVIDENCE_SHA256=7de025dbfa44e4f0c49d03b4428121cbefb1c0b7b624db402a0f60b938a6ec98 +SANITIZED_OUTPUT_SHA256=7de025dbfa44e4f0c49d03b4428121cbefb1c0b7b624db402a0f60b938a6ec98 OUTPUT_BEGIN -GRAM516R5RCA2_SAFE_REPORT={"err_truncated":false,"guest":{"error":null,"ok":true,"php_rc":0,"php_stderr_bytes":0,"php_stderr_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","runtime":{"columns":["error_id","exception_date","user_id","ip_address","exception_type","message","filename","line","trace_string","request_state"],"error":null,"error_count":4,"error_max":4,"ok":true,"rows":[{"error_id":4,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state_sha256":"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf","time_raw_type":"integer","time_utc":"2026-09-18T05:58:47+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"},{"error_id":3,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state_sha256":"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf","time_raw_type":"integer","time_utc":"2026-09-18T05:58:32+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"},{"error_id":2,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state_sha256":"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf","time_raw_type":"integer","time_utc":"2026-09-18T05:58:26+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"},{"error_id":1,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state_sha256":"c809fa5b352e5cabae7067d8626171f788a8dd768fe250455dae052ff2489348","time_raw_type":"integer","time_utc":"2026-09-18T05:54:03+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"}],"time_column":"exception_date"}},"guest_stderr_present":false,"inner_rc":0,"ok":true,"out_truncated":false,"transport_rc":0,"transport_stderr_bytes":0,"transport_stderr_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"} -GRAM516R5RCA2_DECISION=PASS_CODEVIPE_ERROR_ROWS_CAPTURED -GRAM516R5RCA2_NEXT_GATE=CLASSIFY_ERRORS_AND_RESUME_FOOTER_CONTACT_REMOVAL_IF_SAFE -HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-RCA-SCHEMAFIX-READONLY-516R5RCA2","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} +GRAM516R5RCA3_SAFE_REPORT={"err_truncated":false,"guest":{"error":null,"ok":true,"php_rc":0,"php_stderr_bytes":0,"php_stderr_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","runtime":{"error":null,"error_count":4,"error_max":4,"ok":true,"rows":[{"error_id":4,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state":{"bytes":160,"collection_keys":{"_GET":["/support/service-worker"],"_POST":[]},"fields":{"referrer":{"host":"codevipe.ru","path":"/support/staff/ticket"},"url":{"host":null,"path":"/support/service-worker"}},"format":"json","sha256":"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf","top_keys":["url","referrer","_GET","_POST"]},"time_utc":"2026-09-18T05:58:47+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"},{"error_id":3,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state":{"bytes":160,"collection_keys":{"_GET":["/support/service-worker"],"_POST":[]},"fields":{"referrer":{"host":"codevipe.ru","path":"/support/staff/ticket"},"url":{"host":null,"path":"/support/service-worker"}},"format":"json","sha256":"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf","top_keys":["url","referrer","_GET","_POST"]},"time_utc":"2026-09-18T05:58:32+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"},{"error_id":2,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state":{"bytes":160,"collection_keys":{"_GET":["/support/service-worker"],"_POST":[]},"fields":{"referrer":{"host":"codevipe.ru","path":"/support/staff/ticket"},"url":{"host":null,"path":"/support/service-worker"}},"format":"json","sha256":"bf0540e9fdbe13a7e735692f32f0ebe88e3d872ce50068b9165a7546eef32fdf","top_keys":["url","referrer","_GET","_POST"]},"time_utc":"2026-09-18T05:58:26+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"},{"error_id":1,"exception_type":"TypeError","filename_basename":"Response.php","line":490,"message":"strlen(): Argument #1 ($string) must be of type string, XF\\Http\\Response given","request_state":{"bytes":137,"collection_keys":{"_GET":["/support/service-worker"],"_POST":[]},"fields":{"referrer":{"host":"codevipe.ru","path":"/support/staff"},"url":{"host":null,"path":"/support/service-worker"}},"format":"json","sha256":"c809fa5b352e5cabae7067d8626171f788a8dd768fe250455dae052ff2489348","top_keys":["url","referrer","_GET","_POST"]},"time_utc":"2026-09-18T05:54:03+00:00","trace_head":"#0 src/XF/Http/Response.php(293): XF\\Http\\Response->sendBody()\n#1 src/XF.php(894): XF\\Http\\Response->send(Object(XF\\Http\\Request))\n#2 index.php(23): XF::runApp('XF\\\\Pub\\\\App')\n#3 {main}"}]},"source":{"Gram/Support/Pub/Controller/StaffSupport.php":{"basename":"StaffSupport.php","matches":[{"sep":true},{"line":20,"text":""},{"line":21,"text":" if (!$visitor->user_id || !$allowed)"},{"line":22,"text":" {"},{"line":23,"text":" throw $this->exception($this->noPermission());"},{"line":24,"text":" }"},{"line":25,"text":" }"},{"line":26,"text":""},{"line":27,"text":" public function actionIndex()"},{"line":28,"text":" {"},{"line":29,"text":" $this->assertStaff(false);"},{"line":30,"text":""},{"line":31,"text":" $tickets = $this->repository('Gram\\Support:Ticket')"},{"line":32,"text":" ->findStaffQueue()"},{"line":33,"text":" ->fetch();"},{"line":34,"text":""},{"line":35,"text":" return $this->view("},{"line":36,"text":" 'Gram\\Support:StaffQueue',"},{"line":37,"text":" 'gram_support_staff_queue',"},{"line":38,"text":" ['tickets' => $tickets]"},{"line":39,"text":" );"},{"line":40,"text":" }"},{"line":41,"text":""},{"line":42,"text":" public function actionTicket()"},{"line":43,"text":" {"},{"line":44,"text":" $this->assertStaff(false);"},{"line":45,"text":" $ticket = $this->assertTicket();"},{"line":46,"text":""},{"line":47,"text":" $messages = $this->repository('Gram\\Support:Message')"},{"line":48,"text":" ->findAllForTicket((int)$ticket->ticket_id)"},{"line":49,"text":" ->fetch();"},{"line":50,"text":""},{"line":51,"text":" return $this->view("},{"line":52,"text":" 'Gram\\Support:StaffTicket',"},{"line":53,"text":" 'gram_support_staff_ticket',"},{"line":54,"text":" ["},{"line":55,"text":" 'ticket' => $ticket,"},{"line":56,"text":" 'messages' => $messages,"},{"line":57,"text":" 'statusOptions' => StatusPolicy::all()"},{"line":58,"text":" ]"},{"line":59,"text":" );"},{"line":60,"text":" }"},{"line":61,"text":""},{"line":62,"text":" public function actionReply()"},{"line":63,"text":" {"},{"line":64,"text":" $this->assertPostOnly();"},{"line":65,"text":" $this->assertStaff(true);"},{"line":66,"text":""},{"line":67,"text":" $ticket = $this->assertTicket();"},{"line":68,"text":" $isInternal = (bool)$this->filter('is_internal', 'bool');"},{"line":69,"text":""},{"line":70,"text":" if ($isInternal"},{"line":71,"text":" && !\\XF::visitor()->hasPermission('gramSupport', 'internalNotes'))"},{"line":72,"text":" {"},{"line":73,"text":" return $this->noPermission();"},{"line":74,"text":" }"},{"line":75,"text":""},{"line":76,"text":" /** @var Reply $reply */"},{"line":77,"text":" $reply = $this->service(Reply::class);"},{"line":78,"text":" $reply->add("},{"line":79,"text":" $ticket,"},{"line":80,"text":" $this->filter('message', 'str'),"},{"line":81,"text":" true,"},{"line":82,"text":" $isInternal"},{"line":83,"text":" );"},{"line":84,"text":""},{"line":85,"text":" return $this->redirect("},{"line":86,"text":" $this->buildLink('support/staff/ticket', null, ['ref' => $ticket->public_ref])"},{"line":87,"text":" );"},{"line":88,"text":" }"},{"line":89,"text":""},{"line":90,"text":" public function actionUpdate()"},{"line":91,"text":" {"},{"line":92,"text":" $this->assertPostOnly();"},{"line":93,"text":" $this->assertStaff(true);"},{"line":94,"text":""},{"line":95,"text":" $ticket = $this->assertTicket();"},{"line":96,"text":" $newStatus = trim($this->filter('status', 'str'));"},{"line":97,"text":" $assignedUserId = (int)$this->filter('assigned_user_id', 'uint');"},{"sep":true},{"line":100,"text":" $staffUpdate = $this->service(StaffUpdate::class);"},{"line":101,"text":" $staffUpdate->validateTransition((string)$ticket->status, $newStatus);"},{"line":102,"text":""},{"line":103,"text":" if ($assignedUserId > 0)"},{"line":104,"text":" {"},{"line":105,"text":" if (!\\XF::visitor()->hasPermission('gramSupport', 'assign'))"},{"line":106,"text":" {"},{"line":107,"text":" return $this->noPermission();"},{"line":108,"text":" }"},{"line":109,"text":""},{"line":110,"text":" $assigned = \\XF::em()->find('XF:User', $assignedUserId);"},{"line":111,"text":" if (!$assigned"},{"line":112,"text":" || (!$assigned->hasPermission('gramSupport', 'viewAll')"},{"line":113,"text":" && !$assigned->hasPermission('gramSupport', 'manage')))"},{"line":114,"text":" {"},{"line":115,"text":" return $this->error(\\XF::phrase('gram_support_assignee_invalid'));"},{"line":116,"text":" }"},{"line":117,"text":" }"},{"line":118,"text":""},{"line":119,"text":" $oldStatus = (string)$ticket->status;"},{"line":120,"text":" $oldAssigned = (int)$ticket->assigned_user_id;"},{"line":121,"text":""},{"line":122,"text":" $db = \\XF::db();"},{"sep":true},{"line":154,"text":" {"},{"line":155,"text":" $db->rollback();"},{"line":156,"text":" throw $e;"},{"line":157,"text":" }"},{"line":158,"text":""},{"line":159,"text":" (new EventDispatcher())->dispatchSafely($event, $ticket);"},{"line":160,"text":""},{"line":161,"text":" return $this->redirect("},{"line":162,"text":" $this->buildLink('support/staff/ticket', null, ['ref' => $ticket->public_ref])"},{"line":163,"text":" );"},{"line":164,"text":" }"},{"line":165,"text":""},{"line":166,"text":" private function assertTicket()"},{"line":167,"text":" {"},{"line":168,"text":" $ticket = $this->repository('Gram\\Support:Ticket')"},{"line":169,"text":" ->findByPublicRef($this->filter('ref', 'str'));"},{"line":170,"text":""},{"line":171,"text":" if (!$ticket)"},{"line":172,"text":" {"},{"line":173,"text":" throw $this->exception($this->notFound());"},{"line":174,"text":" }"},{"line":175,"text":""},{"line":176,"text":" return $ticket;"},{"line":177,"text":" }"},{"line":178,"text":"}"}],"present":true},"Gram/Support/Pub/Controller/Support.php":{"basename":"Support.php","matches":[{"sep":true},{"line":10,"text":"use Gram\\Support\\Service\\Ticket\\Creator;"},{"line":11,"text":"use Gram\\Support\\Service\\Ticket\\Reply;"},{"line":12,"text":"use Gram\\Support\\Util\\SiteConfig;"},{"line":13,"text":"use XF\\Mvc\\ParameterBag;"},{"line":14,"text":""},{"line":15,"text":"final class Support extends \\XF\\Pub\\Controller\\AbstractController"},{"line":16,"text":"{"},{"line":17,"text":" public function actionIndex()"},{"line":18,"text":" {"},{"line":19,"text":" if (\\XF::visitor()->user_id)"},{"line":20,"text":" {"},{"line":21,"text":" return $this->redirect($this->buildLink('account/support'));"},{"line":22,"text":" }"},{"line":23,"text":""},{"line":24,"text":" return $this->redirect($this->buildLink('support/create'));"},{"line":25,"text":" }"},{"line":26,"text":""},{"line":27,"text":" public function actionCreate()"},{"line":28,"text":" {"},{"line":29,"text":" $visitor = \\XF::visitor();"},{"line":30,"text":""},{"line":31,"text":" if ($visitor->user_id && !$visitor->hasPermission('gramSupport', 'create'))"},{"line":32,"text":" {"},{"line":33,"text":" return $this->noPermission();"},{"line":34,"text":" }"},{"line":35,"text":""},{"line":36,"text":" if ($this->isPost())"},{"line":37,"text":" {"},{"line":38,"text":" $this->assertPostOnly();"},{"line":39,"text":""},{"line":40,"text":" $email = $this->filter('email', 'str');"},{"sep":true},{"line":42,"text":" $subject = $this->filter('subject', 'str');"},{"line":43,"text":" $message = $this->filter('message', 'str');"},{"line":44,"text":""},{"line":45,"text":" if (!$visitor->user_id)"},{"line":46,"text":" {"},{"line":47,"text":" if (!$this->captchaIsValid(true))"},{"line":48,"text":" {"},{"line":49,"text":" return $this->error("},{"line":50,"text":" \\XF::phrase('did_not_complete_the_captcha_verification_properly')"},{"line":51,"text":" );"},{"line":52,"text":" }"},{"line":53,"text":""},{"line":54,"text":" /** @var RateLimiter $rateLimiter */"},{"line":55,"text":" $rateLimiter = $this->service(RateLimiter::class);"},{"line":56,"text":" $allowed = $rateLimiter->consumeGuest("},{"sep":true},{"line":58,"text":" $email,"},{"line":59,"text":" SiteConfig::guestRateLimitCount(),"},{"line":60,"text":" SiteConfig::guestRateLimitWindowSeconds()"},{"line":61,"text":" );"},{"line":62,"text":""},{"line":63,"text":" if (!$allowed)"},{"line":64,"text":" {"},{"line":65,"text":" return $this->error(\\XF::phrase('gram_support_rate_limited'));"},{"line":66,"text":" }"},{"line":67,"text":" }"},{"line":68,"text":""},{"line":69,"text":" $upload = $this->request->getFile('screenshot', false, false);"},{"line":70,"text":" $tempHash = bin2hex(random_bytes(16));"},{"line":71,"text":" $attachmentFlow = new GuestTicketCreateAttachmentFlow();"},{"line":72,"text":""},{"sep":true},{"line":106,"text":" }"},{"line":107,"text":" }"},{"line":108,"text":""},{"line":109,"text":" if ($created['guest_secret'])"},{"line":110,"text":" {"},{"line":111,"text":" $secret = (string)$created['guest_secret'];"},{"line":112,"text":""},{"line":113,"text":" return $this->view("},{"line":114,"text":" 'Gram\\Support:CreatedGuest',"},{"line":115,"text":" 'gram_support_created_guest',"},{"line":116,"text":" ["},{"line":117,"text":" 'ticket' => $ticket,"},{"line":118,"text":" 'accessCode' => $secret,"},{"line":119,"text":" 'magicLink' => $this->buildLink('canonical:support/access') . '#token=' . rawurlencode($secret)"},{"line":120,"text":" ]"},{"line":121,"text":" );"},{"line":122,"text":" }"},{"line":123,"text":""},{"line":124,"text":" return $this->redirect("},{"line":125,"text":" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])"},{"line":126,"text":" );"},{"line":127,"text":" }"},{"line":128,"text":""},{"line":129,"text":" return $this->view("},{"line":130,"text":" 'Gram\\Support:Create',"},{"line":131,"text":" 'gram_support_create',"},{"line":132,"text":" ['forceCaptcha' => !$visitor->user_id]"},{"line":133,"text":" );"},{"line":134,"text":" }"},{"line":135,"text":""},{"line":136,"text":" public function actionAccess()"},{"line":137,"text":" {"},{"line":138,"text":" if ($this->isPost())"},{"line":139,"text":" {"},{"line":140,"text":" $this->assertPostOnly();"},{"line":141,"text":""},{"line":142,"text":" $secret = trim($this->filter('access_code', 'str'));"},{"line":143,"text":" if ($secret === '')"},{"line":144,"text":" {"},{"line":145,"text":" return $this->error(\\XF::phrase('gram_support_access_code_required'));"},{"line":146,"text":" }"},{"line":147,"text":""},{"line":148,"text":" $ticket = $this->repository('Gram\\Support:Ticket')"},{"line":149,"text":" ->findGuestAccessibleBySecret($secret, \\XF::$time);"},{"line":150,"text":""},{"line":151,"text":" if (!$ticket)"},{"line":152,"text":" {"},{"line":153,"text":" return $this->error(\\XF::phrase('gram_support_access_invalid'));"},{"line":154,"text":" }"},{"line":155,"text":""},{"line":156,"text":" GuestTicketSession::grant($ticket);"},{"line":157,"text":""},{"line":158,"text":" return $this->redirect("},{"line":159,"text":" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])"},{"line":160,"text":" );"},{"line":161,"text":" }"},{"line":162,"text":""},{"line":163,"text":" return $this->view("},{"line":164,"text":" 'Gram\\Support:Access',"},{"line":165,"text":" 'gram_support_access',"},{"line":166,"text":" []"},{"line":167,"text":" );"},{"line":168,"text":" }"},{"line":169,"text":""},{"line":170,"text":" public function actionTicket()"},{"line":171,"text":" {"},{"line":172,"text":" $ticket = $this->assertViewableTicketByRef($this->filter('ref', 'str'));"},{"line":173,"text":""},{"line":174,"text":" $messages = $this->repository('Gram\\Support:Message')"},{"line":175,"text":" ->findPublicForTicket((int)$ticket->ticket_id)"},{"line":176,"text":" ->fetch();"},{"line":177,"text":""},{"line":178,"text":" return $this->view("},{"line":179,"text":" 'Gram\\Support:Ticket',"},{"line":180,"text":" 'gram_support_ticket',"},{"line":181,"text":" ["},{"line":182,"text":" 'ticket' => $ticket,"},{"line":183,"text":" 'messages' => $messages"},{"line":184,"text":" ]"},{"line":185,"text":" );"},{"line":186,"text":" }"},{"line":187,"text":""},{"line":188,"text":" public function actionReply()"},{"line":189,"text":" {"},{"line":190,"text":" $this->assertPostOnly();"},{"line":191,"text":""},{"line":192,"text":" $ticket = $this->assertViewableTicketByRef($this->filter('ref', 'str'));"},{"line":193,"text":" $visitor = \\XF::visitor();"},{"line":194,"text":""},{"line":195,"text":" if ($visitor->user_id)"},{"line":196,"text":" {"},{"line":197,"text":" if ((int)$ticket->user_id !== (int)$visitor->user_id"},{"line":198,"text":" || !$visitor->hasPermission('gramSupport', 'replyOwn'))"},{"line":199,"text":" {"},{"line":200,"text":" return $this->noPermission();"},{"line":201,"text":" }"},{"line":202,"text":" }"},{"line":203,"text":" elseif (!GuestTicketSession::hasGrant($ticket))"},{"line":204,"text":" {"},{"line":205,"text":" return $this->noPermission();"},{"line":206,"text":" }"},{"line":207,"text":""},{"line":208,"text":" $message = $this->filter('message', 'str');"},{"line":209,"text":""},{"line":210,"text":" /** @var Reply $reply */"},{"line":211,"text":" $reply = $this->service(Reply::class);"},{"line":212,"text":" $reply->add($ticket, $message, false, false);"},{"line":213,"text":""},{"line":214,"text":" return $this->redirect("},{"line":215,"text":" $this->buildLink('support/ticket', null, ['ref' => $ticket->public_ref])"},{"line":216,"text":" );"},{"line":217,"text":" }"},{"line":218,"text":""},{"line":219,"text":" private function assertViewableTicketByRef(string $publicRef)"},{"line":220,"text":" {"}],"present":true},"XF/Http/Response.php":{"basename":"Response.php","matches":[{"sep":true},{"line":240,"text":"\t\treturn $name;"},{"line":241,"text":"\t}"},{"line":242,"text":""},{"line":243,"text":"\tpublic function body($body = null)"},{"line":244,"text":"\t{"},{"line":245,"text":"\t\tif ($body === null)"},{"line":246,"text":"\t\t{"},{"line":247,"text":"\t\t\treturn $this->body;"},{"line":248,"text":"\t\t}"},{"line":249,"text":""},{"line":250,"text":"\t\t$this->body = $body;"},{"line":251,"text":""},{"line":252,"text":"\t\treturn $this;"},{"line":253,"text":"\t}"},{"line":254,"text":""},{"line":255,"text":"\tpublic function responseFile($fileName)"},{"line":256,"text":"\t{"},{"line":257,"text":"\t\treturn new ResponseFile($fileName);"},{"sep":true},{"line":282,"text":"\t\t}"},{"line":283,"text":""},{"line":284,"text":"\t\t$this->includeContentLength = (bool) $use;"},{"line":285,"text":""},{"line":286,"text":"\t\treturn $this;"},{"line":287,"text":"\t}"},{"line":288,"text":""},{"line":289,"text":"\tpublic function send(?Request $request = null)"},{"line":290,"text":"\t{"},{"line":291,"text":"\t\t$this->prepareForOutput($request);"},{"line":292,"text":"\t\t$this->sendHeaders();"},{"line":293,"text":"\t\t$this->sendBody();"},{"line":294,"text":"\t}"},{"line":295,"text":""},{"line":296,"text":"\tpublic function prepareForOutput(?Request $request = null)"},{"sep":true},{"line":381,"text":"\tpublic function removeCookie($name)"},{"line":382,"text":"\t{"},{"line":383,"text":"\t\tunset($this->cookies[$name]);"},{"line":384,"text":""},{"line":385,"text":"\t\treturn $this;"},{"line":386,"text":"\t}"},{"line":387,"text":""},{"line":388,"text":"\tpublic function sendHeaders()"},{"line":389,"text":"\t{"},{"line":390,"text":"\t\tforeach ($this->headers AS $key => $value)"},{"line":391,"text":"\t\t{"},{"line":392,"text":"\t\t\tif (is_array($value))"},{"line":393,"text":"\t\t\t{"},{"line":394,"text":"\t\t\t\tforeach ($value AS $innerValue)"},{"line":395,"text":"\t\t\t\t{"},{"sep":true},{"line":446,"text":"\t\t\t\t}"},{"line":447,"text":""},{"line":448,"text":"\t\t\t\tcall_user_func('setcookie', $name, $value, $options);"},{"line":449,"text":"\t\t\t}"},{"line":450,"text":"\t\t}"},{"line":451,"text":"\t}"},{"line":452,"text":""},{"line":453,"text":"\tpublic function sendBody()"},{"line":454,"text":"\t{"},{"line":455,"text":"\t\tif ($this->body instanceof ResponseFile)"},{"line":456,"text":"\t\t{"},{"line":457,"text":"\t\t\tif ($this->includeContentLength)"},{"line":458,"text":"\t\t\t{"},{"line":459,"text":"\t\t\t\theader('Content-Length: ' . $this->body->getLength());"},{"line":460,"text":"\t\t\t}"},{"line":461,"text":""},{"line":462,"text":"\t\t\t$this->body->output();"},{"line":463,"text":"\t\t}"},{"line":464,"text":"\t\telse if ($this->body instanceof ResponseStream)"},{"line":465,"text":"\t\t{"},{"line":466,"text":"\t\t\tif ($this->includeContentLength)"},{"line":467,"text":"\t\t\t{"},{"line":468,"text":"\t\t\t\t$length = $this->body->getLength();"},{"line":469,"text":"\t\t\t\tif ($length !== null)"},{"line":470,"text":"\t\t\t\t{"},{"line":471,"text":"\t\t\t\t\theader('Content-Length: ' . $length);"},{"line":472,"text":"\t\t\t\t}"},{"line":473,"text":"\t\t\t}"},{"line":474,"text":""},{"line":475,"text":"\t\t\t$this->body->output();"},{"line":476,"text":"\t\t}"},{"line":477,"text":"\t\telse"},{"line":478,"text":"\t\t{"},{"line":479,"text":"\t\t\tif ($this->compress)"},{"line":480,"text":"\t\t\t{"},{"line":481,"text":"\t\t\t\t$toPrint = gzencode($this->body, 9);"},{"line":482,"text":"\t\t\t}"},{"line":483,"text":"\t\t\telse"},{"line":484,"text":"\t\t\t{"},{"line":485,"text":"\t\t\t\t$toPrint = $this->body;"},{"line":486,"text":"\t\t\t}"},{"line":487,"text":""},{"line":488,"text":"\t\t\tif ($this->includeContentLength)"},{"line":489,"text":"\t\t\t{"},{"line":490,"text":"\t\t\t\theader('Content-Length: ' . strlen($toPrint));"},{"line":491,"text":"\t\t\t}"},{"line":492,"text":""},{"line":493,"text":"\t\t\techo $toPrint;"},{"line":494,"text":"\t\t}"},{"line":495,"text":"\t}"},{"line":496,"text":""},{"line":497,"text":"\tpublic function contentIsCompressible(Request $request)"},{"line":498,"text":"\t{"},{"line":499,"text":"\t\tif ("},{"line":500,"text":"\t\t\t!is_string($this->body)"},{"line":501,"text":"\t\t\t|| !preg_match('#^(?:text/|application/(?:json|xml|rss\\+xml)$)#i', $this->contentType)"},{"line":502,"text":"\t\t\t|| strpos($request->getServer('HTTP_ACCEPT_ENCODING', ''), 'gzip') === false"},{"line":503,"text":"\t\t)"},{"line":504,"text":"\t\t{"},{"line":505,"text":"\t\t\treturn false;"},{"line":506,"text":"\t\t}"},{"line":507,"text":""},{"line":508,"text":"\t\tif (!function_exists('gzencode'))"},{"line":509,"text":"\t\t{"},{"line":510,"text":"\t\t\treturn false;"},{"line":511,"text":"\t\t}"},{"line":512,"text":""},{"line":513,"text":"\t\treturn (strlen($this->body) >= 20);"},{"line":514,"text":"\t}"},{"line":515,"text":"}"}],"present":true}}},"guest_stderr_present":false,"inner_rc":0,"ok":true,"out_truncated":false,"transport_rc":0,"transport_stderr_bytes":0,"transport_stderr_sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"} +GRAM516R5RCA3_DECISION=PASS_ERROR_REQUESTSTATE_AND_SOURCE_CAPTURED +GRAM516R5RCA3_NEXT_GATE=CLASSIFY_CURRENT_RUNTIME_DEFECT +HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260918-GRAM-SUPPORT-CODEVIPE-ERROR-REQUESTSTATE-RCA-READONLY-516R5RCA3","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} OUTPUT_END CHAT_OUTPUT_END