Skip to content

feature/FOUR-20546 Create endpoint to add settings to a bundle #7906

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 23, 2025
22 changes: 21 additions & 1 deletion ProcessMaker/Http/Controllers/Api/DevLinkController.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ public function exportLocalBundleSettings(Bundle $bundle)
return ['settings' => $bundle->exportSettings()];
}

public function exportLocalBundleSettingPayloads(Bundle $bundle)
{
if ($bundle->settings->isEmpty()) {
return ['payloads' => [0 => []]];
}

return ['payloads' => $bundle->exportSettingPayloads()];
}

public function exportLocalAsset(Request $request)
{
$asset = $request->input('class')::findOrFail($request->input('id'));
Expand All @@ -223,7 +232,7 @@ public function addAsset(Request $request, Bundle $bundle)

public function addSettings(Request $request, Bundle $bundle)
{
$bundle->addSettings($request->input('setting'), $request->input('config'));
$bundle->addSettings($request->input('setting'), $request->input('config'), $request->input('type'));
}

public function addAssetToBundles(Request $request)
Expand All @@ -238,6 +247,17 @@ public function addAssetToBundles(Request $request)
}
}

public function addSettingToBundles(Request $request)
{
$bundles = $request->input('bundles');
foreach ($bundles as $id) {
$bundle = Bundle::find($id);
if ($bundle) {
$bundle->addSettingToBundles($request->input('setting'), $request->input('config'), $request->input('type'));
}
}
}

public function sharedAssets(Request $request)
{
return Setting::Where('group', 'Devlink')->get();
Expand Down
2 changes: 1 addition & 1 deletion ProcessMaker/ImportExport/Dependent.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function __get($property)
'attributes' => $this->fallbackMatches,
];

list($_, $model) = Manifest::getModel($this->uuid, $assetInfo, 'discard', $this->exporterClass);
list($_, $model) = Manifest::getModel($this->uuid, $assetInfo, 'discard', $this->exporterClass, false);

