Merge pull request #23710 from eileenmcnaughton/civi_import
[civicrm-core.git] / Civi / Pipe / PipeSession.php
CommitLineData
54675f57
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
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 +--------------------------------------------------------------------+
10 */
11
12namespace Civi\Pipe;
13
25804d7a 14class PipeSession {
54675f57
TO
15
16 use LineSessionTrait;
17
18 protected const METHOD_REGEX = ';^[a-z][a-zA-Z0-9_]*$;';
19
20 /**
e98a5c1f 21 * Open-ended object. Any public method from this object will be available during this session.
54675f57
TO
22 *
23 * @var object
e98a5c1f 24 * @see \Civi\Pipe\PublicMethods
54675f57
TO
25 */
26 protected $methods;
27
5e13f388
TO
28 /**
29 * @var bool|null
30 */
31 protected $trusted;
32
54675f57
TO
33 /**
34 * @inheritDoc
35 */
88d93265 36 protected function onConnect(string $negotiationFlags): ?string {
54675f57
TO
37 \CRM_Core_Session::useFakeSession();
38 $this->methods = new PublicMethods();
88d93265
TO
39
40 // Convention: Every negotiation-flag should produce exactly one output in the header line.
41 foreach (str_split($negotiationFlags) as $flag) {
42 switch ($flag) {
43 case 'v':
44 $flags[$flag] = \CRM_Utils_System::version();
45 break;
46
47 case 'j':
48 $flags[$flag] = ['jsonrpc-2.0'];
49 break;
50
51 case 'l':
52 $flags[$flag] = function_exists('authx_login') ? ['login'] : ['nologin'];
53 break;
54
55 case 't':
56 $this->setTrusted(TRUE);
57 $flags[$flag] = 'trusted';
58 break;
59
60 case 'u':
61 $this->setTrusted(FALSE);
62 $flags[$flag] = 'untrusted';
63 break;
64
65 default:
66 // What flags might exist in the future? We don't know! Communicate that we don't know.
67 $flags[$flag] = NULL;
68 break;
69 }
70 }
71
eaa0d7ac 72 return json_encode(['Civi::pipe' => $flags]);
54675f57
TO
73 }
74
75 /**
76 * @inheritDoc
77 */
78 protected function onRequest(string $requestLine): ?string {
e98a5c1f 79 return JsonRpc::run($requestLine, function(string $method, array $params) {
158d477b
TO
80 $method = str_replace('.', '_', $method);
81 if (!preg_match(self::METHOD_REGEX, $method)) {
82 throw new \InvalidArgumentException('Method not found', -32601);
54675f57
TO
83 }
84
85 if (!is_callable([$this->methods, $method])) {
86 throw new \InvalidArgumentException('Method not found', -32601);
87 }
88
158d477b
TO
89 return call_user_func([$this->methods, $method], $this, $params);
90 });
54675f57
TO
91 }
92
93 /**
94 * @inheritDoc
95 */
96 protected function onException(string $requestLine, \Throwable $t): ?string {
158d477b
TO
97 $error = JsonRpc::createResponseError([], $t);
98 return \json_encode($error);
54675f57
TO
99 }
100
5e13f388
TO
101 /**
102 * @param bool $trusted
103 * @return PipeSession
104 */
105 public function setTrusted(bool $trusted): PipeSession {
106 if ($this->trusted !== NULL && $this->trusted !== $trusted) {
107 throw new \CRM_Core_Exception('Cannot modify PipeSession::$trusted after initialization');
108 }
109 $this->trusted = $trusted;
110 return $this;
111 }
112
113 /**
114 * @return bool
115 */
116 public function isTrusted(): bool {
117 // If this gets called when the value is NULL, then you are doing it wrong.
118 return $this->trusted;
119 }
120
54675f57 121}