Created
March 6, 2024 11:48
-
-
Save Megafry/d20b1d5cb2322ae058edf9e009217114 to your computer and use it in GitHub Desktop.
Formie import/export for console
This file contains 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 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