dbXapp 2.0
RAD, CMS, Module und Runtime-IDE fuer dbXapp
Loading...
Searching...
No Matches
dbxWorkflowBindRegistry.class.php
Go to the documentation of this file.
1<?php
2namespace dbx\dbxWorkflow;
3
5
6 private $ddBind = 'dbxWorkflow|workflowModuleBind';
7
8 private function db() {
9 return dbx()->get_system_obj('dbxDB');
10 }
11
12 private function read_json($value, $default = array()) {
13 $value = trim((string)$value);
14 if ($value === '') {
15 return $default;
16 }
17 $data = json_decode($value, true);
18 return is_array($data) ? $data : $default;
19 }
20
21 private function write_json($value) {
22 return json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
23 }
24
25 public function listModuleDds($modul) {
26 $modul = trim((string)$modul);
27 if ($modul === '') {
28 return array();
29 }
30
31 $out = array();
32 $path = dbx_os_path_file(dbx_get_base_dir() . "dbx/modules/$modul/dd/");
33 if (!is_dir($path)) {
34 return $out;
35 }
36
37 foreach (scandir($path) as $file) {
38 if (!str_ends_with($file, '.dd.php')) {
39 continue;
40 }
41 $dd = str_replace('.dd.php', '', $file);
42 if ($dd === '' || $dd === 'new') {
43 continue;
44 }
45 $out[] = $modul . '|' . $dd;
46 }
47
48 sort($out);
49 return $out;
50 }
51
52 public function detectContextTpl($modul) {
53 $modul = trim((string)$modul);
54 $path = dbx_os_path_file(dbx_get_base_dir() . "dbx/modules/$modul/tpl/htm/");
55 if (!is_dir($path)) {
56 return '';
57 }
58
59 foreach (scandir($path) as $file) {
60 if (str_ends_with($file, '-summary.htm')) {
61 return $modul . '|' . str_replace('.htm', '', $file);
62 }
63 }
64
65 return '';
66 }
67
68 public function ddFields($ddRef) {
69 $oDD = dbx()->get_system_obj('dbxDD');
70 $model = $oDD->get_dd_model($ddRef);
71 if (!$model) {
72 return array();
73 }
74
75 $fields = array();
76 foreach ((array)($model['fields'] ?? array()) as $field) {
77 $name = (string)($field['name'] ?? '');
78 if ($name === '') {
79 continue;
80 }
81 $fields[$name] = $field;
82 }
83
84 return $fields;
85 }
86
87 public function guessRecordNeedKey($ddRef) {
88 $parts = explode('|', $ddRef);
89 $dd = (string)($parts[1] ?? 'record');
90 $key = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $dd));
91 return trim(preg_replace('/[^a-z0-9_]+/', '_', $key), '_');
92 }
93
94 public function generateBindSkeleton($modul, $ddRef, $bindKey = '') {
95 $modul = trim((string)$modul);
96 $ddRef = trim((string)$ddRef);
97 if ($modul === '' || $ddRef === '') {
98 return array();
99 }
100
101 $fields = $this->ddFields($ddRef);
102 $recordNeed = $this->guessRecordNeedKey($ddRef);
103 $contextTpl = $this->detectContextTpl($modul);
104 $bindKey = trim((string)$bindKey);
105 if ($bindKey === '') {
106 $bindKey = $recordNeed;
107 }
108
109 $contextFields = array('rid' => 'id');
110 $summaryCandidates = array('subject', 'name', 'email', 'phone', 'message', 'title', 'label');
111 foreach ($summaryCandidates as $name) {
112 if (isset($fields[$name])) {
113 $contextFields[$name] = $name;
114 }
115 }
116
117 $needs = array(
118 $recordNeed => array(
119 'type' => 'dd_select',
120 'where' => array('trash' => 0),
121 'label' => '#{id}',
122 'order_field' => 'create_date',
123 'order_dir' => 'DESC',
124 ),
125 );
126
127 if (isset($fields['status']) && trim((string)($fields['status']['options'] ?? '')) !== '') {
128 $needs['status'] = array('type' => 'dd_field_options', 'field' => 'status');
129 }
130
131 $finishMap = array();
132 if (isset($fields['status'])) {
133 $finishMap['status'] = 'status';
134 }
135 if (isset($fields['reply_text'])) {
136 $needs['reply_text'] = array('type' => 'dd_field_value', 'field' => 'reply_text');
137 $finishMap['reply_text'] = 'reply_text';
138 }
139 if (isset($fields['reply_date'])) {
140 $finishMap['reply_date'] = '@now';
141 }
142 if (isset($fields['reply_uid'])) {
143 $finishMap['reply_uid'] = '@uid';
144 }
145
146 $bind = array(
147 'modul' => $modul,
148 'record' => array(
149 'dd' => $ddRef,
150 'id_need' => $recordNeed,
151 'prefill_rid' => true,
152 ),
153 'needs' => $needs,
154 'finish' => array(
155 'type' => 'dd_update',
156 'map' => $finishMap,
157 ),
158 );
159
160 if ($contextTpl !== '') {
161 $bind['context'] = array(
162 'tpl' => $contextTpl,
163 'hide_on_need' => $recordNeed,
164 'fields' => $contextFields,
165 );
166 }
167
168 if (isset($fields['email']) && isset($fields['reply_text'])) {
169 $mailTpl = $modul . '|mail-contact-reply';
170 $mailFile = dbx_os_path_file(dbx_get_base_dir() . "dbx/modules/$modul/tpl/htm/mail-contact-reply.htm");
171 if (file_exists($mailFile)) {
172 $bind['needs']['send_mail'] = array(
173 'type' => 'static_select',
174 'show_if_config' => array('modul' => $modul, 'key' => 'mail_on_reply', 'has' => 'mail'),
175 'options' => array(
176 array('value' => '1', 'label' => 'Ja, E-Mail senden'),
177 array('value' => '0', 'label' => 'Nein, nur speichern'),
178 ),
179 );
180 $bind['finish']['mail'] = array(
181 'when_need' => 'send_mail',
182 'when_value' => '1',
183 'config_modul' => $modul,
184 'mode_key' => 'mail_on_reply',
185 'to_field' => 'email',
186 'subject_tpl' => 'Antwort: {subject}',
187 'body_tpl' => $mailTpl,
188 'body_vars' => array(
189 'subject' => 'subject',
190 'reply_text' => '@need:reply_text',
191 ),
192 'track_fields' => array(
193 'reply_mail_sent' => 1,
194 'reply_mail_sent_date' => '@now',
195 ),
196 );
197 }
198 }
199
200 return array(
201 'modul' => $modul,
202 'bind_key' => $bindKey,
203 'title' => 'Workflow fuer ' . $modul . ' / ' . $ddRef,
204 'description' => 'Automatisch aus DD/TPL erzeugtes Binding. Bitte Needs und Finish pruefen.',
205 'bind_json' => $this->write_json($bind),
206 'active' => 1,
207 );
208 }
209
210 public function contactReplyBind() {
211 $bind = $this->read_json($this->generateBindSkeleton('dbxContact', 'dbxContact|contactRequest', 'contact_reply')['bind_json'] ?? '', array());
212
213 $bind['record'] = array(
214 'dd' => 'dbxContact|contactRequest',
215 'id_need' => 'contact_request',
216 'prefill_rid' => true,
217 );
218 $bind['needs']['contact_request'] = array(
219 'type' => 'dd_select',
220 'where' => array('status' => 'open', 'trash' => 0),
221 'label' => '#{id} - {subject} ({name})',
222 'fields' => array('id', 'subject', 'name'),
223 'order_field' => 'create_date',
224 'order_dir' => 'DESC',
225 );
226 unset($bind['needs'][$this->guessRecordNeedKey('dbxContact|contactRequest')]);
227
228 $bind['needs']['status'] = array('type' => 'dd_field_options', 'field' => 'status');
229 $bind['needs']['customer_reply'] = array('type' => 'dd_field_value', 'field' => 'reply_text');
230 unset($bind['needs']['reply_text']);
231
232 $bind['finish']['map'] = array(
233 'status' => 'status',
234 'reply_text' => 'customer_reply',
235 'reply_date' => '@now',
236 'reply_uid' => '@uid',
237 );
238 if (isset($bind['finish']['mail']['body_vars'])) {
239 $bind['finish']['mail']['body_vars']['reply_text'] = '@need:customer_reply';
240 }
241
242 return array(
243 'modul' => 'dbxContact',
244 'bind_key' => 'contact_reply',
245 'title' => 'Kontaktanfrage beantworten',
246 'description' => 'Binding fuer dbxContact|contactRequest: Auswahl, Status, Antwort, optional Mail.',
247 'bind_json' => $this->write_json($bind),
248 'active' => 1,
249 );
250 }
251
252 public function seedBind(array $record) {
253 $db = $this->db();
254 $modul = (string)($record['modul'] ?? '');
255 $bindKey = (string)($record['bind_key'] ?? '');
256 if ($modul === '' || $bindKey === '') {
257 return 0;
258 }
259
260 $rows = $db->select($this->ddBind, array('modul' => $modul, 'bind_key' => $bindKey), array('id'), 'id', 'DESC', '', 1, 0, 0);
261 if (isset($rows[0]['id'])) {
262 return (int)$db->update($this->ddBind, $record, array('id' => (int)$rows[0]['id']), 0, 1, 1, 1);
263 }
264
265 return (int)$db->insert($this->ddBind, $record, 0, 1, 1, 1);
266 }
267
268 public function seedDefaultBinds() {
269 return $this->seedBind($this->contactReplyBind());
270 }
271}
272?>
$fields[]
Definition config.dd.php:16
$field
Definition config.dd.php:4
dbx_os_path_file($path_file)
Definition index.php:164
dbx_get_base_dir($cut_Data=0)
Definition index.php:157
DBX schema administration.