Created
September 14, 2021 16:06
-
-
Save michaelhue/88ea58a18977e8be7e67d13a3b29b179 to your computer and use it in GitHub Desktop.
Formie "New submission" extension
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Implement our custom "New submission" button into the Formie submission index. | |
*/ | |
(function () { | |
const newSubmissionActionUrl = "/admin/actions/site/formie-draft/new"; | |
const newSubmissionLabel = Craft.t("formie", "New submission"); | |
Craft.Formie.SubmissionIndex.implement({ | |
forms: null, | |
$newEntryBtn: null, | |
init(...args) { | |
this.on("selectSource", this.updateButton.bind(this)); | |
this.on("selectSite", this.updateButton.bind(this)); // not needed yet | |
this.base(...args); | |
}, | |
/** | |
* Find form sources. | |
*/ | |
afterInit() { | |
this.forms = Array.from(this.$visibleSources) | |
.filter((el) => el.dataset.handle) | |
.map((el) => ({ | |
handle: el.dataset.handle, | |
label: el.innerText, | |
})); | |
this.base(); | |
}, | |
/** | |
* Update the "New submission" button. | |
*/ | |
updateButton() { | |
if (!this.$source) { | |
return; | |
} | |
if (this.$newEntryBtn) { | |
this.$newEntryBtn.remove(); | |
} | |
const handle = this.$source.data("handle"); | |
const selected = this.forms.find((form) => form.handle === handle); | |
if (selected) { | |
this.$newEntryBtn = $("<a>") | |
.attr({ | |
href: `${newSubmissionActionUrl}?handle=${selected.handle}`, | |
class: "btn submit add icon", | |
role: "button", | |
tabindex: 0, | |
}) | |
.text(newSubmissionLabel); | |
this.addButton(this.$newEntryBtn); | |
} | |
}, | |
}); | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace site\web\assets\formie; | |
use craft\web\AssetBundle; | |
use verbb\formie\web\assets\cp\CpAsset; | |
class FormieAsset extends AssetBundle | |
{ | |
public function init() | |
{ | |
parent::init(); | |
$this->sourcePath = __DIR__; | |
$this->depends = [CpAsset::class]; | |
$this->js = ['extension.js']; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace site\controllers; | |
use Craft; | |
use craft\web\Controller; | |
use DateTime; | |
use DateTimeZone; | |
use Exception; | |
use verbb\formie\elements\Form; | |
use verbb\formie\elements\Submission; | |
use verbb\formie\Formie; | |
use yii\web\BadRequestHttpException; | |
class FormieDraftController extends Controller | |
{ | |
protected $allowAnonymous = self::ALLOW_ANONYMOUS_NEVER; | |
/** | |
* Handle of the status to apply to new drafts. | |
*/ | |
protected $draftStatus = "draft"; | |
/** | |
* Creates a new submission draft. | |
*/ | |
public function actionNew() | |
{ | |
$this->requireCpRequest(); | |
$this->requirePermission('formie-editSubmissions'); | |
$request = Craft::$app->getRequest(); | |
$handle = $request->getQueryParam("handle"); | |
/** @var Form */ | |
$form = Form::find()->handle($handle)->one(); | |
if (!$form) { | |
throw new BadRequestHttpException("No form exists with the handle \"$handle\""); | |
} | |
$submission = new Submission(); | |
$submission->setForm($form); | |
$submission->siteId = Craft::$app->getSites()->getCurrentSite()->id; | |
// Apply a special "draft" status to distinguish from front-end submissions. | |
$submission->setStatus( | |
Formie::$plugin->getStatuses()->getStatusByHandle($this->draftStatus) | |
?? $form->getDefaultStatus() | |
); | |
// Save IP and user if needed, same as original submit action. | |
if ($form->settings->collectIp) { | |
$submission->ipAddress = Craft::$app->getRequest()->userIP; | |
} | |
if ($form->settings->collectUser) { | |
if ($user = Craft::$app->getUser()->getIdentity()) { | |
$submission->setUser($user); | |
} | |
} | |
// Our title will be the submission timestamp, since no fields have been | |
// filled out yet. We use the `afterSaveSubmission` event to update the | |
// title of every submission anyway, so this is fine for now. | |
if (!$submission->title) { | |
$now = new DateTime('now', new DateTimeZone(Craft::$app->getTimeZone())); | |
$submission->title = $now->format(DateTime::W3C); | |
} | |
$success = Craft::$app->getElements()->saveElement($submission, false); | |
if (!$success) { | |
throw new Exception(Craft::t("formie", "Couldn’t save submission.")); | |
} | |
// We skip triggering events and integrations at this point, since they | |
// are not needed for our use case. | |
// Redirect to our fresh submission. | |
return $this->redirect($submission->getCpEditUrl()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace site; | |
use Craft; | |
use craft\events\TemplateEvent; | |
use craft\web\View; | |
use site\web\assets\formie\FormieAsset; | |
use verbb\formie\elements\Submission; | |
use yii\base\Event; | |
class Module extends \yii\base\Module | |
{ | |
/** | |
* Initializes the module. | |
*/ | |
public function init(): void | |
{ | |
// Set a @modules alias pointed to the modules/ directory | |
Craft::setAlias('@site', __DIR__); | |
// Set the controllerNamespace based on whether this is a console or web request | |
if (Craft::$app->getRequest()->getIsConsoleRequest()) { | |
$this->controllerNamespace = 'site\\console\\controllers'; | |
} else { | |
$this->controllerNamespace = 'site\\controllers'; | |
} | |
parent::init(); | |
$this->registerFormieExtensions(); | |
} | |
/** | |
* Registers event listeners for the Formie plugin. | |
*/ | |
protected function registerFormieExtensions(): void | |
{ | |
// Update the title according to format whenever a submission was saved. | |
// We could add some checks here to only apply to drafts, but I want to | |
// keep the submission title in sync with data always. | |
Event::on(Submission::class, Submission::EVENT_AFTER_SAVE, function (Event $event) { | |
/** @var Submission */ | |
$submission = $event->sender; | |
if (!$event->isNew) { | |
$form = $submission->getForm(); | |
$submission->updateTitle($form); | |
} | |
}); | |
// Attach our asset bundle if the Formie's control panel bundle is loaded. | |
// The bundle will extend Formie's element index script in order to add | |
// the "New submission" button. | |
Event::on(View::class, View::EVENT_BEFORE_RENDER_TEMPLATE, function (TemplateEvent $event) { | |
$formieCpBundle = "verbb\\formie\\web\\assets\\cp\\CpAsset"; | |
$loadedBundles = array_keys($event->sender->assetBundles ?? []); | |
if (!in_array($formieCpBundle, $loadedBundles)) { | |
return; | |
} | |
$event->sender->registerAssetBundle(FormieAsset::class); | |
$event->sender->registerTranslations('formie', [ | |
'New submission', | |
]); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment