3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * Synchronous line-oriented communication session.
18 * $session = new class {
19 * use LineSessionTrait;
20 * protected function onRequest(string $requestLine): ?string {
23 * protected function onException(string $requestLine, \Throwable $t): ?string {
27 * $session->setIO(STDIN, STDOUT)->run();
30 trait LineSessionTrait
{
33 * The onConnect() method is called when a new session is opened.
35 * @param string $negotiationFlags
36 * List of pipe initialization flags. See Civi::pipe() for description of flags.
38 * Header/welcome line, or NULL if none.
41 protected function onConnect(string $negotiationFlags): ?
string {
46 * The onRequest() method is called after receiving one line of text.
48 * @param string $requestLine
49 * The received line of text.
51 * The line to send back, or NULL if none.
53 abstract protected function onRequest(string $requestLine): ?
string;
56 * The onRequest() method is called after receiving one line of text.
58 * @param string $requestLine
59 * The received line of text - which led to the unhandled exception.
60 * @param \Throwable $t
61 * The unhandled exception.
63 * The line to send back, or NULL if none.
65 abstract protected function onException(string $requestLine, \Throwable
$t): ?
string;
84 protected $delimiter = "\n";
87 * Maximum size of the buffer for reading lines.
89 * Clients may need to set this if they submit large requests.
93 protected $bufferSize = 524288;
96 * A value to display immediately before the response lines.
98 * Clients may set this is if they want to detect and skip buggy noise.
103 protected $responsePrefix = NULL;
106 * @param resource|null $input
107 * @param resource|null $output
109 public function __construct($input = NULL, $output = NULL) {
110 $this->input
= $input;
111 $this->output
= $output;
115 * Run the main loop. Poll for commands on $input and write responses to $output.
117 * @param string $negotiationFlags
118 * List of pipe initialization flags. See Civi::pipe() for description of flags.
120 public function run(string $negotiationFlags = '') {
121 $this->write($this->onConnect($negotiationFlags));
123 while (FALSE !== ($line = stream_get_line($this->input
, $this->bufferSize
, $this->delimiter
))) {
124 $line = rtrim($line, $this->delimiter
);
130 $response = $this->onRequest($line);
132 catch (\Throwable
$t) {
133 $response = $this->onException($line, $t);
135 $this->write($response);
142 public function getBufferSize(): int {
143 return $this->bufferSize
;
147 * @param int $bufferSize
150 public function setBufferSize(int $bufferSize) {
151 $this->bufferSize
= $bufferSize;
156 * @return string|null
158 public function getResponsePrefix(): ?
string {
159 return $this->responsePrefix
;
163 * @param string|null $responsePrefix
166 public function setResponsePrefix(?
string $responsePrefix) {
167 $this->responsePrefix
= $responsePrefix;
172 * @param resource $input
173 * @param resource $output
176 public function setIO($input, $output) {
177 $this->input
= $input;
178 $this->output
= $output;
182 protected function write(?
string $response): void
{
183 if ($response === NULL) {
186 if ($this->responsePrefix
!== NULL) {
187 fwrite($this->output
, $this->responsePrefix
);
189 fwrite($this->output
, $response);
190 fwrite($this->output
, $this->delimiter
);