// Only return the model if it is persisted in the database
if ($model && $model->exists) {
Expand Down
3 changes: 2 additions & 1 deletion ProcessMaker/ImportExport/Importer.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function previewImport()

public function loadManifest()
{
return Manifest::fromArray($this->payload['export'], $this->options, $this->logger);
return Manifest::fromArray($this->payload['export'], $this->options, $this->logger, $this->payload['root']);
}

public function doImport($existingAssetInDatabase = null, $importingFromTemplate = false)
Expand All @@ -50,6 +50,7 @@ public function doImport($existingAssetInDatabase = null, $importingFromTemplate
$this->logger->log("Importing {$count} assets");
foreach ($this->manifest->all() as $uuid => $exporter) {
$this->logger->setStatus('saving', $uuid);
\Log::info('Importing ' . get_class($exporter->model), ['mode' => $exporter->mode]);
if ($exporter->mode !== 'discard') {
$this->logger->log('Importing ' . get_class($exporter->model));
if ($exporter->disableEventsWhenImporting) {
Expand Down
9 changes: 5 additions & 4 deletions ProcessMaker/ImportExport/Manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function toArray($skipHidden = false)
return $manifest;
}

public static function fromArray(array $array, Options $options, $logger)
public static function fromArray(array $array, Options $options, $logger, $root)
{
self::$logger = $logger;

Expand All @@ -95,7 +95,8 @@ public static function fromArray(array $array, Options $options, $logger)
$exporterClass = $assetInfo['exporter'];
$modeOption = $options->get('mode', $uuid);
$saveAssetsModeOption = $options->get('saveAssetsMode', $uuid);
list($mode, $model, $matchedBy) = self::getModel($uuid, $assetInfo, $modeOption, $exporterClass);
$isRoot = $uuid === $root;
list($mode, $model, $matchedBy) = self::getModel($uuid, $assetInfo, $modeOption, $exporterClass, $isRoot);
$model = self::updateBPMNDefinitions($model, $saveAssetsModeOption);
$exporter = new $exporterClass($model, $manifest, $options, false);
$exporter->logger = $logger;
Expand Down Expand Up @@ -134,7 +135,7 @@ public function push(string $uuid, ExporterInterface $exporter)
$this->manifest[$uuid] = $exporter;
}

public static function getModel($uuid, $assetInfo, $mode, $exporterClass)
public static function getModel($uuid, $assetInfo, $mode, $exporterClass, $isRoot)
{
$model = null;
$class = $assetInfo['model'];
Expand All @@ -153,7 +154,7 @@ public static function getModel($uuid, $assetInfo, $mode, $exporterClass)
}
}

if ($exporterClass::doNotImport($uuid, $assetInfo)) {
if (!$isRoot && $exporterClass::doNotImport($uuid, $assetInfo)) {
$mode = 'discard';
}

Expand Down
149 changes: 143 additions & 6 deletions ProcessMaker/Models/Bundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use ProcessMaker\ImportExport\Logger;
use ProcessMaker\ImportExport\Options;
use ProcessMaker\Models\ProcessMakerModel;
use ProcessMaker\Models\Setting;
use ProcessMaker\Models\SettingsMenus;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

Expand Down Expand Up @@ -78,6 +80,17 @@ public function export()
}

public function exportSettings()
{
$exports = [];

foreach ($this->settings as $setting) {
$exports[] = $setting;
}

return $exports;
}

public function exportSettingPayloads()
{
return $this->settings()->get()->map(function ($setting) {
return $setting->export();
Expand Down Expand Up @@ -138,18 +151,81 @@ public function addAsset(ProcessMakerModel $asset)
]);
}

public function addSettings($setting, $config)
public function addSettings($setting, $newId, $type = null)
{
$exists = $this->settings()->where('setting', $setting)->exists();
if ($exists) {
$this->settings()->where('setting', $setting)->update([
'config' => $config,
$existingSetting = $this->settings()->where('setting', $setting)->first();
//If $newId is null, set config to null
if (is_null($newId) && is_null($type)) {
if ($existingSetting) {
$existingSetting->update(['config' => null]);
} else {
BundleSetting::create([
'bundle_id' => $this->id,
'setting' => $setting,
'config' => null,
]);
}

return;
}
// verify if newId is a json with id key
$decodedNewId = json_decode($newId, true);
if (json_last_error() === JSON_ERROR_NONE) {
if (is_array($decodedNewId)) {
$newId = $decodedNewId;
} elseif (isset($decodedNewId['id'])) {
$newId = [$decodedNewId['id']];
} else {
$newId = ['id' => [$decodedNewId]];
}
} else {
$newId = ['id' => [$newId]];
}

if ($existingSetting) {
// Decode the existing JSON
$config = json_decode($existingSetting->config, true);
// Ensure 'id' is an array
if (!isset($config['id']) || !is_array($config['id'])) {
$config['id'] = [];
}
// Add the new ID
foreach ($newId['id'] as $id) {
$config['id'][] = $id;
}
// Remove duplicates
$config['id'] = array_unique($config['id']);
//reindex the array
$config['id'] = array_values($config['id']);
// Update the config
$existingSetting->update([
'config' => json_encode($config),
]);
} else {
// Create a new BundleSetting with the initial ID
$config = ['id' => []];
if ($newId && $type !== 'settings') {
foreach ($newId['id'] as $id) {
$config['id'][] = $id;
}
}

if ($type === 'settings') {
$settingsMenu = SettingsMenus::where('menu_group', $setting)->first();
$settingsKeys = Setting::where([
['group_id', '=', $settingsMenu->id],
['hidden', '=', false],
])->pluck('key')->toArray();
if ($settingsMenu) {
$config['id'] = $settingsKeys;
$config['type'] = $type;
}
}

BundleSetting::create([
'bundle_id' => $this->id,
'setting' => $setting,
'config' => $config,
'config' => json_encode($config),
]);
}
}
Expand All @@ -166,6 +242,18 @@ public function addAssetToBundles(ProcessMakerModel $asset)
return $message;
}

public function addSettingToBundles($setting, $newId, $type = null)
{
$message = null;
try {
$this->addSettings($setting, $newId, $type);
} catch (ValidationException $ve) {
$message = $ve->getMessage();
}

return $message;
}

public function validateEditable()
{
if (!$this->editable()) {
Expand Down Expand Up @@ -226,6 +314,55 @@ public function installSettings($settings)
}
}

public function installSettingsPayloads(array $payloads, $mode, $logger = null)
{
$options = new Options([
'mode' => $mode,
]);
$clientRepository = app('Laravel\Passport\ClientRepository');

$assets = [];
foreach ($payloads as $payload) {
if (isset($payload[0]['export'])) {
$logger->status('Installing bundle settings on the this instance');
$logger->setSteps($payloads[0]);
$assets[] = DevLink::import($payload[0], $options, $logger);
} else {
switch ($payload[0]['setting_type']) {
case 'auth_clients':
$clientRepository->create(
null,
$payload[0]['name'],
$payload[0]['redirect'],
$payload[0]['provider'],
$payload[0]['personal_access_client'],
$payload[0]['password_client']
);
break;
case 'User Settings':
case 'Email':
case 'Integrations':
case 'Log-In & Auth':
$settingsMenu = SettingsMenus::where('menu_group', $payload[0]['setting_type'])->first();
Setting::updateOrCreate([
'key' => $payload[0]['key'],
], [
'config' => $payload[0]['config'],
'name' => $payload[0]['name'],
'helper' => $payload[0]['helper'],
'format' => $payload[0]['format'],
'hidden' => $payload[0]['hidden'],
'readonly' => $payload[0]['readonly'],
'ui' => $payload[0]['ui'],
'group_id' => $settingsMenu->id,
'group' => $payload[0]['group'],
]);
break;
}
}
}
}

public function install(array $payloads, $mode, $logger = null)
{
if ($logger === null) {
Expand Down
Loading
Loading