Skip to content

Instantly share code, notes, and snippets.

@Megafry
Created March 6, 2024 11:48
Show Gist options
  • Save Megafry/d20b1d5cb2322ae058edf9e009217114 to your computer and use it in GitHub Desktop.
Save Megafry/d20b1d5cb2322ae058edf9e009217114 to your computer and use it in GitHub Desktop.
Formie import/export for console
<?php
namespace modules\ExtendFormie\console\controllers;
use Throwable;
use verbb\formie\helpers\ImportExportHelper;
use yii\console\Controller;
use yii\console\ExitCode;
use yii\helpers\Console;
use verbb\formie\Formie;
use verbb\formie\helpers\HandleHelper;
use craft\db\Query;
use craft\helpers\Json;
use craft\helpers\FileHelper;
class FormController extends Controller
{
// Properties
// =========================================================================
/**
* option for find files
*
* @var array
*/
private array $_findFilesOptions = ['only' => ['*.json']];
/**
* default folder
*
* @var string
*/
private string $_defaultExportFolder = 'exports/formie';
/**
* By default update, allow to force the creation of a new form
*
* @var bool
*/
public bool $create = false;
// Public Methods
// =========================================================================
/**
* @inheritdoc
*/
public function options($actionID)
{
$options = parent::options($actionID);
switch ($actionID) {
case 'import':
case 'import-all':
$options[] = 'create';
break;
}
return $options;
}
/**
* Export from handle
*
* @return int
* @throws Throwable
*/
public function actionExport($formHandle = null, $exportPath = null): int
{
if (is_null($formHandle)) {
$this->stderr("handle need to be provided" . PHP_EOL, Console::FG_RED);
return ExitCode::UNSPECIFIED_ERROR;
}
$formElement = Formie::$plugin->getForms()->getFormByHandle($formHandle);
if (!isset($formElement->handle)) {
$this->stderr("Form with handle $formHandle don't exist" . PHP_EOL, Console::FG_YELLOW);
return ExitCode::UNSPECIFIED_ERROR;
}
try {
$formExport = ImportExportHelper::generateFormExport($formElement);
$json = Json::encode($formExport, JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK);
$tempFileForm = $this->_getExportFolder($exportPath) . '/' . 'formie-' . $formElement->handle . '.json';
FileHelper::writeToFile($tempFileForm, $json);
} catch (Throwable $e) {
$this->stderr("Form with handle $formHandle could not be saved" . PHP_EOL);
return ExitCode::UNSPECIFIED_ERROR;
}
$this->stdout("Form #{$formHandle} has been exported" . PHP_EOL, Console::FG_GREEN);
return ExitCode::OK;
}
/**
* Import json from path
*
* @return int
* @throws Throwable
*/
public function actionImport($path = null): int
{
return $this->_importFormieFromPath($path);
}
/**
* Import all json from the export folder
*
* @return int
* @throws Throwable
*/
public function actionImportAll($exportPath = null): int
{
try {
$files = FileHelper::findFiles($this->_getExportFolder($exportPath), $this->_findFilesOptions);
} catch (\Throwable $th) {
$this->stderr("Export directory is empty or don't exist" . PHP_EOL, Console::FG_RED);
return ExitCode::UNSPECIFIED_ERROR;
}
if (empty($files)) {
$this->stderr("No json fund in folder $exportPath" . PHP_EOL, Console::FG_YELLOW);
return ExitCode::UNSPECIFIED_ERROR;
}
foreach ($files as $file) {
$this->_importFormieFromPath($file);
}
return ExitCode::OK;
}
/**
* list all form to export or import
*
* @return int
* @throws Throwable
*/
public function actionList($exportPath = null): int
{
$listEntries = [];
$files = $this->_getFileFromFolder($exportPath);
if (!empty($files)) {
$listEntries[] = [
'title' => 'Json to import:',
'entriesList' => array_map(function ($file) {
preg_match('/formie-(.*?).json/', $file, $matches);
return [
'handle' => $matches[1],
'title' => $file
];
}, $files)
];
}
$allForms = Formie::$plugin->getForms()->getAllForms();
if (!empty($allForms)) {
$listEntries[] = [
'title' => 'formie:',
'entriesList' => array_map(function ($form) {
return [
'handle' => $form->handle,
'title' => $form->title
];
}, $allForms)
];
}
foreach ($listEntries as $entries) {
$this->stderr($entries['title'] . PHP_EOL, Console::FG_YELLOW);
$handleMaxLen = max(array_map('strlen', array_column($entries['entriesList'], 'handle')));
foreach ($entries['entriesList'] as $entry) {
$this->stderr("- " . $entry['handle'], Console::FG_GREEN);
$this->stderr(Console::moveCursorTo($handleMaxLen + 5));
$this->stderr($entry['title'] . PHP_EOL);
}
}
return ExitCode::OK;
}
// Private Methods
// =========================================================================
/**
* get all Json from the export folder
*/
private function _getFileFromFolder($exportPath = null)
{
try {
$file = FileHelper::findFiles($this->_getExportFolder($exportPath), $this->_findFilesOptions);
} catch (\Throwable $th) {
return false;
}
return $file;
}
/**
* import form from path
*/
private function _importFormieFromPath($filePath): ?int
{
if (!is_file($filePath)) {
$this->stderr("Json file doesn't exist for: $filePath" . PHP_EOL);
return ExitCode::UNSPECIFIED_ERROR;
}
if (strtolower(pathinfo($filePath, PATHINFO_EXTENSION)) !== 'json') {
$this->stderr("file is not of type Json: $filePath" . PHP_EOL);
return ExitCode::UNSPECIFIED_ERROR;
}
try {
$json = Json::decode(file_get_contents($filePath));
} catch (\Throwable $th) {
$this->stderr("Json not valide for $filePath." . PHP_EOL, Console::FG_RED);
return ExitCode::SOFTWARE;
}
// Find an existing form with the same handle
$existingForm = null;
$formHandle = $json['handle'] ?? null;
if ($formHandle) {
$existingForm = Formie::$plugin->getForms()->getFormByHandle($formHandle);
}
// When creating a new form, change the handle
if ($this->create) {
$formHandles = (new Query())
->select(['handle'])
->from('{{%formie_forms}}')
->column();
//mnake it unique
$json['handle'] = HandleHelper::getUniqueHandle($formHandles, $json['handle']);
// Create the form element, ready to go
$form = ImportExportHelper::createFormFromImport($json);
} else {
// Update the form (force)
$form = ImportExportHelper::createFormFromImport($json, $existingForm);
}
if (!Formie::$plugin->getForms()->saveForm($form)) {
$this->stderr('Unable to import form.' . PHP_EOL, Console::FG_RED);
return null;
}
$this->stdout("Form #{$formHandle} has been imported" . PHP_EOL, Console::FG_GREEN);
return ExitCode::OK;
}
/**
* import form from path
*/
private function _getExportFolder($exportPath): string
{
return $exportPath ?? $this->_defaultExportFolder;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment