attachmentLocator = $attachmentLocator; } /** @required */ public function setContextManager(ContextManager $contextManager) { $this->contextManager = $contextManager; } /** @var \Order */ protected $order; public function setOrder(\Order $order) { $this->order = $order; return $this; } public function getOrder() { return $this->order; } protected $comment; public function setComment($comment) { $this->comment = $comment; return $this; } public function setIsAdminEmail(bool $isAdminEmail): self { $this->isAdminEmail = $isAdminEmail; return $this; } public function setSendToInvoiceCopyEmail(?bool $sendToInvoiceCopyEmail): self { $this->sendToInvoiceCopyEmail = $sendToInvoiceCopyEmail; return $this; } public function getEmailTemplate($languageID = null): array { if (!$languageID && $this->order) { $languageID = $this->order->id_language; } return parent::getEmailTemplate($languageID); } /** * @return array */ public function getBasicTemplate($languageID = null) { if (!$languageID && $this->order) { $languageID = $this->order->id_language; } return parent::getBasicTemplate($languageID); } public function renderEmail($template, $data = [], $base_template = 'order.tpl'): array { if ($this->comment) { $template['body'] = str_replace('{KOMENTAR}', $this->comment, $template['body']); } if ($this->order) { $data = array_merge($data, ['order' => $this->order]); } $message = parent::renderEmail($template, $data, $base_template); if ($this->order) { $message['to'] = $this->order->getUserEmail(); if ($this->shouldSendCopyEmail($template['attachments'])) { if ($copyEmail = $this->order->getCopyEmail()) { $message['cc'] = $copyEmail; } } } $message['template'] = $template; return $message; } public function replacePlaceholdersItem($placeholder) { switch ($placeholder) { case 'DATUM_DORUCENI': $delivery_date = $this->orderInfo->getDeliveryDate($this->order); if (!$delivery_date) { // produkt neni skladem a nevime kdy bude => nemuzeme napsat datum doruceni return translate_shop('unknownDeliveryDate', 'order'); } return $delivery_date->format(\Settings::getDateFormat()); case 'POLOZKY_EXCEL': return path('kupshop_orderingbundle_xlsinvoice', ['id_order' => $this->order->id, 'cf' => $this->order->getSecurityCode()], Router::ABSOLUTE_URL); case 'ODKAZ_FAKTURA': // spousta shopu ma tenhle placeholder pridany custom na shopu v class.Order.php, takze nejdriv to zkusim vytahnout // pres order a pokud to existuje, tak vratim to kvuli backward compatibility if ($result = $this->order->replacePlaceholdersItem($placeholder)) { return $result; } return path( 'kupshop_orderingbundle_pdfinvoice', [ 'id_order' => $this->order->id, 'cf' => $this->order->getSecurityCode(), ], Router::ABSOLUTE_URL ); case 'BALIKY': // could be more than one package $packages = []; foreach ($this->orderInfo->getPackages($this->order) as $package_id => $package) { if ($link = $package['track_url'] ?? null) { $packages[] = "{$package_id}"; } else { $packages[] = $package_id; } } return implode(', ', $packages); case 'TELEFON_FAKTURACNI': return $this->order->invoice_phone; case 'TELEFON_DODACI': return $this->order->delivery_phone; case 'MISTO_ODBERU': $value = ''; $deliveryType = $this->order->getDeliveryType(); // vracim udaje jen kdy je typ doruceni POINT if ($deliveryType->delivery_class->getType() == \DeliveryBase::TYPE_POINT) { $value = $deliveryType->getDelivery()->name.': '.$deliveryType->getDelivery()->printDeliveryInfo(); } return $value; case 'URL_PRODEJCE': $value = ''; $deliveryType = $this->order->getDeliveryType(); // vracim udaje jen kdyz je typ doruceni IN_PERSON if ($deliveryType->delivery_class->getType() == \DeliveryBase::TYPE_IN_PERSON) { if ($sellerId = SellerOrderUtil::getOrderSellerId($this->order->id)) { $value = path('shop_seller_seller_detail', ['id_seller' => $sellerId]); } } return $value; case 'JMENO': return $this->order->invoice_name; case 'PRIJMENI': return $this->order->invoice_surname; } $parent = parent::replacePlaceholdersItem($placeholder); if ($parent === null) { return $this->order->replacePlaceholdersItem($placeholder); } return $parent; } public function getAttachments($template): array { if (empty($template['attachments']) || !$this->order) { return []; } return $this->renderAttachments(function () use ($template): iterable { $types = json_decode($template['attachments'], true); foreach ($types as $type) { $attachment = $this->attachmentLocator->getServiceByType($type, $this->order); yield $attachment; } }); } public function testEmail(): array { if (!isset($this->order)) { $this->setTestEntity(); } $this->order->setPlaceholder('KOMENTAR', '
Testovací komentář od uživatele.
'); try { return $this->contextManager->activateOrder( $this->order, function () { return parent::testEmail(); } ); } catch (\Throwable $e) { throw new \InvalidArgumentException('E-mail nelze otestovat, protože neexistuje žádná objednávka', previous: $e); } } public function setTestEntity(?int $id = null): void { $order = new \Order(); $order->createFromDB($id ?: sqlQueryBuilder()->select('MAX(id)')->from('orders')->execute()->fetchOne()); $this->setOrder($order); } public function sendEmail($message, $logComment = null) { // pokud je email vypnutej, tak nedava smysl logovat odeslani mailu if ($this->isEnabled()) { $this->logHistory($message, $logComment); } if (($bcc = (\Settings::getDefault()->archive_email ?? null)) && $bcc !== ($message['to'] ?? null)) { $message['bcc'] = [$bcc]; } $messageId = parent::sendEmail($message); if ($messageId && !empty($message['id_history'])) { // update orders_history with email ID sqlQueryBuilder()->update('orders_history') ->set('custom_data', JsonOperator::set('custom_data', 'email_id', $messageId)) ->where(Operator::equals(['id' => $message['id_history']])) ->execute(); } return $messageId; } protected function logHistory(&$message, $comment = null) { $historyId = null; $notifiedStatus = $this->isAdminEmail ? 0 : 4; if ($this->logSentEmail && $this->order) { $template = $message['template']; $customData['email_type'] = self::getType(); if (self::getType() == 'ORDER_MESSAGE') { $customData['email_type'] = 'Zprávy uživatelům: '.$this->order_message; } $customData['subject'] = $message['subject']; $customData['isAdminEmail'] = $this->isAdminEmail; if ($template['attachments']) { // get attachments types because of saving them into history $types = json_decode($template['attachments'], true); $customData['attachments'] = empty($types) ? null : $types; } // Renders only body from email to $comment if (is_null($comment)) { $comment = $this->renderOnlyBody($message, ['order' => $this->order]); } // Write history $comment = $this->replacePlaceholders($comment); $historyId = $this->order->logHistory($comment, $notifiedStatus, $customData); } $message['isAdminEmail'] = $this->isAdminEmail; $message['id_history'] = $historyId; } public static function getPlaceholders() { $placeholders = [ 'KOD' => [ 'text' => translate('OrderCode', 'emails'), ], 'STAV' => [ 'text' => translate('NewOrderStatus', 'emails'), ], 'CENA' => [ 'text' => translate('OrderPrice', 'emails'), ], 'ZAPLATIT' => [ 'text' => translate('RemainsPaid', 'emails'), ], 'ODKAZ' => [ 'text' => translate('ReferenceDetail', 'emails'), ], 'ODKAZ_PLATBA' => [ 'text' => translate('ReferencePayment', 'emails'), ], 'DATUM_OBJEDNAVKY' => [ 'text' => translate('OrderDate', 'emails'), ], 'CAS_OBJEDNAVKY' => [ 'text' => translate('OrderTime', 'emails'), ], 'JMENO' => [ 'text' => translate('UserName', 'emails'), ], 'PRIJMENI' => [ 'text' => translate('UserSurname', 'emails'), ], 'OSLOVENI_JMENO' => [ 'text' => translate('GreetingUserName', 'emails'), ], 'OSLOVENI_PRIJMENI' => [ 'text' => translate('GreetingUserSurname', 'emails'), ], 'EMAIL_UZIVATELE' => [ 'text' => translate('UsersEmail', 'emails'), ], 'KOMENTAR' => [ 'text' => translate('CommentEntered', 'emails'), ], 'POLOZKY_OBJEDNAVKY' => [ 'text' => translate('ListOfItems', 'emails'), ], 'QR_PLATBA' => [ 'text' => translate('qrcodePayment', 'emails'), ], 'DATUM_SPLATNOSTI' => [ 'text' => translate('dueDate', 'emails'), ], 'FAKTURACNI_ADRESA' => [ 'text' => translate('invoiceAddress', 'emails'), ], 'DODACI_ADRESA' => [ 'text' => translate('deliveryAddress', 'emails'), ], 'POZNAMKA_UZIVATELE' => [ 'text' => translate('userNote', 'emails'), ], 'POLOZKY_EXCEL' => [ 'text' => translate('invoice_xls', 'emails'), ], 'ODKAZ_FAKTURA' => [ 'text' => translate('invoice_pdf', 'emails'), ], 'BALIKY' => [ 'text' => translate('LinkToWebpage', 'emails'), ], 'CISLO_FAKTURY' => [ 'text' => translate('invoice_no', 'emails'), ], ]; if (findModule(\Modules::DELIVERY_TYPES)) { $placeholders['POPIS_ZPUSOBU_DORUCENI'] = [ 'text' => translate('DescriptionOfSelected', 'emails').' '.translate('DescriptionOfSelectedLink', 'emails').'', ]; $placeholders['POPIS_PLATBY'] = [ 'text' => translate('DescriptionOfSelectedPay', 'emails').' '.translate('DescriptionOfSelectedPayLink', 'emails').'', ]; $placeholders['POPIS_DOPRAVY'] = [ 'text' => translate('DescriptionOfSelectedPay', 'emails').' '.translate('DescriptionOfSelectedTransport', 'emails').'', ]; } $placeholders['DATUM_DORUCENI'] = ['text' => translate('deliveryDate', 'emails')]; if (findModule(\Modules::BONUS_PROGRAM)) { $placeholders['BONUS_PROGRAM_BODY'] = [ 'text' => translate('bonusProgramPoints', 'emails'), ]; $placeholders['ZBYVAJICI_BONUS_PROGRAM_BODY'] = [ 'text' => translate('bonusProgramPointsRemaining', 'emails'), ]; } $placeholders['TELEFON_FAKTURACNI'] = ['text' => translate('invoicePhone', 'emails')]; $placeholders['TELEFON_DODACI'] = ['text' => translate('deliveryPhone', 'emails')]; $placeholders['MISTO_ODBERU'] = ['text' => translate('deliveryLocation', 'emails')]; $placeholders['URL_PRODEJCE'] = ['text' => translate('sellerUrl', 'emails')]; return [self::$type => $placeholders] + (parent::getPlaceholders() ?? []); } public function getMicrodata(): array { if ($order = $this->getOrder()) { try { return $this->microdataUtil->getOrderMicrodata($order); } catch (\Throwable $exception) { \Sentry\captureException($exception); } } return []; } public function __wakeup() { parent::__wakeup(); $this->attachmentLocator = ServiceContainer::getService(AttachmentLocator::class); $this->contextManager = ServiceContainer::getService(ContextManager::class); $this->orderInfo = ServiceContainer::getService(OrderInfo::class); $this->microdataUtil = ServiceContainer::getService(Microdata::class); } public function __sleep() { return array_diff(parent::__sleep(), ['attachmentLocator', 'contextManager', 'orderInfo', 'microdataUtil']); } public function getTestType(): ?string { return self::$type_test_email; } public function shouldSendCopyEmail($attachments): bool { return $this->sendToInvoiceCopyEmail ?? in_array(InvoicePDFAttachment::getType(), json_decode($attachments ?? '', true) ?? []); } }