6 private $ddBind =
'dbxWorkflow|workflowModuleBind';
8 private function db() {
9 return dbx()->get_system_obj(
'dbxDB');
12 private function tpl() {
13 return dbx()->get_system_obj(
'dbxTPL');
16 private function h($value) {
17 return htmlspecialchars((
string)$value, ENT_QUOTES,
'UTF-8');
20 private function read_json($value, $default = array()) {
21 $value = trim((
string)$value);
25 $data = json_decode($value,
true);
26 return is_array($data) ? $data : $default;
30 $bindRef = trim((
string)$bindRef);
31 if ($bindRef ===
'' || strpos($bindRef,
'|') ===
false) {
35 $parts = explode(
'|', $bindRef, 2);
36 return array(trim((
string)$parts[0]), trim((
string)$parts[1]));
41 if ($modul ===
'' || $bindKey ===
'') {
45 $rows = $this->db()->select(
47 array(
'modul' => $modul,
'bind_key' => $bindKey,
'active' => 1,
'trash' => 0),
57 return (is_array($rows) && isset($rows[0])) ? $rows[0] : array();
61 $bindRef = trim((
string)($definition[
'bind_ref'] ??
''));
62 if ($bindRef ===
'') {
71 $bind = $this->read_json($row[
'bind_json'] ??
'', array());
73 $definition[
'bind'] = $bind;
79 private function bindConfig(array $definition) {
80 return (array)($definition[
'bind'] ?? array());
83 private function recordConfig(array $definition) {
84 return (array)($this->bindConfig($definition)[
'record'] ?? array());
88 $record = $this->recordConfig($definition);
89 $idNeed = trim((
string)($record[
'id_need'] ??
''));
90 if ($idNeed ===
'' || !array_key_exists($idNeed, $values)) {
94 return (
int)preg_replace(
'/\D+/',
'', (
string)$values[$idNeed]);
97 public function loadRecord(array $definition, $rid = 0) {
98 $recordCfg = $this->recordConfig($definition);
99 $dd = trim((
string)($recordCfg[
'dd'] ??
''));
101 if ($dd ===
'' || $rid <= 0) {
105 $row = $this->db()->select1($dd, $rid);
106 return (is_array($row) && $row) ? $row : array();
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);
120 private function optionsFromDdSelect(array $bindNeed, array $definition, array $values) {
121 $record = $this->recordConfig($definition);
122 $dd = trim((
string)($record[
'dd'] ??
''));
127 $source = array_merge(
128 array(
'dd' => $dd,
'include_from' => (
string)($record[
'id_need'] ??
'')),
136 $dd = trim((
string)($source[
'dd'] ??
''));
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 .
'}')));
146 if ($valueField !==
'' && !in_array($valueField,
$fields,
true)) {
150 $rows = $this->db()->select(
154 (
string)($source[
'order_field'] ??
'id'),
155 (
string)($source[
'order_dir'] ??
'DESC'),
157 (
int)($source[
'limit'] ?? 200),
165 foreach ((array)$rows as $row) {
166 $id = (string)($row[$valueField] ??
'');
173 'label' => $this->labelFromTemplate($labelTpl, $row),
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) {
182 'value' => $includeId,
183 'label' => $this->labelFromTemplate($labelTpl, $record),
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 ===
'') {
199 $oDD =
dbx()->get_system_obj(
'dbxDD');
200 $model = $oDD->get_dd_model($dd);
203 foreach ((array)($model[
'fields'] ?? array()) as
$field) {
204 if ((
string)(
$field[
'name'] ??
'') === $fieldName) {
205 $optionsRaw = (string)(
$field[
'options'] ??
'');
210 if ($optionsRaw ===
'') {
215 foreach (explode(
'&', $optionsRaw) as $pair) {
217 if ($pair ===
'' || strpos($pair,
'=') ===
false) {
220 list($value, $label) = explode(
'=', $pair, 2);
222 'value' => trim($value),
223 'label' => trim($label),
230 private function configHasPart($modul, $key, $part) {
231 if ($part !==
'mail') {
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)) {
242 if (class_exists(
'\\dbx\\dbxContact\\dbxContactConfig',
false)) {
243 return \dbx\dbxContact\dbxContactConfig::modulMailEnabled((
string) $modul, (
string) $key);
246 $mode = strtolower(trim((
string) dbx()->get_config($modul, $key)));
247 return ($mode ===
'both' || $mode ===
'mail' || strpos($mode,
'mail') !==
false);
250 private function needBind(array $definition, $needKey) {
251 return (array)($this->bindConfig($definition)[
'needs'][$needKey] ?? array());
254 private function needVisible(array $definition, $needKey, array $bindNeed) {
255 $showIf = (array)($bindNeed[
'show_if_config'] ?? array());
260 $modul = trim((
string)($showIf[
'modul'] ??
''));
261 $key = trim((
string)($showIf[
'key'] ??
''));
262 $has = trim((
string)($showIf[
'has'] ??
''));
264 if ($modul ===
'' || $key ===
'' || $has ===
'') {
268 return $this->configHasPart($modul, $key, $has);
273 $bindNeeds = (array)($this->bindConfig($definition)[
'needs'] ?? array());
276 foreach ((array)($definition[
'needs'] ?? array()) as $need) {
277 if (!is_array($need)) {
281 $key = (string)($need[
'key'] ??
'');
282 $bindNeed = (array)($bindNeeds[$key] ?? array());
284 if ($bindNeed && !$this->needVisible($definition, $key, $bindNeed)) {
288 if (!empty($need[
'source']) && is_array($need[
'source'])) {
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()));
308 $definition[
'needs'] = $needs;
309 $definition = $this->enrichShopEbayPublishDefinition($definition, $values);
313 private function enrichShopEbayPublishDefinition(array $definition, array $values): array {
314 if ((string)($definition[
'workflow_key'] ??
'') !==
'shop_ebay_publish') {
318 $productId = (int)($values[
'product'] ?? 0);
319 if ($productId <= 0) {
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'),
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'] ??
''));
340 foreach ($definition[
'needs'] as &$need) {
341 if ((
string)($need[
'key'] ??
'') !==
'ebay_view') {
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(
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',
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',
367 if ($offerId !==
'') {
368 $extra[] =
'Offer-ID: ' . $offerId;
370 if ($status !==
'') {
371 $extra[] =
'Status: ' . $status;
373 if ($message !==
'') {
376 $need[
'hint'] =
'Optionaler Kontrollschritt: Es ist noch keine eBay Listing-ID gespeichert. Pruefe zuerst Exportstatus und Mapping.'
377 . ($extra ?
' ' . implode(
' | ', $extra) :
'');
387 $recordCfg = $this->recordConfig($definition);
389 if (empty($recordCfg[
'prefill_rid']) || $rid <= 0) {
393 $record = $this->
loadRecord($definition, $rid);
399 $idNeed = trim((
string)($recordCfg[
'id_need'] ??
''));
400 if ($idNeed !==
'') {
401 $values[$idNeed] = (string)$rid;
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']];
409 if ($type ===
'dd_field_value' && isset($record[(
string)($bindNeed[
'field'] ??
'')])) {
410 $text = trim((
string)$record[(
string)$bindNeed[
'field']]);
412 $values[$needKey] = $text;
420 private function contextData(array $definition, array $record) {
421 $context = (array)($this->bindConfig($definition)[
'context'] ?? array());
422 $fields = (array)($context[
'fields'] ?? array());
425 foreach (
$fields as $tplKey => $recordKey) {
426 $value = $record[(string)$recordKey] ??
'';
427 if ($tplKey ===
'phone' && trim((
string)$value) ===
'') {
430 $data[$tplKey] = $this->h($value);
438 $context = (array)($this->bindConfig($definition)[
'context'] ?? array());
443 $hideOn = trim((
string)($context[
'hide_on_need'] ??
''));
446 if ($rid > 0 && $hideOn !==
'' && $need[
'key'] !== $hideOn) {
447 $record = $this->
loadRecord($definition, $rid);
449 $tpl = trim((
string)($context[
'tpl'] ??
''));
451 return $this->tpl()->get_tpl($tpl, $this->contextData($definition, $record));
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);
462 return $this->tpl()->get_tpl(
'dbx|alert-info', array(
463 'msg' =>
'Keine passenden Datensaetze gefunden. Bitte zuerst im Modul erfassen.',
474 $bindNeed = $this->needBind($definition, (
string)($need[
'key'] ??
''));
475 if ((
string)($bindNeed[
'type'] ??
'') !==
'dd_field_value') {
479 if (array_key_exists($need[
'key'], $values)) {
480 return $this->h($values[$need[
'key']]);
485 $record = $this->
loadRecord($definition, $rid);
486 $field = (string)($bindNeed[
'field'] ??
'');
487 if ($record &&
$field !==
'') {
488 return $this->h(trim((
string)($record[
$field] ??
'')));
497 $needKey = (string)($need[
'key'] ??
'');
498 $bindNeed = $this->needBind($definition, $needKey);
500 if (is_array($value) && !empty($value[
'skipped'])) {
501 return '<em>Uebersprungen</em>';
504 if ((
string)($bindNeed[
'type'] ??
'') ===
'dd_select') {
505 $record = $this->
loadRecord($definition, (
int)$value);
507 return $this->h($this->labelFromTemplate((
string)($bindNeed[
'label'] ??
'#{id}'), $record));
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']);
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']);
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>'
542 private function genericFinalStatus(array $definition,
string $instanceStatus,
int $completed,
int $total, array $missingLabels): string {
543 if ($missingLabels !== array()) {
544 return $this->finalStatusBox(
546 'Workflow noch nicht vollstaendig',
547 'Es fehlen noch Pflichtschritte: ' . implode(
', ', $missingLabels) .
'.'
551 if ($instanceStatus ===
'finished') {
552 return $this->finalStatusBox(
554 'Workflow komplett abgeschlossen',
555 'Alle notwendigen Schritte sind erledigt. Ergebnis: ' . (
string)($definition[
'result'] ?? $definition[
'title'] ??
'Workflow') .
'.'
559 return $this->finalStatusBox(
561 'Workflow bereit zum Abschluss',
562 'Alle notwendigen Schritte sind erledigt (' . $completed .
' von ' . $total .
'). Pruefe die Zusammenfassung und schliesse den Workflow ab.'
566 private function ebayFinalStatus(array $values,
string $instanceStatus,
int $completed,
int $total, array $missingLabels): string {
567 if ($missingLabels !== array()) {
568 return $this->finalStatusBox(
570 'eBay-Workflow noch nicht vollstaendig',
571 'Es fehlen noch Pflichtschritte: ' . implode(
', ', $missingLabels) .
'.'
575 $productId = (int)($values[
'product'] ?? 0);
576 if ($productId <= 0) {
577 return $this->finalStatusBox(
'warning',
'eBay-Status unklar',
'Es ist kein Artikel ausgewaehlt.');
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'),
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'] ??
'');
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>';
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>';
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);
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);
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);
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.';
630 return $this->finalStatusBox(
'warning',
'eBay-Rueckmeldung fehlt oder ist offen', $text, $extra);
633 return $this->finalStatusBox(
'info',
'eBay-Status pruefen',
'Alle Workflow-Schritte sind erledigt, der technische Status ist aber nicht eindeutig als veroeffentlicht markiert.', $extra);
636 public function renderFinalStatus(array $definition, array $values,
string $instanceStatus,
int $completed,
int $total, array $missingLabels): string {
638 if ((
string)($definition[
'workflow_key'] ??
'') ===
'shop_ebay_publish') {
639 return $this->ebayFinalStatus($values, $instanceStatus, $completed, $total, $missingLabels);
641 return $this->genericFinalStatus($definition, $instanceStatus, $completed, $total, $missingLabels);
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');
649 if ($token ===
'@uid') {
650 return (
int)
dbx()->user();
652 if (strpos($token,
'@need:') === 0) {
653 $needKey = substr($token, 6);
654 return $values[$needKey] ??
'';
656 if (array_key_exists($token, $values)) {
657 return $values[$token];
659 if (array_key_exists($token, $record)) {
660 return $record[$token];
666 private function resolveMap(array $map, array $definition, array $values, array $record) {
668 foreach ($map as $dbField => $source) {
669 $out[$dbField] = $this->resolveToken($source, $definition, $values, $record);
674 private function shopWorkflowFinish(array $definition, array $values) {
675 $workflowKey = (string)($definition[
'workflow_key'] ??
'');
676 if ($workflowKey !==
'shop_article_publish' && $workflowKey !==
'shop_ebay_publish') {
680 $productId = (int)($values[
'product'] ?? 0);
681 if ($productId <= 0) {
682 return array(
'ok' => 0,
'message' =>
'Kein Artikel ausgewaehlt.');
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.');
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),
701 return array(
'ok' => 0,
'message' =>
'Artikel konnte nicht freigegeben werden.');
703 return array(
'ok' => 1,
'message' =>
'Artikel wurde im Shop freigegeben.');
706 $channelRows = $this->db()->select(
707 'dbxShop|shopProductChannel',
708 array(
'product_id' => $productId,
'channel_key' =>
'ebay'),
717 if (!is_array($channelRows)) {
718 return array(
'ok' => 0,
'message' =>
'Channel-Daten konnten nicht gelesen werden.');
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'] ??
''));
726 'message' =>
'eBay-Exportstatus wurde uebernommen' . ($status !==
'' ?
': ' . $status :
'') . ($message !==
'' ?
' - ' . $message :
'') .
'.'
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.');
734 $result = (array)
$repo->exportProductToChannel($productId,
'ebay');
736 return array(
'ok' => 0,
'message' => (
string)(
$result[
'message'] ??
'eBay-Export fehlgeschlagen.'));
739 return array(
'ok' => 1,
'message' => (
string)(
$result[
'message'] ??
'eBay-Export wurde ausgefuehrt.'));
744 $shopResult = $this->shopWorkflowFinish($definition, $values);
745 if (is_array($shopResult)) {
749 $finish = (array)($this->bindConfig($definition)[
'finish'] ?? array());
750 if (!$finish || (
string)($finish[
'type'] ??
'') !==
'dd_update') {
754 $recordCfg = $this->recordConfig($definition);
755 $dd = trim((
string)($recordCfg[
'dd'] ??
''));
757 if ($dd ===
'' || $rid <= 0) {
758 return array(
'ok' => 0,
'message' =>
'Kein Datensatz fuer den Abschluss ausgewaehlt.');
761 $record = $this->
loadRecord($definition, $rid);
763 return array(
'ok' => 0,
'message' =>
'Datensatz #' . $rid .
' wurde nicht gefunden.');
766 $update = $this->resolveMap((array)($finish[
'map'] ?? array()), $definition, $values, $record);
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.');
775 $ok = $this->db()->update($dd, $update, $rid);
777 return array(
'ok' => 0,
'message' =>
'Datensatz konnte nicht gespeichert werden.');
780 $message =
'Datensatz #' . $rid .
' wurde gespeichert.';
781 $mail = (array)($finish[
'mail'] ?? array());
784 $whenNeed = trim((
string)($mail[
'when_need'] ??
''));
785 $whenValue = (string)($mail[
'when_value'] ??
'1');
786 $send = ($whenNeed ===
'') || ((
string)($values[$whenNeed] ??
'') === $whenValue);
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')) {
795 $toField = trim((
string)($mail[
'to_field'] ??
'email'));
796 $to = trim((
string)($record[$toField] ??
''));
798 $message .=
' E-Mail-Versand nicht moeglich (keine Adresse).';
800 $subjectTpl = (string)($mail[
'subject_tpl'] ??
'Antwort');
801 $subject = $this->labelFromTemplate($subjectTpl, array_merge($record, $update));
802 $bodyTpl = trim((
string)($mail[
'body_tpl'] ??
''));
804 foreach ((array)($mail[
'body_vars'] ?? array()) as $tplKey => $source) {
805 $bodyVars[$tplKey] = $this->h($this->resolveToken($source, $definition, $values, $record));
807 $html = $bodyTpl !==
'' ? $this->tpl()->get_tpl($bodyTpl, $bodyVars) : nl2br($this->h((
string)($update[
'reply_text'] ??
'')));
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;
818 $mailOk =
dbx()->send_mail($fromParam, $to, $subject, $html,
'html', array(), $options);
820 $track = $this->resolveMap((array)($mail[
'track_fields'] ?? array()), $definition, $values, $record);
822 $this->db()->update($dd, $track, $rid);
824 $message .=
' E-Mail wurde versendet.';
826 $message .=
' E-Mail-Versand fehlgeschlagen.';
832 return array(
'ok' => 1,
'message' => $message);