diff --git a/config.codekit3 b/config.codekit3 index 6e0b0d5..57398a9 100644 --- a/config.codekit3 +++ b/config.codekit3 @@ -526,7 +526,7 @@ "rFN": 0, "uCM": 0 }, - "/docs/template-guides/voucher-template.md": { + "/docs/template-guides/single-voucher.md": { "cB": 0, "cS": 0, "eF": 1, @@ -536,7 +536,26 @@ "ft": 4096, "hM": 0, "oA": 1, - "oAP": "/docs/template-guides/voucher-template.html", + "oAP": "/docs/template-guides/single-voucher.html", + "oF": 0, + "oFM": 0, + "oS": 0, + "pHT": 0, + "pME": 1, + "rFN": 0, + "uCM": 0 + }, + "/docs/template-guides/vouchers-index.md": { + "cB": 0, + "cS": 0, + "eF": 1, + "eL": 1, + "ema": 1, + "eSQ": 1, + "ft": 4096, + "hM": 0, + "oA": 1, + "oAP": "/docs/template-guides/vouchers-index.html", "oF": 0, "oFM": 0, "oS": 0, diff --git a/src/controllers/VouchersController.php b/src/controllers/VouchersController.php index 06b870d..698b0f8 100755 --- a/src/controllers/VouchersController.php +++ b/src/controllers/VouchersController.php @@ -3,6 +3,7 @@ use verbb\giftvoucher\GiftVoucher; use verbb\giftvoucher\elements\Voucher; +use verbb\giftvoucher\helpers\VoucherHelper; use Craft; use craft\base\Element; @@ -19,6 +20,7 @@ use yii\base\Exception; use yii\base\InvalidConfigException; +use yii\base\Model; use yii\web\BadRequestHttpException; use yii\web\ForbiddenHttpException; use yii\web\HttpException; @@ -108,7 +110,7 @@ public function actionEdit(string $voucherTypeHandle, int $voucherId = null, str return $this->renderTemplate('gift-voucher/vouchers/_edit', $variables); } - public function actionDeleteVoucher() + public function actionDelete() { $this->requirePostRequest(); @@ -143,36 +145,97 @@ public function actionDeleteVoucher() return $this->redirectToPostedUrl($voucher); } - public function actionSave() + public function actionSave(bool $duplicate = false) { $this->requirePostRequest(); + // Get the requested voucher $request = Craft::$app->getRequest(); + $oldVoucher = VoucherHelper::voucherFromPost($request); + $this->enforceVoucherPermissions($oldVoucher); + $elementsService = Craft::$app->getElements(); + + $transaction = Craft::$app->getDb()->beginTransaction(); + try { + // If we're duplicating the voucher, swap $voucher with the duplicate + if ($duplicate) { + try { + $voucher = $elementsService->duplicateElement($oldVoucher); + } catch (InvalidElementException $e) { + $transaction->rollBack(); + + /** @var Voucher $clone */ + $clone = $e->element; + + if ($request->getAcceptsJson()) { + return $this->asJson([ + 'success' => false, + 'errors' => $clone->getErrors(), + ]); + } - $voucher = $this->_setVoucherFromPost(); + Craft::$app->getSession()->setError(Craft::t('gift-voucher', 'Couldn’t duplicate voucher.')); - $this->enforceVoucherPermissions($voucher); + // Send the original voucher back to the template, with any validation errors on the clone + $oldVoucher->addErrors($clone->getErrors()); - if ($voucher->enabled && $voucher->enabledForSite) { - $voucher->setScenario(Element::SCENARIO_LIVE); - } + Craft::$app->getUrlManager()->setRouteParams([ + 'voucher' => $oldVoucher + ]); - if (!Craft::$app->getElements()->saveElement($voucher)) { - if ($request->getAcceptsJson()) { - return $this->asJson([ - 'success' => false, - 'errors' => $voucher->getErrors(), - ]); + return null; + } catch (\Throwable $e) { + throw new ServerErrorHttpException(Craft::t('gift-voucher', 'An error occurred when duplicating the voucher.'), 0, $e); + } + } else { + $voucher = $oldVoucher; } - Craft::$app->getSession()->setError(Craft::t('gift-voucher', 'Couldn’t save voucher.')); + // Now populate the rest of it from the post data + VoucherHelper::populateVoucherFromPost($voucher, $request); - // Send the category back to the template - Craft::$app->getUrlManager()->setRouteParams([ - 'voucher' => $voucher - ]); + // Save the voucher (finally!) + if ($voucher->enabled && $voucher->enabledForSite) { + $voucher->setScenario(Element::SCENARIO_LIVE); + } - return null; + $success = $elementsService->saveElement($voucher); + + if (!$success && $duplicate && $voucher->getScenario() === Element::SCENARIO_LIVE) { + // Try again with the voucher disabled + $voucher->enabled = false; + $voucher->setScenario(Model::SCENARIO_DEFAULT); + $success = $elementsService->saveElement($voucher); + } + + if (!$success) { + $transaction->rollBack(); + + if ($request->getAcceptsJson()) { + return $this->asJson([ + 'success' => false, + 'errors' => $voucher->getErrors(), + ]); + } + + Craft::$app->getSession()->setError(Craft::t('gift-voucher', 'Couldn’t save voucher.')); + + if ($duplicate) { + // Add validation errors on the original voucher + $oldVoucher->addErrors($voucher->getErrors()); + } + + Craft::$app->getUrlManager()->setRouteParams([ + 'voucher' => $oldVoucher + ]); + + return null; + } + + $transaction->commit(); + } catch (\Throwable $e) { + $transaction->rollBack(); + throw $e; } if ($request->getAcceptsJson()) { @@ -186,7 +249,7 @@ public function actionSave() ]); } - Craft::$app->getSession()->setNotice(Craft::t('app', 'Voucher saved.')); + Craft::$app->getSession()->setNotice(Craft::t('gift-voucher', 'Voucher saved.')); return $this->redirectToPostedUrl($voucher); } @@ -301,12 +364,6 @@ private function _prepEditVoucherVariables(array &$variables) $variables['voucher'] = new Voucher(); $variables['voucher']->typeId = $variables['voucherType']->id; - $taxCategories = $variables['voucherType']->getTaxCategories(); - $variables['voucher']->taxCategoryId = key($taxCategories); - - $shippingCategories = $variables['voucherType']->getShippingCategories(); - $variables['voucher']->shippingCategoryId = key($shippingCategories); - $variables['voucher']->typeId = $variables['voucherType']->id; $variables['voucher']->enabled = true; $variables['voucher']->siteId = $site->id;