dbXapp 2.0
RAD, CMS, Module und Runtime-IDE fuer dbXapp
Loading...
Searching...
No Matches
dbxWorkflowModule.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 tpl() {
13 return dbx()->get_system_obj('dbxTPL');
14 }
15
16 private function h($value) {
17 return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
18 }
19
20 private function read_json($value, $default = array()) {
21 $value = trim((string)$value);
22 if ($value === '') {
23 return $default;
24 }
25 $data = json_decode($value, true);
26 return is_array($data) ? $data : $default;
27 }
28
29 public function parseBindRef($bindRef) {
30 $bindRef = trim((string)$bindRef);
31 if ($bindRef === '' || strpos($bindRef, '|') === false) {
32 return array('', '');
33 }
34
35 $parts = explode('|', $bindRef, 2);
36 return array(trim((string)$parts[0]), trim((string)$parts[1]));
37 }
38
39 public function loadBindRecord($bindRef) {
40 list($modul, $bindKey) = $this->parseBindRef($bindRef);
41 if ($modul === '' || $bindKey === '') {
42 return array();
43 }
44
45 $rows = $this->db()->select(
46 $this->ddBind,
47 array('modul' => $modul, 'bind_key' => $bindKey, 'active' => 1, 'trash' => 0),
48 '*',
49 'id',
50 'DESC',
51 '',
52 1,
53 0,
54 0
55 );
56
57 return (is_array($rows) && isset($rows[0])) ? $rows[0] : array();
58 }
59
60 public function applyBindRef(array $definition) {
61 $bindRef = trim((string)($definition['bind_ref'] ?? ''));
62 if ($bindRef === '') {
63 return $definition;
64 }
65
66 $row = $this->loadBindRecord($bindRef);
67 if (!$row) {
68 return $definition;
69 }
70
71 $bind = $this->read_json($row['bind_json'] ?? '', array());
72 if ($bind) {
73 $definition['bind'] = $bind;
74 }
75
76 return $definition;
77 }
78
79 private function bindConfig(array $definition) {
80 return (array)($definition['bind'] ?? array());
81 }
82
83 private function recordConfig(array $definition) {
84 return (array)($this->bindConfig($definition)['record'] ?? array());
85 }
86
87 public function recordIdFromValues(array $definition, array $values) {
88 $record = $this->recordConfig($definition);
89 $idNeed = trim((string)($record['id_need'] ?? ''));
90 if ($idNeed === '' || !array_key_exists($idNeed, $values)) {
91 return 0;
92 }
93
94 return (int)preg_replace('/\D+/', '', (string)$values[$idNeed]);
95 }
96
97 public function loadRecord(array $definition, $rid = 0) {
98 $recordCfg = $this->recordConfig($definition);
99 $dd = trim((string)($recordCfg['dd'] ?? ''));
100 $rid = (int)$rid;
101 if ($dd === '' || $rid <= 0) {
102 return array();
103 }
104
105 $row = $this->db()->select1($dd, $rid);
106 return (is_array($row) && $row) ? $row : array();
107 }
108
109 private function labelFromTemplate($template, array $row) {
110 $label = (string)$template;
111 foreach ($row as $key => $value) {
112 if (is_scalar($value) || $value === null) {
113 $label = str_replace('{' . $key . '}', (string)$value, $label);
114 }
115 }
116
117 return trim($label);
118 }
119
120 private function optionsFromDdSelect(array $bindNeed, array $definition, array $values) {
121 $record = $this->recordConfig($definition);
122 $dd = trim((string)($record['dd'] ?? ''));
123 if ($dd === '') {
124 return array();
125 }
126
127 $source = array_merge(
128 array('dd' => $dd, 'include_from' => (string)($record['id_need'] ?? '')),
129 $bindNeed
130 );
131
132 return $this->optionsFromSource($source, $values, $this->recordIdFromValues($definition, $values));
133 }
134
135 public function optionsFromSource(array $source, array $values = array(), $includeId = 0) {
136 $dd = trim((string)($source['dd'] ?? ''));
137 if ($dd === '') {
138 return array();
139 }
140
141 $where = (array)($source['where'] ?? array());
142 $fields = (array)($source['fields'] ?? array('id'));
143 $valueField = trim((string)($source['value'] ?? 'id'));
144 $labelTpl = trim((string)($source['label'] ?? ('{' . $valueField . '}')));
145
146 if ($valueField !== '' && !in_array($valueField, $fields, true)) {
147 $fields[] = $valueField;
148 }
149
150 $rows = $this->db()->select(
151 $dd,
152 $where,
153 $fields,
154 (string)($source['order_field'] ?? 'id'),
155 (string)($source['order_dir'] ?? 'DESC'),
156 '',
157 (int)($source['limit'] ?? 200),
158 0,
159 0
160 );
161
162 $options = array();
163 $seen = array();
164
165 foreach ((array)$rows as $row) {
166 $id = (string)($row[$valueField] ?? '');
167 if ($id === '') {
168 continue;
169 }
170 $seen[$id] = 1;
171 $options[] = array(
172 'value' => $id,
173 'label' => $this->labelFromTemplate($labelTpl, $row),
174 );
175 }
176
177 $includeId = (string)(int)$includeId;
178 if ((int)$includeId > 0 && empty($seen[$includeId])) {
179 $record = $this->db()->select1($dd, (int)$includeId, $fields);
180 if (is_array($record) && $record) {
181 $options[] = array(
182 'value' => $includeId,
183 'label' => $this->labelFromTemplate($labelTpl, $record),
184 );
185 }
186 }
187
188 return $options;
189 }
190
191 private function optionsFromFdField(array $definition, $fieldName) {
192 $record = $this->recordConfig($definition);
193 $dd = trim((string)($record['dd'] ?? ''));
194 $fieldName = trim((string)$fieldName);
195 if ($dd === '' || $fieldName === '') {
196 return array();
197 }
198
199 $oDD = dbx()->get_system_obj('dbxDD');
200 $model = $oDD->get_dd_model($dd);
201 $optionsRaw = '';
202
203 foreach ((array)($model['fields'] ?? array()) as $field) {
204 if ((string)($field['name'] ?? '') === $fieldName) {
205 $optionsRaw = (string)($field['options'] ?? '');
206 break;
207 }
208 }
209
210 if ($optionsRaw === '') {
211 return array();
212 }
213
214 $options = array();
215 foreach (explode('&', $optionsRaw) as $pair) {
216 $pair = trim($pair);
217 if ($pair === '' || strpos($pair, '=') === false) {
218 continue;
219 }
220 list($value, $label) = explode('=', $pair, 2);
221 $options[] = array(
222 'value' => trim($value),
223 'label' => trim($label),
224 );
225 }
226
227 return $options;
228 }
229
230 private function configHasPart($modul, $key, $part) {
231 if ($part !== 'mail') {
232 return false;
233 }
234
235 if ($modul === 'dbxContact' && !class_exists('\\dbx\\dbxContact\\dbxContactConfig', false)) {
236 $path = dbx_get_base_dir() . 'dbx/modules/dbxContact/include/dbxContactConfig.class.php';
237 if (is_file($path)) {
238 require_once $path;
239 }
240 }
241
242 if (class_exists('\\dbx\\dbxContact\\dbxContactConfig', false)) {
243 return \dbx\dbxContact\dbxContactConfig::modulMailEnabled((string) $modul, (string) $key);
244 }
245
246 $mode = strtolower(trim((string) dbx()->get_config($modul, $key)));
247 return ($mode === 'both' || $mode === 'mail' || strpos($mode, 'mail') !== false);
248 }
249
250 private function needBind(array $definition, $needKey) {
251 return (array)($this->bindConfig($definition)['needs'][$needKey] ?? array());
252 }
253
254 private function needVisible(array $definition, $needKey, array $bindNeed) {
255 $showIf = (array)($bindNeed['show_if_config'] ?? array());
256 if (!$showIf) {
257 return true;
258 }
259
260 $modul = trim((string)($showIf['modul'] ?? ''));
261 $key = trim((string)($showIf['key'] ?? ''));
262 $has = trim((string)($showIf['has'] ?? ''));
263
264 if ($modul === '' || $key === '' || $has === '') {
265 return true;
266 }
267
268 return $this->configHasPart($modul, $key, $has);
269 }
270
271 public function enrichDefinition(array $definition, array $values = array()) {
272 $definition = $this->applyBindRef($definition);
273 $bindNeeds = (array)($this->bindConfig($definition)['needs'] ?? array());
274 $needs = array();
275
276 foreach ((array)($definition['needs'] ?? array()) as $need) {
277 if (!is_array($need)) {
278 continue;
279 }
280
281 $key = (string)($need['key'] ?? '');
282 $bindNeed = (array)($bindNeeds[$key] ?? array());
283
284 if ($bindNeed && !$this->needVisible($definition, $key, $bindNeed)) {
285 continue;
286 }
287
288 if (!empty($need['source']) && is_array($need['source'])) {
289 $need['options'] = $this->optionsFromSource(
290 $need['source'],
291 $values,
292 $this->recordIdFromValues($definition, $values)
293 );
294 } elseif ($bindNeed) {
295 $type = (string)($bindNeed['type'] ?? '');
296 if ($type === 'dd_select') {
297 $need['options'] = $this->optionsFromDdSelect($bindNeed, $definition, $values);
298 } elseif ($type === 'dd_field_options') {
299 $need['options'] = $this->optionsFromFdField($definition, (string)($bindNeed['field'] ?? ''));
300 } elseif ($type === 'static_select') {
301 $need['options'] = array_values((array)($bindNeed['options'] ?? array()));
302 }
303 }
304
305 $needs[] = $need;
306 }
307
308 $definition['needs'] = $needs;
309 $definition = $this->enrichShopEbayPublishDefinition($definition, $values);
310 return $definition;
311 }
312
313 private function enrichShopEbayPublishDefinition(array $definition, array $values): array {
314 if ((string)($definition['workflow_key'] ?? '') !== 'shop_ebay_publish') {
315 return $definition;
316 }
317
318 $productId = (int)($values['product'] ?? 0);
319 if ($productId <= 0) {
320 return $definition;
321 }
322
323 $rows = $this->db()->select(
324 'dbxShop|shopProductChannel',
325 array('product_id' => $productId, 'channel_key' => 'ebay'),
326 array('external_listing_id', 'external_offer_id', 'export_status', 'export_message'),
327 'id',
328 'DESC',
329 '',
330 1,
331 0,
332 0
333 );
334 $row = (is_array($rows) && isset($rows[0])) ? $rows[0] : array();
335 $listingId = trim((string)($row['external_listing_id'] ?? ''));
336 $offerId = trim((string)($row['external_offer_id'] ?? ''));
337 $status = trim((string)($row['export_status'] ?? ''));
338 $message = trim((string)($row['export_message'] ?? ''));
339
340 foreach ($definition['needs'] as &$need) {
341 if ((string)($need['key'] ?? '') !== 'ebay_view') {
342 continue;
343 }
344
345 if ($listingId !== '') {
346 $need['hint'] = 'Optionaler Kontrollschritt: Das eBay-Angebot wurde mit Listing-ID ' . $listingId . ' gespeichert. Oeffne das Angebot und pruefe Darstellung, Preis, Versand und Bilder.';
347 $need['module_links'] = array(
348 array(
349 'label' => 'Bei eBay ansehen',
350 'icon' => 'bi-box-arrow-up-right',
351 'url' => 'https://www.ebay.de/itm/' . rawurlencode($listingId),
352 'title' => 'eBay-Angebot ansehen',
353 'width' => '92%',
354 'height' => '90%'
355 ),
356 array(
357 'label' => 'eBay-Mapping',
358 'icon' => 'bi-sliders2',
359 'url' => '?dbx_modul=dbxShop_admin&dbx_run1=product_channel_mapping&id={product}&channel=ebay&dbx_ajax=1',
360 'title' => 'Channel-Mapping: eBay',
361 'width' => '68%',
362 'height' => '84%'
363 )
364 );
365 } else {
366 $extra = array();
367 if ($offerId !== '') {
368 $extra[] = 'Offer-ID: ' . $offerId;
369 }
370 if ($status !== '') {
371 $extra[] = 'Status: ' . $status;
372 }
373 if ($message !== '') {
374 $extra[] = $message;
375 }
376 $need['hint'] = 'Optionaler Kontrollschritt: Es ist noch keine eBay Listing-ID gespeichert. Pruefe zuerst Exportstatus und Mapping.'
377 . ($extra ? ' ' . implode(' | ', $extra) : '');
378 }
379 }
380 unset($need);
381
382 return $definition;
383 }
384
385 public function prefillStart(array $definition, $rid = 0) {
386 $definition = $this->applyBindRef($definition);
387 $recordCfg = $this->recordConfig($definition);
388 $rid = (int)$rid;
389 if (empty($recordCfg['prefill_rid']) || $rid <= 0) {
390 return array();
391 }
392
393 $record = $this->loadRecord($definition, $rid);
394 if (!$record) {
395 return array();
396 }
397
398 $values = array();
399 $idNeed = trim((string)($recordCfg['id_need'] ?? ''));
400 if ($idNeed !== '') {
401 $values[$idNeed] = (string)$rid;
402 }
403
404 foreach ((array)($this->bindConfig($definition)['needs'] ?? array()) as $needKey => $bindNeed) {
405 $type = (string)($bindNeed['type'] ?? '');
406 if ($type === 'dd_field_options' && isset($record[(string)($bindNeed['field'] ?? '')])) {
407 $values[$needKey] = (string)$record[(string)$bindNeed['field']];
408 }
409 if ($type === 'dd_field_value' && isset($record[(string)($bindNeed['field'] ?? '')])) {
410 $text = trim((string)$record[(string)$bindNeed['field']]);
411 if ($text !== '') {
412 $values[$needKey] = $text;
413 }
414 }
415 }
416
417 return $values;
418 }
419
420 private function contextData(array $definition, array $record) {
421 $context = (array)($this->bindConfig($definition)['context'] ?? array());
422 $fields = (array)($context['fields'] ?? array());
423 $data = array();
424
425 foreach ($fields as $tplKey => $recordKey) {
426 $value = $record[(string)$recordKey] ?? '';
427 if ($tplKey === 'phone' && trim((string)$value) === '') {
428 $value = '-';
429 }
430 $data[$tplKey] = $this->h($value);
431 }
432
433 return $data;
434 }
435
436 public function renderStepContext(array $definition, array $need, array $values) {
437 $definition = $this->applyBindRef($definition);
438 $context = (array)($this->bindConfig($definition)['context'] ?? array());
439 if (!$context) {
440 return '';
441 }
442
443 $hideOn = trim((string)($context['hide_on_need'] ?? ''));
444 $rid = $this->recordIdFromValues($definition, $values);
445
446 if ($rid > 0 && $hideOn !== '' && $need['key'] !== $hideOn) {
447 $record = $this->loadRecord($definition, $rid);
448 if ($record) {
449 $tpl = trim((string)($context['tpl'] ?? ''));
450 if ($tpl !== '') {
451 return $this->tpl()->get_tpl($tpl, $this->contextData($definition, $record));
452 }
453 }
454 }
455
456 if ($hideOn !== '' && $need['key'] === $hideOn && $rid <= 0) {
457 $recordCfg = $this->recordConfig($definition);
458 $bindNeed = $this->needBind($definition, $hideOn);
459 if (($bindNeed['type'] ?? '') === 'dd_select') {
460 $options = $this->optionsFromDdSelect($bindNeed, $definition, $values);
461 if (!$options) {
462 return $this->tpl()->get_tpl('dbx|alert-info', array(
463 'msg' => 'Keine passenden Datensaetze gefunden. Bitte zuerst im Modul erfassen.',
464 ));
465 }
466 }
467 }
468
469 return '';
470 }
471
472 public function renderFormValue(array $definition, array $need, array $values) {
473 $definition = $this->applyBindRef($definition);
474 $bindNeed = $this->needBind($definition, (string)($need['key'] ?? ''));
475 if ((string)($bindNeed['type'] ?? '') !== 'dd_field_value') {
476 return '';
477 }
478
479 if (array_key_exists($need['key'], $values)) {
480 return $this->h($values[$need['key']]);
481 }
482
483 $rid = $this->recordIdFromValues($definition, $values);
484 if ($rid > 0) {
485 $record = $this->loadRecord($definition, $rid);
486 $field = (string)($bindNeed['field'] ?? '');
487 if ($record && $field !== '') {
488 return $this->h(trim((string)($record[$field] ?? '')));
489 }
490 }
491
492 return '';
493 }
494
495 public function formatValueLabel(array $definition, array $need, $value) {
496 $definition = $this->applyBindRef($definition);
497 $needKey = (string)($need['key'] ?? '');
498 $bindNeed = $this->needBind($definition, $needKey);
499
500 if (is_array($value) && !empty($value['skipped'])) {
501 return '<em>Uebersprungen</em>';
502 }
503
504 if ((string)($bindNeed['type'] ?? '') === 'dd_select') {
505 $record = $this->loadRecord($definition, (int)$value);
506 if ($record) {
507 return $this->h($this->labelFromTemplate((string)($bindNeed['label'] ?? '#{id}'), $record));
508 }
509 }
510
511 if ((string)($bindNeed['type'] ?? '') === 'dd_field_options') {
512 foreach ($this->optionsFromFdField($definition, (string)($bindNeed['field'] ?? '')) as $opt) {
513 if ((string)($opt['value'] ?? '') === (string)$value) {
514 return $this->h($opt['label']);
515 }
516 }
517 }
518
519 if ((string)($bindNeed['type'] ?? '') === 'static_select') {
520 foreach ((array)($bindNeed['options'] ?? array()) as $opt) {
521 if (is_array($opt) && (string)($opt['value'] ?? '') === (string)$value) {
522 return $this->h($opt['label']);
523 }
524 }
525 }
526
527 return null;
528 }
529
530 private function finalStatusBox(string $type, string $title, string $body, string $extra = ''): string {
531 $icon = 'bi-info-circle';
532 if ($type === 'success') $icon = 'bi-check2-circle';
533 if ($type === 'warning') $icon = 'bi-exclamation-triangle';
534 if ($type === 'danger') $icon = 'bi-x-circle';
535 return '<div class="alert alert-' . $this->h($type) . ' mb-3">'
536 . '<div class="fw-semibold"><i class="bi ' . $icon . '"></i> ' . $this->h($title) . '</div>'
537 . '<div>' . $this->h($body) . '</div>'
538 . $extra
539 . '</div>';
540 }
541
542 private function genericFinalStatus(array $definition, string $instanceStatus, int $completed, int $total, array $missingLabels): string {
543 if ($missingLabels !== array()) {
544 return $this->finalStatusBox(
545 'warning',
546 'Workflow noch nicht vollstaendig',
547 'Es fehlen noch Pflichtschritte: ' . implode(', ', $missingLabels) . '.'
548 );
549 }
550
551 if ($instanceStatus === 'finished') {
552 return $this->finalStatusBox(
553 'success',
554 'Workflow komplett abgeschlossen',
555 'Alle notwendigen Schritte sind erledigt. Ergebnis: ' . (string)($definition['result'] ?? $definition['title'] ?? 'Workflow') . '.'
556 );
557 }
558
559 return $this->finalStatusBox(
560 'info',
561 'Workflow bereit zum Abschluss',
562 'Alle notwendigen Schritte sind erledigt (' . $completed . ' von ' . $total . '). Pruefe die Zusammenfassung und schliesse den Workflow ab.'
563 );
564 }
565
566 private function ebayFinalStatus(array $values, string $instanceStatus, int $completed, int $total, array $missingLabels): string {
567 if ($missingLabels !== array()) {
568 return $this->finalStatusBox(
569 'warning',
570 'eBay-Workflow noch nicht vollstaendig',
571 'Es fehlen noch Pflichtschritte: ' . implode(', ', $missingLabels) . '.'
572 );
573 }
574
575 $productId = (int)($values['product'] ?? 0);
576 if ($productId <= 0) {
577 return $this->finalStatusBox('warning', 'eBay-Status unklar', 'Es ist kein Artikel ausgewaehlt.');
578 }
579
580 $rows = $this->db()->select(
581 'dbxShop|shopProductChannel',
582 array('product_id' => $productId, 'channel_key' => 'ebay'),
583 array('external_listing_id', 'external_offer_id', 'export_status', 'export_message', 'last_export_date'),
584 'id',
585 'DESC',
586 '',
587 1,
588 0,
589 0
590 );
591 $row = (is_array($rows) && isset($rows[0])) ? $rows[0] : array();
592 $listingId = trim((string)($row['external_listing_id'] ?? ''));
593 $offerId = trim((string)($row['external_offer_id'] ?? ''));
594 $status = strtolower(trim((string)($row['export_status'] ?? '')));
595 $message = trim((string)($row['export_message'] ?? ''));
596 $lastExport = trim((string)($row['last_export_date'] ?? ''));
597 $manualCheck = (string)($values['status_check'] ?? '');
598
599 $meta = array();
600 if ($status !== '') $meta[] = 'Status: ' . $status;
601 if ($lastExport !== '') $meta[] = 'Letzter Export: ' . $lastExport;
602 if ($offerId !== '') $meta[] = 'Offer-ID: ' . $offerId;
603 if ($listingId !== '') $meta[] = 'Listing-ID: ' . $listingId;
604 $extra = $meta ? '<div class="small mt-2 text-muted">' . $this->h(implode(' | ', $meta)) . '</div>' : '';
605 if ($message !== '') {
606 $extra .= '<div class="small mt-1">' . $this->h($message) . '</div>';
607 }
608 if ($listingId !== '') {
609 $url = 'https://www.ebay.de/itm/' . rawurlencode($listingId);
610 $extra .= '<div class="mt-2"><a class="btn btn-outline-primary btn-sm dbx-win" href="' . $this->h($url) . '" data-url="' . $this->h($url) . '" data-title="eBay-Angebot ansehen" data-width="92%" data-height="90%"><i class="bi bi-box-arrow-up-right"></i> Bei eBay ansehen</a></div>';
611 }
612
613 if (in_array($status, array('failed', 'error'), true)) {
614 return $this->finalStatusBox('danger', 'eBay-Veroeffentlichung fehlgeschlagen', 'Der Connector hat einen Fehler gemeldet. Bitte Mapping, Zugangsdaten und eBay-Rueckmeldung pruefen.', $extra);
615 }
616
617 if ($listingId !== '' && in_array($status, array('published', 'exported', 'ready'), true)) {
618 return $this->finalStatusBox('success', 'Artikel ist auf eBay veroeffentlicht', 'Der Export hat eine eBay Listing-ID geliefert. Der Workflow ist fachlich erfolgreich.', $extra);
619 }
620
621 if ($lastExport === '') {
622 return $this->finalStatusBox('warning', 'eBay-Export noch nicht ausgefuehrt', 'Der Workflow ist inhaltlich vorbereitet, aber es gibt noch keinen gespeicherten Exportlauf.', $extra);
623 }
624
625 if ($listingId === '') {
626 $text = 'Der Export wurde ausgefuehrt, aber es ist noch keine eBay Listing-ID gespeichert. Das kann bedeuten, dass die Plattform asynchron prueft oder die Rueckmeldung fehlt.';
627 if ($manualCheck === 'error') {
628 $text = 'Der Workflow wurde mit Fehlerstatus geprueft. Bitte die Connector-Meldung und eBay-Daten korrigieren.';
629 }
630 return $this->finalStatusBox('warning', 'eBay-Rueckmeldung fehlt oder ist offen', $text, $extra);
631 }
632
633 return $this->finalStatusBox('info', 'eBay-Status pruefen', 'Alle Workflow-Schritte sind erledigt, der technische Status ist aber nicht eindeutig als veroeffentlicht markiert.', $extra);
634 }
635
636 public function renderFinalStatus(array $definition, array $values, string $instanceStatus, int $completed, int $total, array $missingLabels): string {
637 $definition = $this->applyBindRef($definition);
638 if ((string)($definition['workflow_key'] ?? '') === 'shop_ebay_publish') {
639 return $this->ebayFinalStatus($values, $instanceStatus, $completed, $total, $missingLabels);
640 }
641 return $this->genericFinalStatus($definition, $instanceStatus, $completed, $total, $missingLabels);
642 }
643
644 private function resolveToken($token, array $definition, array $values, array $record) {
645 $token = trim((string)$token);
646 if ($token === '@now') {
647 return date('Y-m-d H:i:s');
648 }
649 if ($token === '@uid') {
650 return (int)dbx()->user();
651 }
652 if (strpos($token, '@need:') === 0) {
653 $needKey = substr($token, 6);
654 return $values[$needKey] ?? '';
655 }
656 if (array_key_exists($token, $values)) {
657 return $values[$token];
658 }
659 if (array_key_exists($token, $record)) {
660 return $record[$token];
661 }
662
663 return $token;
664 }
665
666 private function resolveMap(array $map, array $definition, array $values, array $record) {
667 $out = array();
668 foreach ($map as $dbField => $source) {
669 $out[$dbField] = $this->resolveToken($source, $definition, $values, $record);
670 }
671 return $out;
672 }
673
674 private function shopWorkflowFinish(array $definition, array $values) {
675 $workflowKey = (string)($definition['workflow_key'] ?? '');
676 if ($workflowKey !== 'shop_article_publish' && $workflowKey !== 'shop_ebay_publish') {
677 return null;
678 }
679
680 $productId = (int)($values['product'] ?? 0);
681 if ($productId <= 0) {
682 return array('ok' => 0, 'message' => 'Kein Artikel ausgewaehlt.');
683 }
684
685 if ($workflowKey === 'shop_article_publish') {
686 $release = (string)($values['final_check'] ?? '');
687 if ($release === 'draft') {
688 return array('ok' => 1, 'message' => 'Artikel bleibt als Entwurf vorbereitet.');
689 }
690
691 $ok = $this->db()->update(
692 'dbxShop|shopProduct',
693 array('active' => 1, 'update_date' => date('Y-m-d H:i:s'), 'update_uid' => (int)dbx()->user()),
694 array('id' => $productId, 'trash' => 0),
695 1,
696 1,
697 1,
698 1
699 );
700 if ($ok !== 1) {
701 return array('ok' => 0, 'message' => 'Artikel konnte nicht freigegeben werden.');
702 }
703 return array('ok' => 1, 'message' => 'Artikel wurde im Shop freigegeben.');
704 }
705
706 $channelRows = $this->db()->select(
707 'dbxShop|shopProductChannel',
708 array('product_id' => $productId, 'channel_key' => 'ebay'),
709 '*',
710 'id',
711 'DESC',
712 '',
713 1,
714 0,
715 1
716 );
717 if (!is_array($channelRows)) {
718 return array('ok' => 0, 'message' => 'Channel-Daten konnten nicht gelesen werden.');
719 }
720 $channelRow = (is_array($channelRows) && isset($channelRows[0])) ? $channelRows[0] : array();
721 if (trim((string)($channelRow['last_export_date'] ?? '')) !== '') {
722 $status = trim((string)($channelRow['export_status'] ?? ''));
723 $message = trim((string)($channelRow['export_message'] ?? ''));
724 return array(
725 'ok' => 1,
726 'message' => 'eBay-Exportstatus wurde uebernommen' . ($status !== '' ? ': ' . $status : '') . ($message !== '' ? ' - ' . $message : '') . '.'
727 );
728 }
729
730 $repo = dbx()->get_include_obj('dbxShopRepository', 'dbxShop');
731 if (!is_object($repo) || !method_exists($repo, 'exportProductToChannel')) {
732 return array('ok' => 0, 'message' => 'Shop-Repository fuer den Channel-Export konnte nicht geladen werden.');
733 }
734 $result = (array)$repo->exportProductToChannel($productId, 'ebay');
735 if (empty($result['ok'])) {
736 return array('ok' => 0, 'message' => (string)($result['message'] ?? 'eBay-Export fehlgeschlagen.'));
737 }
738
739 return array('ok' => 1, 'message' => (string)($result['message'] ?? 'eBay-Export wurde ausgefuehrt.'));
740 }
741
742 public function applyFinish(array $definition, array $values) {
743 $definition = $this->applyBindRef($definition);
744 $shopResult = $this->shopWorkflowFinish($definition, $values);
745 if (is_array($shopResult)) {
746 return $shopResult;
747 }
748
749 $finish = (array)($this->bindConfig($definition)['finish'] ?? array());
750 if (!$finish || (string)($finish['type'] ?? '') !== 'dd_update') {
751 return null;
752 }
753
754 $recordCfg = $this->recordConfig($definition);
755 $dd = trim((string)($recordCfg['dd'] ?? ''));
756 $rid = $this->recordIdFromValues($definition, $values);
757 if ($dd === '' || $rid <= 0) {
758 return array('ok' => 0, 'message' => 'Kein Datensatz fuer den Abschluss ausgewaehlt.');
759 }
760
761 $record = $this->loadRecord($definition, $rid);
762 if (!$record) {
763 return array('ok' => 0, 'message' => 'Datensatz #' . $rid . ' wurde nicht gefunden.');
764 }
765
766 $update = $this->resolveMap((array)($finish['map'] ?? array()), $definition, $values, $record);
767
768 if (array_key_exists('reply_text', (array)($finish['map'] ?? array()))) {
769 $replyText = trim((string)($update['reply_text'] ?? ''));
770 if (strlen($replyText) < 2) {
771 return array('ok' => 0, 'message' => 'Bitte eine Rueckmeldung mit mindestens 2 Zeichen erfassen.');
772 }
773 }
774
775 $ok = $this->db()->update($dd, $update, $rid);
776 if ($ok !== 1) {
777 return array('ok' => 0, 'message' => 'Datensatz konnte nicht gespeichert werden.');
778 }
779
780 $message = 'Datensatz #' . $rid . ' wurde gespeichert.';
781 $mail = (array)($finish['mail'] ?? array());
782
783 if ($mail) {
784 $whenNeed = trim((string)($mail['when_need'] ?? ''));
785 $whenValue = (string)($mail['when_value'] ?? '1');
786 $send = ($whenNeed === '') || ((string)($values[$whenNeed] ?? '') === $whenValue);
787
788 $configModul = trim((string)($mail['config_modul'] ?? ($definition['bind']['modul'] ?? '')));
789 $modeKey = trim((string)($mail['mode_key'] ?? 'reply_mode'));
790 if ($configModul !== '' && $modeKey !== '' && !$this->configHasPart($configModul, $modeKey, 'mail')) {
791 $send = false;
792 }
793
794 if ($send) {
795 $toField = trim((string)($mail['to_field'] ?? 'email'));
796 $to = trim((string)($record[$toField] ?? ''));
797 if ($to === '') {
798 $message .= ' E-Mail-Versand nicht moeglich (keine Adresse).';
799 } else {
800 $subjectTpl = (string)($mail['subject_tpl'] ?? 'Antwort');
801 $subject = $this->labelFromTemplate($subjectTpl, array_merge($record, $update));
802 $bodyTpl = trim((string)($mail['body_tpl'] ?? ''));
803 $bodyVars = array();
804 foreach ((array)($mail['body_vars'] ?? array()) as $tplKey => $source) {
805 $bodyVars[$tplKey] = $this->h($this->resolveToken($source, $definition, $values, $record));
806 }
807 $html = $bodyTpl !== '' ? $this->tpl()->get_tpl($bodyTpl, $bodyVars) : nl2br($this->h((string)($update['reply_text'] ?? '')));
808
809 $from = trim((string)dbx()->get_config($configModul, 'mail_from'));
810 $fromName = trim((string)dbx()->get_config($configModul, 'mail_from_name'));
811 $fromParam = ($from !== '') ? array('email' => $from, 'name' => $fromName) : '';
812 $options = array('text' => strip_tags(str_replace('<br />', "\n", $html)));
813 $profile = trim((string)dbx()->get_config($configModul, 'mail_profile'));
814 if ($profile !== '') {
815 $options['mail_profile'] = $profile;
816 }
817
818 $mailOk = dbx()->send_mail($fromParam, $to, $subject, $html, 'html', array(), $options);
819 if ($mailOk) {
820 $track = $this->resolveMap((array)($mail['track_fields'] ?? array()), $definition, $values, $record);
821 if ($track) {
822 $this->db()->update($dd, $track, $rid);
823 }
824 $message .= ' E-Mail wurde versendet.';
825 } else {
826 $message .= ' E-Mail-Versand fehlgeschlagen.';
827 }
828 }
829 }
830 }
831
832 return array('ok' => 1, 'message' => $message);
833 }
834}
835?>
applyFinish(array $definition, array $values)
renderFormValue(array $definition, array $need, array $values)
formatValueLabel(array $definition, array $need, $value)
optionsFromSource(array $source, array $values=array(), $includeId=0)
renderFinalStatus(array $definition, array $values, string $instanceStatus, int $completed, int $total, array $missingLabels)
enrichDefinition(array $definition, array $values=array())
renderStepContext(array $definition, array $need, array $values)
recordIdFromValues(array $definition, array $values)
$fields[]
Definition config.dd.php:16
$field
Definition config.dd.php:4
if( $syncRequest)
Definition index.php:520
dbx_get_base_dir($cut_Data=0)
Definition index.php:157
DBX schema administration.
if(! $db->connect_db_server($server)) $result