<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_formea
 *
 * @copyright   Copyright (C) 2010-2025 Feseur Sdn Bhd. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 * @version     1.3.0
 */

namespace Joomla\Component\Formea\Administrator\Model;

defined('_JEXEC') or die;

use Exception;
use Feseur\Library\FsrDate;
use Feseur\Library\FsrHelper;
use Feseur\Library\FsrResponse;
use Joomla\Archive\Archive;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Formea\Site\Helper\FormeaGeneralHelper;
use Joomla\Database\DatabaseDriver;
use Joomla\Database\DatabaseQuery;
use Joomla\CMS\Application\CMSApplicationInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\Filesystem\File;
use Joomla\Filesystem\Folder;
use Joomla\Filesystem\Path;
use Joomla\Filter\OutputFilter;
use RuntimeException;
use stdClass;

/**
 * Methods supporting a list of formea records.
 *
 * @since  1.0
 */
class FormeasModel extends ListModel
{
  /**
   * @var CMSApplicationInterface|null
   * @since 1.0.0
   */
  protected $app;


  /**
   * @var string[]
   * @since 1.2.2
   */
  protected $allowedFormFiles = ['elements', 'form', 'groupedElements', 'layouts', 'submissions', 'grouped_map'];

  /**
   * @var string[]
   * @since 1.2.2
   */
  protected $allowedFormFolders = ['attachments', 'submissions'];

  /**
   * Constructor.
   *
   * @param   array  $config  An optional associative array of configuration settings.
   *
   * @see     \JControllerLegacy
   * @since   1.0
   */
  public function __construct($config = [])
  {

    if (empty($config['filter_fields'])) {
      $config['filter_fields'] = [
        'id',
        'a.id',
        'state',
        'a.state',
        'access_level',
        'a.access_level',
        'checked_out',
        'a.checked_out',
        'checked_out_time',
        'a.checked_out_time',
        'publish_up',
        'a.publish_up',
        'publish_down',
        'a.publish_down',
        'created_date',
        'a.created_date',
        'created_by',
        'a.created_by',
        'modified_date',
        'a.modified_date',
        'modified_by',
        'a.modified_by',
        'title',
        'a.title',
        'alia',
        'a.alias',
      ];
    }

    parent::__construct($config);
    $this->app = Factory::getApplication();
  }

  /**
   * Method to get a DatabaseQuery object for retrieving the data set from a database.
   *
   * @return  DatabaseQuery|string  A DatabaseQuery object to retrieve the data set.
   *
   * @since   1.6
   */
  protected function getListQuery()
  {
    $columns = [
      'a.id',
      'a.state',
      'a.access_level',
      'a.checked_out',
      'a.checked_out_time',
      'a.publish_up',
      'a.publish_down',
      'a.created_date',
      'a.created_by',
      'a.modified_date',
      'a.modified_by',
      'a.title',
      'a.alias',
      'a.allow_submission',
    ];
    // Create a new query object.
    $db    = $this->getDatabase();
    $query = $db->getQuery(true);

    // Select the required fields from the table.
    $query->select(
      $db->quoteName(
        explode(
          ', ',
          $this->getState(
            'list.select',
            implode(', ', $columns)
          )
        )
      )
    );

    $query->from($db->quoteName('#__formea_forms', 'a'));
    $query->select($db->quoteName('b.title', 'access_level_title'))->innerJoin(
      $db->quoteName('#__viewlevels', 'b') . ' ON ' . $db->quoteName('a.access_level') . ' = ' .
        $db->quoteName('b.id')
    );


    // Join over the users for the checked out user.
    $query->select($db->quoteName('uc.name', 'editor'))
      ->join(
        'LEFT',
        $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')
      );


    // Filter by access level.
    if ($access = $this->getState('filter.access')) {
      $query->where($db->quoteName('a.access_level') . ' = ' . (int) $access);
    }

    // Filter by published state
    $published = (string) $this->getState('filter.published');

    if (is_numeric($published)) {
      $query->where($db->quoteName('a.state') . ' = ' . (int) $published);
    } elseif ($published === '') {
      $query->where($db->quoteName('a.state') . ' = 0');
      $query->extendWhere('OR', $db->quoteName('a.state') . ' = 1');
    }
    $subQuery = $db->getQuery(true);
    $subQuery->select('COUNT(*)')
      ->from($db->quoteName('#__formea_submissions', 'sb'))
      ->where($db->quoteName('a.id') . ' = ' . $db->quoteName('sb.form_id'));
    $query->select('(' . $subQuery . ') AS submissions');

    // Filter by search in name.
    $search = $this->getState('filter.search');

    if (!empty($search)) {
      if (stripos($search, 'id:') === 0) {
        $query->where('a.id = ' . (int) substr($search, 3));
      } else {
        $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%'));
        $query->where(
          '(' . $db->quoteName('a.name') . ' LIKE ' . $search . ')'
        );
      }
    }

    // Filter on the language.
    if ($language = $this->getState('filter.language')) {
      $query->where($db->quoteName('a.language') . ' = ' . $db->quote($language));
    }

    // Add the list ordering clause.
    $orderCol  = $this->state->get('list.ordering', 'a.name');
    $orderDirn = $this->state->get('list.direction', 'asc');

    if ($orderCol == 'a.ordering' || $orderCol == 'category_title') {
      $orderCol = $db->quoteName('c.title') . ' ' . $orderDirn . ', ' . $db->quoteName('a.ordering');
    }

    $query->order($db->escape($orderCol . ' ' . $orderDirn));

    return $query;
  }

  /**
   * Method to auto-populate the model state.
   *
   * Note. Calling getState in this method will result in recursion.
   *
   * @param   string  $ordering   An optional ordering field.
   * @param   string  $direction  An optional direction (asc|desc).
   *
   * @return  void
   *
   * @since   1.0
   */
  protected function populateState($ordering = 'a.id', $direction = 'desc')
  {
    $app = Factory::getApplication();

    // Adjust the context to support modal layouts.
    if ($layout = $app->input->get('layout')) {
      $this->context .= '.' . $layout;
    }

    // List state information.
    parent::populateState($ordering, $direction);
  }

  public function getItems()
  {
    // Get a storage key.
    $store = $this->getStoreId();

    // Try to load the data from internal storage.
    if (isset($this->cache[$store])) {
      return $this->cache[$store];
    }

    try {
      // Load the list items and add the items to the internal cache.
      $this->cache[$store] = $this->_getList($this->_getListQuery(), $this->getStart(), $this->getState('list.limit'));
    } catch (RuntimeException $e) {
      $this->app->enqueueMessage($e->getMessage(), 'error');

      return false;
    }

    return $this->cache[$store];
  }

  /**
   * Upload and process a Formea form backup.
   *
   * @param   array  $file       The uploaded file data.
   * @param   array  $formLists  Optional list of forms.
   *
   * @return FsrResponse
   * @since 1.2.2
   */
  public function uploadFormeaForm($file, $formLists = [])
  {
    $retObject = new FsrResponse();

    try {
      $this->validateUploadedFile($file);

      $tmpPath        = Path::clean($this->app->getConfig()->get('tmp_path', JPATH_ROOT . '/tmp'));
      $destinationDir = $tmpPath . '/' . $file['name'];

      if (!File::upload($file['tmp_name'], $destinationDir, false, true)) {
        throw new Exception(Text::_('COM_FORMEA_UPLOAD_FORM_FAILED'));
      }


      $extractDir = $this->extractArchive($destinationDir, $tmpPath);
      $backupType = $this->processExtractedFiles($extractDir, $file['name'], $formLists);

      if ($backupType['invalid']) {
        $this->cleanup($extractDir, $destinationDir);
        throw new Exception(Text::_('COM_FORMEA_INVALID_BACKUP_FILE'));
      }

      $retObject->setSuccess(true);
      $retObject->setResult($backupType);
    } catch (\Exception $e) {
      $retObject->setMsg($e->getMessage());
    }

    return $retObject;
  }

  /**
   * Validate the uploaded file.
   *
   * @param   array  $file  The file to validate.
   *
   * @throws Exception If validation fails.
   * @since 1.2.2
   */
  private function validateUploadedFile($file)
  {
    $commonZipType = FsrHelper::commonZipMimeType();

    if (!isset($file['name'])) {
      throw new Exception(Text::_('COM_FORMEA_FILE_NOT_FOUND'));
    }

    if (!isset($file['type']) || !in_array($file['type'], $commonZipType)) {
      throw new Exception(Text::_('COM_FORMEA_INVALID_FILE_TYPE'));
    }

    if ($file['error'] || $file['size'] < 1) {
      throw new Exception(Text::_('COM_FORMEA_UPLOAD_FORM_ERROR'));
    }
  }

  /**
   * Extract the uploaded archive.
   *
   * @param   string  $destinationDir  The directory where the file is stored.
   * @param   string  $tmpPath         The temporary path.
   *
   * @return string The directory where files are extracted.
   * @throws Exception If extraction fails.
   * @since 1.2.2
   */
  private function extractArchive($destinationDir, $tmpPath)
  {
    $tmpDir     = uniqid('formeaForm_');
    $extractDir = Path::clean(dirname($destinationDir) . '/' . $tmpDir);
    $archive    = new Archive(['tmp_path' => $tmpPath]);
    if (!$archive->extract($destinationDir, $extractDir)) {
      throw new Exception(Text::_('COM_FORMEA_EXTRACT_FORM_ERROR'));
    }


    // Check if the extracted folder contains a single folder
    $dirList = array_merge(Folder::files($extractDir, ''), Folder::folders($extractDir, ''));
    if (count($dirList) === 1 && is_dir($extractDir . '/' . $dirList[0])) {
      $extractDir = Path::clean($extractDir . '/' . $dirList[0]);
    }

    return $extractDir;
  }

  /**
   * Process extracted files and validate forms.
   *
   * @param   string  $extractDir  The directory where files were extracted.
   * @param   string  $filename    The file name.
   * @param   array   $formLists   List of forms.
   *
   * @return array The backup type data.
   * @since 1.2.2
   */
  private function processExtractedFiles($extractDir, $filename, $formLists)
  {
    $jsonFiles        = Folder::files($extractDir, '.json$', 1, false);
    $backupType       = [
      'backupType'  => 'form',
      'invalid'     => true,
      'packageInfo' => null,
      'tmp_dir'     => $extractDir,
      'filename'    => $filename,
      'forms'       => [],
    ];
    $formeaExtensions = FormeaGeneralHelper::getGroupedFormeaExtensions(-1, true);
    if (in_array('formea_backup_package.json', $jsonFiles)) {
      $backupType = $this->processPackageBackup($extractDir, $formLists, $backupType, $formeaExtensions);
    } elseif (in_array('formea_backup.json', $jsonFiles)) {
      $processedForm = $this->processFormBackup($extractDir, $formLists, $formeaExtensions);
      if ($processedForm) {
        $backupType['invalid'] = false;
        $backupType['forms'][] = $processedForm;
      }
    }

    return $backupType;
  }

  /**
   * Process form backup files.
   *
   * @param   string    $extractDir        The directory where files were extracted.
   * @param   array     $formLists         Available forms.
   * @param   stdClass  $formeaExtensions  Grouped of installable formea extension.
   *
   * @return array The backup type data.
   * @since 1.2.2
   */
  private function processFormBackup($formFolder, $formLists, $formeaExtensions)
  {
    $formInfo = [
      'info'               => null,
      'elements'           => false,
      'form'               => false,
      'groupedElements'    => false,
      'layouts'            => false,
      'submissions'        => false,
      'submissionsFolder'  => false,
      'attachmentsFolder'  => false,
      'logs'               => [],
      'logError'           => 0,
      'logWarning'         => 0,
      'includeSubmissions' => 0,
      'overwrite'          => 0,
      'overwrite_id'       => $formLists[0]->id ?? 0,
    ];

    if (is_file($formFolder . '/formea_backup.json')) {
      $formInfoString              = file_get_contents($formFolder . '/formea_backup.json');
      $formInfo['info']            = json_decode($formInfoString, true);
      $formInfo['info']['tmp_dir'] = $formFolder;
      $this->validateFormFiles($formFolder, $formeaExtensions, $formInfo);
    }

    return $formInfo;
  }


  /**
   * Process package backup files.
   *
   * @param   string    $extractDir        The directory where files were extracted.
   * @param   array     $formLists         List of forms.
   * @param   array     $backupType        Standard Backup type information.
   * @param   stdClass  $formeaExtensions  Grouped of installable formea extension.
   *
   * @return array The backup type data.
   * @since 1.2.2
   */
  private function processPackageBackup($extractDir, $formLists, $backupType, $formeaExtensions)
  {
    //$backupType                = ['backupType' => 'package', 'invalid' => false, 'forms' => []];
    $backupType['backupType'] = 'package';

    $pkgJson                   = file_get_contents($extractDir . '/formea_backup_package.json');
    $backupType['packageInfo'] = json_decode($pkgJson, true);

    $totalForms = $backupType['packageInfo']['total_forms'] ?? 0;
    $zipFiles   = Folder::files($extractDir, '.zip$', 1, true);

    for ($i = 0; $i < $totalForms; $i++) {
      if (isset($zipFiles[$i])) {
        $formInfo = $this->processFormZip($zipFiles[$i], $formLists, $formeaExtensions);
        if ($formInfo) {
          $backupType['invalid'] = false;
          $backupType['forms'][] = $formInfo;
        }
      }
    }

    return $backupType;
  }

  /**
   * Process an individual form backup ZIP file.
   *
   * @param   string    $zipFile           The path to the form ZIP file.
   * @param   array     $formLists         List of forms.
   * @param   stdClass  $formeaExtensions  Grouped of installable formea extension.
   *
   * @return array|null The processed form data or null if failed.
   * @since 1.2.2
   */
  private function processFormZip($zipFile, $formLists, $formeaExtensions)
  {
    $pathinfo   = pathinfo($zipFile);
    $formFolder = $pathinfo['dirname'] . '/' . $pathinfo['filename'];

    $archive = new Archive(['tmp_path' => $pathinfo['dirname']]);
    if (!$archive->extract($zipFile, $formFolder)) {
      return null;
    }

    return $this->processFormBackup($formFolder, $formLists, $formeaExtensions);
  }

  /**
   * Validate form files and update the form information.
   *
   * @param   string    $formFolder        The folder containing the form files.
   * @param   stdClass  $formeaExtensions  Grouped of installable formea extension.
   * @param   array     $formInfo          The form information array to update.
   *
   * @since 1.2.2
   */
  private function validateFormFiles($formFolder, $formeaExtensions, &$formInfo)
  {
    $elementTypeString     = Text::_('COM_FORMEA_ELEMENT_TYPE');
    $validationTypeString  = Text::_('COM_FORMEA_VALIDATION_TYPE');
    $coreTypeString        = Text::_('COM_FORMEA_CORE_EXTENSION_TYPE');
    $checkedValidationType = [];
    $checkedElementType    = [];
    $checkedTheme          = [];
    $checkedCores          = [];
    foreach ($this->allowedFormFiles as $file) {
      $formInfo[$file] = is_file($formFolder . '/' . $file . '.json');
    }

    foreach ($this->allowedFormFolders as $folder) {
      $formInfo[$folder . 'Folder'] = is_dir($formFolder . '/' . $folder);
    }

    if ($formInfo['elements']) {
      $jsonElementsString = file_get_contents(Path::clean($formFolder . DIRECTORY_SEPARATOR . 'elements.json'));
      $jsonElements       = json_decode($jsonElementsString, true);
      $elements           = $jsonElements['lists'];
      $totalElements      = count($elements);
      for ($j = 0; $j < $totalElements; $j++) {
        if (!in_array($elements[$j]['type'], $checkedElementType)) {
          $checkedElementType[] = $elements[$j]['type'];
          if (isset($formeaExtensions->eltypes[$elements[$j]['type']])) {
            // TODO: check version
            //$typeVersion = $formeaExtensions->eltypes[$jsonElements[$j]['type']]->version;
          } else {
            $msg                = Text::sprintf('COM_FORMEA_UPLOAD_FORM_NOT_FOUND_ERROR_S', $elementTypeString, $elements[$j]['type']);
            $formInfo['logs'][] = ['level' => -1, 'msg' => $msg];
            $formInfo['logError']++;
          }
        }

        $totalValidations = count($elements[$j]['validations']);
        for ($k = 0; $k < $totalValidations; $k++) {
          if (!in_array($elements[$j]['validations'][$k]['validation_type'], $checkedValidationType)) {
            $checkedValidationType[] = $elements[$j]['validations'][$k]['validation_type'];
            if (isset($formeaExtensions->validations[$elements[$j]['validations'][$k]['validation_type']])) {
              // TODO: check version
            } else {
              $msg                = Text::sprintf('COM_FORMEA_UPLOAD_FORM_NOT_FOUND_ERROR_S', $validationTypeString, $elements[$j]['validations'][$k]['validation_type']);
              $formInfo['logs'][] = ['level' => -1, 'msg' => $msg];
              $formInfo['logError']++;
            }
          }
        }
      }
    }

    if ($formInfo['form']) {
      $jsonFormString = file_get_contents(Path::clean($formFolder . DIRECTORY_SEPARATOR . 'form.json'));
      $formData       = json_decode($jsonFormString, true);

      //TODO:Check Theme
      /*$theme = $formData['theme'];
        if(!isset($checkedTheme[$theme])){}*/

      $cores      = $formData['cores'];
      $totalCores = count($cores);
      for ($l = 0; $l < $totalCores; $l++) {
        $params = json_decode($cores[$l]['params'], true);
        if ((int) $params['enabled'] > 0) {
          if (!in_array($cores[$l]['corename'], $checkedCores)) {
            $checkedCores[] = $cores[$l]['corename'];
            if (isset($formeaExtensions->cores[$cores[$l]['corename']])) {
              // TODO: check version
            } else {
              $msg                = Text::sprintf('COM_FORMEA_UPLOAD_FORM_NOT_FOUND_ERROR_S', $coreTypeString, $cores[$l]['corename']);
              $formInfo['logs'][] = ['level' => -1, 'msg' => $msg];
              $formInfo['logError']++;
            }
          }
        }
      }
    }
    if ($formInfo['layouts']) {
      $jsonLayoutString = file_get_contents(Path::clean($formFolder . DIRECTORY_SEPARATOR . 'layouts.json'));
      $layoutData       = json_decode($jsonLayoutString, true);

      $totalLayouts = count($layoutData);
      if ($totalLayouts > 1) {
        //check renderer
        $rendererExtensions = FormeaGeneralHelper::getCoreExtensions(1, [1]);
        if (empty($rendererExtensions)) {
          $msg                = Text::sprintf('COM_FORMEA_UPLOAD_FORM_NOT_FOUND_ERROR_S', $coreTypeString, 'MultiPage');
          $formInfo['logs'][] = ['level' => -1, 'msg' => $msg];
          $formInfo['logError']++;
        }
      }
    }
  }

  /**
   * Cleanup extracted directories and files.
   *
   * @param   string  $extractDir      The directory where files were extracted.
   * @param   string  $destinationDir  The original uploaded file destination.
   *
   * @since 1.2.2
   */
  private function cleanup($extractDir, $destinationDir)
  {
    if (is_dir($extractDir)) {
      Folder::delete($extractDir);
    }
    if (is_file($destinationDir)) {
      File::delete($destinationDir);
    }
  }

  /**
   * @param   string  $tmpDir  The directory where files were extracted.
   *
   * @return bool
   *
   * @since 1.2.2
   */
  public function removeUploadedFormPkg($tmpDir, $filename)
  {
    $tmpPath = Path::clean($this->app->getConfig()->get('tmp_path', JPATH_ROOT . '/tmp'));
    $file    = $tmpPath . '/' . $filename;
    $this->cleanup($tmpDir, $file);
    if (is_dir(Path::clean($tmpDir))) {
      Folder::delete(Path::clean($tmpDir));

      return true;
    }

    return false;
  }

  /**
   * @param   string  $tmpDir
   * @param   string  $filename
   * @param   array   $form_detail  - int includeSubmissions | int overwrite | int overwrite_id | string tmp_dir
   *
   * @return FsrResponse
   * @since 1.2.2
   */
  public function formUploadInstall($tmpDir, $filename, $form_detail)
  {
    $retObject = new FsrResponse();
    try {
      $tmpPath = Path::clean($this->app->getConfig()->get('tmp_path', JPATH_ROOT . '/tmp'));
      if (!is_dir(Path::clean($tmpDir))) {
        throw new Exception(Text::_('COM_FORMEA_UPLOAD_FORM_NOT_FOUND'));
      }
      if (!is_file(Path::clean($tmpPath . '/' . $filename))) {
        throw new Exception(Text::_('COM_FORMEA_UPLOAD_FORM_FILE_NOT_FOUND'));
      }
      if (empty($form_detail)) {
        throw new Exception(Text::_('COM_FORMEA_UPLOAD_FORM_NOT_FOUND'));
      }

      $formeaExtensions = FormeaGeneralHelper::getGroupedFormeaExtensions(-1, true);

      $defaultTheme = null;
      if (isset($formeaExtensions->themes)) {
        $_themes = array_values($formeaExtensions->themes);
        if (isset($_themes[0])) {
          $defaultTheme = $_themes[0];
        }
      }

      if (empty($defaultTheme)) {
        throw new Exception(Text::_('COM_FORMEA_NO_THEME_INSTALLED'));
      }


      $lang           = $this->app->getLanguage();
      $langTag        = $lang->getTag();
      $langTitle      = $lang->getName();
      $defaultLangTag = 'en-GB';
      $user           = $this->app->getIdentity();

      $totalFormDetail         = count($form_detail);
      $totalAllowedFormFiles   = count($this->allowedFormFiles);
      $totalAllowedFormFolders = count($this->allowedFormFolders);

      $completedForm = [];
      for ($i = 0; $i < $totalFormDetail; $i++) {
        $formInfo        = [];
        $processElements = [
          'form_note'          => '',
          'form_title'         => '',
          'form_id'            => 0,
          'form_url'           => '',
          'elementCode'        => [],
          'groupedElementCode' => [],
          'skippedElements'    => [],
          'skippedCores'       => [],
          'skippedValidations' => [],
          'logs'               => [],
        ];

        for ($j = 0; $j < $totalAllowedFormFiles; $j++) {
          if (is_file(Path::clean($form_detail[$i]['tmp_dir'] . '/' . $this->allowedFormFiles[$j] . '.json'))) {
            $formInfo[$this->allowedFormFiles[$j]] = json_decode(file_get_contents($form_detail[$i]['tmp_dir'] . '/' . $this->allowedFormFiles[$j] . '.json'), true);
          } else {
            $formInfo[$this->allowedFormFiles[$j]] = null;
          }
        }

        for ($k = 0; $k < $totalAllowedFormFolders; $k++) {
          if (is_dir(Path::clean($form_detail[$i]['tmp_dir'] . '/' . $this->allowedFormFolders[$k]))) {
            $folderFiles                                        = Folder::files($form_detail[$i]['tmp_dir'] . '/' . $this->allowedFormFolders[$k]);
            $formInfo[$this->allowedFormFolders[$k] . 'Folder'] = $folderFiles;
          } else {
            $formInfo[$this->allowedFormFolders[$k] . 'Folder'] = null;
          }
        }

        $processElements['form_note'] = $form_detail[$i]['note'];


        $processElements = $this->installFormElements($processElements, $formInfo, $form_detail[$i], $formeaExtensions, $user, $langTag, $defaultLangTag);


        $processElements = $this->installGroupedElements($processElements, $formInfo, $form_detail[$i], $formeaExtensions, $user, $langTag, $defaultLangTag);

        $processElements = $this->installLayout($defaultTheme, $processElements, $formInfo, $form_detail[$i], $formeaExtensions, $user, $langTag, $defaultLangTag);

        //Todo:  attachments and files

        if ((int) $form_detail[$i]['includeSubmissions'] > 0 && (isset($formInfo['submissions']) && !empty($formInfo['submissions']))) {
          $processElements = $this->installSubmissionData($processElements, $formInfo, $form_detail[$i]);
        }

        $completedForm[] = $processElements;
      }

      $this->removeUploadedFormPkg($tmpDir, $filename);

      $retObject->setSuccess(true);
      $retObject->setResult($completedForm);
    } catch (Exception $e) {
      $retObject->setMsg($e->getMessage());
    }

    return $retObject;
  }

  private function installFormElements($processElements, $formStructure, $formDetail, $formeaExtensions, $user, $langTag = 'en-GB', $defaultLangTag = 'en-GB')
  {
    $elementCode    = [];
    $sampleElements = [];
    if (isset($formStructure['elements']['map'])) {
      $elementCode = array_flip($formStructure['elements']['map']);
    }
    if (isset($formStructure['elements']['lists'])) {
      $sampleElements = $formStructure['elements']['lists'];
    }

    $totalSampleElements = count($sampleElements);
    $date                = new FsrDate();
    $container           = Factory::getContainer();
    /** @var DatabaseDriver $db */
    $db                   = $container->get('DatabaseDriver');
    $logs                 = [];
    $elementTypeString    = Text::_('COM_FORMEA_ELEMENT_TYPE');
    $validationTypeString = Text::_('COM_FORMEA_VALIDATION_TYPE');
    $skippedElements      = [];

    for ($j = 0; $j < $totalSampleElements; $j++) {
      if (!in_array($sampleElements[$j]['type'], $skippedElements)) {
        if (isset($formeaExtensions->eltypes[$sampleElements[$j]['type']])) {
          $totalElementValues = count($sampleElements[$j]['values']);
          $totalValidations   = count($sampleElements[$j]['validations']);
          $totalDetails       = count($sampleElements[$j]['details']);

          if ($langTag !== $defaultLangTag) {
            //add user lang tag
            if ($totalElementValues > 0) {
              $_value                         = clone $sampleElements[$j]['values'][0];
              $_value->language               = $langTag;
              $sampleElements[$j]['values'][] = $_value;
              $totalElementValues             = count($sampleElements[$j]['values']);
            }
            if ($totalDetails > 0) {
              $_detail                         = clone $sampleElements[$j]['details'][0];
              $_detail->language               = $langTag;
              $sampleElements[$j]['details'][] = $_detail;
              $totalDetails                    = count($sampleElements[$j]['details']);
            }
          }

          $alias            = FsrHelper::createAlias($sampleElements[$j]['alias'], 'formea_elements');
          $idPlaceholderKey = $sampleElements[$j]['id']; //[SP_YOUR_NAME]
          $element          = [
            'title'        => $sampleElements[$j]['title'],
            'alias'        => $alias,
            'type'         => $sampleElements[$j]['type'],
            'state'        => $sampleElements[$j]['state'],
            'params'       => $sampleElements[$j]['params'],
            'created_date' => $date->toSql(),
            'created_by'   => (!is_null($user->id)) ? $user->id : 0,
            'access_level' => $sampleElements[$j]['access_level'],
          ];
          $element          = (object) $element;
          $db->insertObject('#__formea_elements', $element);
          $element->id                    = $db->insertid();
          $elementCode[$idPlaceholderKey] = $element->id;

          //values
          for ($i = 0; $i < $totalElementValues; $i++) {
            $elementValues = [
              'element_id'   => $element->id,
              'defval'       => $sampleElements[$j]['values'][$i]['defval'],
              'option_lists' => $sampleElements[$j]['values'][$i]['option_lists'],
              'language'     => $sampleElements[$j]['values'][$i]['language'],
            ];
            $elementValues = (object) $elementValues;
            $db->insertObject('#__formea_element_values', $elementValues);
            $elementValues->id = $db->insertid();

            if (!empty($formStructure['attachmentsFolder']) && !empty($sampleElements[$j]['values'][$i]['defval'])) {
              $imgArray = [];
              if (!empty($sampleElements[$j]['values'][$i]['defval'])) {
                $imgArray = array_merge($imgArray, FsrHelper::getAllImageSrc($sampleElements[$j]['values'][$i]['defval']));
              }

              if (!empty($imgArray)) {
                $sourceDir = $formDetail['tmp_dir'] . '/attachments/';
                $copyFiles = FsrHelper::copyFilesFromBackup($sourceDir, $formStructure['attachmentsFolder'], $imgArray);
              }
            }
          }

          //validations
          for ($k = 0; $k < $totalValidations; $k++) {
            if (!in_array($sampleElements[$j]['validations'][$k]['validation_type'], $processElements['skippedValidations'])) {
              if (isset($formeaExtensions->validations[$sampleElements[$j]['validations'][$k]['validation_type']])) {
                $invalidMessages = $sampleElements[$j]['validations'][$k]['invalid_messages'];
                if ($langTag !== $defaultLangTag) {
                  $_validation               = $sampleElements[$j]['validations'][$k];
                  $_invalidMessage           = json_decode($_validation->invalid_messages, true);
                  $_invalidMessage[$langTag] = $_invalidMessage[$defaultLangTag];
                  $_validation               = json_encode($_invalidMessage);
                  $invalidMessages           = $_validation;
                }
                $elementValidation = [
                  'element_id'       => $element->id,
                  'validation_type'  => $sampleElements[$j]['validations'][$k]['validation_type'],
                  'params'           => $sampleElements[$j]['validations'][$k]['params'],
                  'invalid_messages' => $invalidMessages,
                ];
                $elementValidation = (object) $elementValidation;
                $db->insertObject('#__formea_element_validations', $elementValidation);
                $elementValidation->id = $db->insertid();
              } else {
                $processElements['skippedValidations'][] = $sampleElements[$j]['validations'][$k]['validation_type'];
                $msg                                     = Text::sprintf('COM_FORMEA_UPLOAD_FORM_NOT_FOUND_ERROR_S', $validationTypeString, $sampleElements[$j]['validations'][$k]['validation_type']);
                $logs[]                                  = ['level' => -1, 'msg' => $msg];
              }
            }
          }

          //details
          for ($k = 0; $k < $totalDetails; $k++) {
            $elementDetail = [
              'element_id'  => $element->id,
              'caption'     => $sampleElements[$j]['details'][$k]['caption'],
              'placeholder' => $sampleElements[$j]['details'][$k]['placeholder'],
              'description' => $sampleElements[$j]['details'][$k]['description'],
              'language'    => $sampleElements[$j]['details'][$k]['language'],
            ];
            $elementDetail = (object) $elementDetail;
            $db->insertObject('#__formea_element_details', $elementDetail);
            $elementDetail->id = $db->insertid();
          }

          //attribute
          if (!empty($sampleElements[$j]['attribute'])) {
            $elementAttribute = [
              'element_id'      => $element->id,
              'class'           => $sampleElements[$j]['attribute']['class'],
              'size'            => $sampleElements[$j]['attribute']['size'],
              'max_size'        => $sampleElements[$j]['attribute']['max_size'],
              'additional_attr' => $sampleElements[$j]['attribute']['additional_attr'],
            ];
            $elementAttribute = (object) $elementAttribute;
            $db->insertObject('#__formea_element_attributes', $elementAttribute);
            $elementAttribute->id = $db->insertid();
          }
        } else {
          $skippedElements[] = $sampleElements[$j]['type'];
          $msg               = Text::sprintf('COM_FORMEA_UPLOAD_FORM_NOT_FOUND_ERROR_S', $elementTypeString, $sampleElements[$j]['type']);
          $logs[]            = ['level' => -1, 'msg' => $msg];
        }
      }
    }
    $processElements['elementCode']     = $elementCode;
    $processElements['skippedElements'] = $skippedElements;
    $processElements['logs']            = $logs;


    return $processElements;
  }

  private function installGroupedElements($processElements, $formStructure, $formDetail, $formeaExtensions, $user, $langTag = 'en-GB', $defaultLangTag = 'en-GB')
  {

    if (!empty($formStructure['groupedElements']) && !empty($formStructure['grouped_map'])) {

      if (isset($formStructure['elements']['map'])) {
        $groupedElementCode = array_flip($formStructure['grouped_map']);
      }

      $db = $this->getDatabase();

      $groupedElementColumns = $db->getTableColumns('#__formea_groups');
      $skippedColumns        = [
        'id',
        'layout',
        'checked_out',
        'checked_out_time',
        'publish_up',
        'publish_down',
        'created_date',
        'created_by',
        'modified_date',
        'modified_by'
      ];

      $string = json_encode($formStructure['groupedElements']);

      foreach ($processElements['elementCode'] as $elementCode => $element_id) {
        $string = str_replace($elementCode, $element_id, $string);
      }

      $formStructure['groupedElements'] = json_decode($string, true);

      $totalGroupedElements = count($formStructure['groupedElements']);
      $date                 = new FsrDate();
      $container            = Factory::getContainer();
      /** @var DatabaseDriver $db */
      $db                  = $container->get('DatabaseDriver');
      $groupedElementModel = new GroupedElementModel();
      $layouts             = [];
      $coreTypeString      = Text::_('COM_FORMEA_CORE_EXTENSION_TYPE');
      for ($i = 0; $i < $totalGroupedElements; $i++) {
        if (isset($formStructure['groupedElements'][$i]['layout']) && !empty($formStructure['groupedElements'][$i]['layout'])) {
          $newGroupedElement = [];
          foreach ($formStructure['groupedElements'][$i] as $property => $value) {
            if (isset($groupedElementColumns[$property]) && !in_array($property, $skippedColumns)) {
              if ($property == 'alias') {
                $value = FsrHelper::createAlias($value, 'formea_groups');
              }
              $newGroupedElement[$property] = $value;
            }
          }

          if (!empty($newGroupedElement)) {

            $newGroupedElement['created_by']    = $user->id;
            $newGroupedElement['modified_by']   = $user->id;
            $newGroupedElement['created_date']  = $date->toSql();
            $newGroupedElement['modified_date'] = $date->toSql();
            $newGroupedElement                  = (object) $newGroupedElement;
            $db->insertObject('#__formea_groups', $newGroupedElement);
            $newGroupedElement->id                 = $db->insertid();
            $idPlaceholderKey                      = $formStructure['groupedElements'][$i]['id']; //[SP_YOUR_NAME]
            $groupedElementCode[$idPlaceholderKey] = $newGroupedElement->id;
            $layouts[$newGroupedElement->id]       = $formStructure['groupedElements'][$i]['layout'];
            //
            if (!empty($formStructure['groupedElements'][$i]['cores'])) {
              $totalCores = count($formStructure['groupedElements'][$i]['cores']);
              for ($j = 0; $j < $totalCores; $j++) {
                if (isset($formeaExtensions->cores[$formStructure['groupedElements'][$i]['cores'][$j]['corename']])) {

                  $groupCoreParams = $formStructure['groupedElements'][$i]['cores'][$j]['params'];
                  if (!is_string($groupCoreParams)) {
                    $groupCoreParams = json_encode($groupCoreParams);
                  }
                  $groupCore = [
                    'group_id' => $newGroupedElement->id,
                    'enabled'  => $formStructure['groupedElements'][$i]['cores'][$j]['enabled'],
                    'corename' => $formStructure['groupedElements'][$i]['cores'][$j]['corename'],
                    'params'   => $groupCoreParams,
                  ];
                  $groupCore = (object) $groupCore;
                  $db->insertObject('#__formea_group_cores', $groupCore);
                  $groupCore->id = $db->insertid();
                } else {
                  $processElements['skippedCores'][] = $formStructure['groupedElements'][$i]['cores'][$j]['corename'];
                  $msg                               = Text::sprintf('COM_FORMEA_UPLOAD_FORM_NOT_FOUND_ERROR_S', $coreTypeString, $formStructure['groupedElements'][$i]['cores'][$j]['corename']);
                  $processElements['logs'][]         = ['level' => -1, 'msg' => $msg];
                }
              }
            }
          }
        }
      }

      if (!empty($layouts)) {
        foreach ($layouts as $group_id => $layout) {
          $layoutString = json_encode($layout);
          foreach ($groupedElementCode as $groupCode => $group_replace_id) {
            $layoutString = str_replace($groupCode, $group_replace_id, $layoutString);
          }
          $decoded = json_decode($layoutString);
          $groupedElementModel->uploadGroupedElementLayout($group_id, $decoded);
        }
      }
      $processElements['groupedElementCode'] = $groupedElementCode;
    }

    return $processElements;
  }

  private function installLayout($defaultTheme, $processElements, $formStructure, $formDetail, $formeaExtensions, $user, $langTag = 'en-GB', $defaultLangTag = 'en-GB')
  {
    if (isset($formStructure['form']) && isset($formStructure['layouts']) && !empty($formStructure['layouts']) && !empty($formStructure['form'])) {
      $formJson    = json_encode($formStructure['form']);
      $formRowJson = json_encode($formStructure['layouts']);

      foreach ($processElements['elementCode'] as $keyCode => $element_id) {
        $formJson    = str_replace($keyCode, $element_id, $formJson);
        $formRowJson = str_replace($keyCode, $element_id, $formRowJson);
      }
      foreach ($processElements['groupedElementCode'] as $keyCode => $element_id) {
        $formJson    = str_replace($keyCode, $element_id, $formJson);
        $formRowJson = str_replace($keyCode, $element_id, $formRowJson);
      }
      $coreTypeString = Text::_('COM_FORMEA_CORE_EXTENSION_TYPE');
      $formeaModel    = new FormeaModel();
      $sampleForm     = json_decode($formJson, true);
      $db             = $this->getDatabase();
      $date           = new FsrDate();
      $formAlias      = FsrHelper::createAlias($sampleForm['alias'], 'formea_forms');
      $formObject     = [
        'title'            => $sampleForm['title'],
        'alias'            => $formAlias,
        'state'            => $sampleForm['state'],
        'limit_submission' => $sampleForm['limit_submission'],
        'allow_submission' => $sampleForm['allow_submission'],
        'inline_css'       => $sampleForm['inline_css'],
        'additional_css'   => $sampleForm['additional_css'],
        'inline_js'        => $sampleForm['inline_js'],
        'additional_js'    => $sampleForm['additional_js'],
        'admin_column'     => json_encode($sampleForm['admin_column']),
        'form_type'        => $sampleForm['form_type'],
        'access_level'     => $sampleForm['access_level'],
        'params'           => $sampleForm['params'],
        'created_date'     => $date->toSql(),
        'created_by'       => (!is_null($user->id)) ? $user->id : 0,
      ];

      $formObject = (object) $formObject;
      //determine new or overwrite
      if ((int) $formDetail['overwrite'] == 1 && (int) $formDetail['overwrite_id'] > 0) {
        $pks                 = [(int) $formDetail['overwrite_id']];
        $deleteRelatedTables = $formeaModel->deleteDependencies($pks);

        $formObject->id = (int) $formDetail['overwrite_id'];
        $db->updateObject('#__formea_forms', $formObject, 'id');
      } else {
        $db->insertObject('#__formea_forms', $formObject);
        $formObject->id = $db->insertid();
      }

      $processElements['form_title'] = $sampleForm['title'];
      $processElements['form_id']    = $formObject->id;

      $processElements['form_url'] = 'index.php?option=com_formea&view=formea&task=formea.edit&id=' . $formObject->id;
      //formEmails
      $totalFormEmails = count($sampleForm['emails']);
      for ($i = 0; $i < $totalFormEmails; $i++) {
        $formEmail = [
          'form_id'       => $formObject->id,
          'target_type'   => $sampleForm['emails'][$i]['target_type'],
          'from_email'    => $sampleForm['emails'][$i]['from_email'],
          'to_email'      => $sampleForm['emails'][$i]['to_email'],
          'cc_email'      => $sampleForm['emails'][$i]['cc_email'],
          'bcc_email'     => $sampleForm['emails'][$i]['bcc_email'],
          'replyto_email' => $sampleForm['emails'][$i]['replyto_email'],
        ];
        $formEmail = (object) $formEmail;
        $db->insertObject('#__formea_formemails', $formEmail);
        $formEmail->id     = $db->insertid();
        $totalEmailContent = count($sampleForm['emails'][$i]['contents']);
        if ($langTag !== $defaultLangTag) {
          if ($totalEmailContent > 0) {
            $_emailContent                          = $sampleForm['emails'][$i]['contents'][0];
            $_emailContent['language']              = $langTag;
            $sampleForm['emails'][$i]['contents'][] = $_emailContent;
            $totalEmailContent                      = count($sampleForm['emails'][$i]['contents']);
          }
        }
        for ($j = 0; $j < $totalEmailContent; $j++) {
          $emailContent = [
            'form_id'       => $formObject->id,
            'email_id'      => $formEmail->id,
            'from_name'     => $sampleForm['emails'][$i]['contents'][$j]['from_name'],
            'replyto_name'  => $sampleForm['emails'][$i]['contents'][$j]['replyto_name'],
            'subject'       => $sampleForm['emails'][$i]['contents'][$j]['subject'],
            'email_content' => $sampleForm['emails'][$i]['contents'][$j]['email_content'],
            'attachments'   => $sampleForm['emails'][$i]['contents'][$j]['attachments'],
            'language'      => $sampleForm['emails'][$i]['contents'][$j]['language'],
          ];
          $emailContent = (object) $emailContent;
          $db->insertObject('#__formea_formemailcontent', $emailContent);
          $emailContent->id = $db->insertid();

          if (!empty($formStructure['attachmentsFolder']) && (!empty($emailContent->email_content) || !empty($emailContent->attachments))) {
            $imgArray = [];
            if (!empty($emailContent->email_content)) {
              $imgArray = array_merge($imgArray, FsrHelper::getAllImageSrc($emailContent->email_content));
            }
            if (!empty($emailContent->attachments)) {
              $imgArray = array_merge($imgArray, json_decode($emailContent->attachments));
            }

            if (!empty($imgArray)) {
              $sourceDir = $formDetail['tmp_dir'] . '/attachments/';
              $copyFiles = FsrHelper::copyFilesFromBackup($sourceDir, $formStructure['attachmentsFolder'], $imgArray);
            }
          }
        }
      }

      //form details
      $totalFormDetails = count($sampleForm['details']);
      if ($langTag !== $defaultLangTag) {
        if ($totalFormDetails > 0) {
          $_formDetail             = $sampleForm['details'][0];
          $_formDetail['language'] = $langTag;
          $sampleForm['details'][] = $_formDetail;
          $totalFormDetails        = count($sampleForm['details']);
        }
      }
      for ($i = 0; $i < $totalFormDetails; $i++) {
        $formDetail = [
          'form_id'      => $formObject->id,
          'form_heading' => $sampleForm['details'][$i]['form_heading'],
          'metakey'      => $sampleForm['details'][$i]['metakey'],
          'metadesc'     => $sampleForm['details'][$i]['metadesc'],
          'language'     => $sampleForm['details'][$i]['language'],
        ];
        $formDetail = (object) $formDetail;
        $db->insertObject('#__formea_formdetails', $formDetail);
      }

      //form theme

      $themeId = $defaultTheme->extension_id;
      $loadCss = 0;
      $loadJS  = 0;


      if (isset($sampleForm['theme']['name'])) {
        if (isset($formeaExtensions->themes[$sampleForm['theme']['name']])) {
          $themeId = $formeaExtensions->themes[$sampleForm['theme']['name']]->extension_id;
        } elseif ((int) $sampleForm['theme']['theme_id'] == 0) {
          $themeId = 0;
        }
      }
      if (isset($sampleForm['theme']['load_css'])) {
        $loadCss = $sampleForm['theme']['load_css'];
      }
      if (isset($sampleForm['theme']['load_js'])) {
        $loadJS = $sampleForm['theme']['load_js'];
      }


      $formTheme = [
        'form_id'  => $formObject->id,
        'theme_id' => $themeId,
        'style_id' => 0,
        'load_css' => $loadCss,
        'load_js'  => $loadJS,
      ];
      $formTheme = (object) $formTheme;
      $db->insertObject('#__formea_formthemes', $formTheme);

      //submissions
      $totalSubmissions = count($sampleForm['submissions']);
      if ($langTag !== $defaultLangTag) {
        if ($totalFormDetails > 0) {
          $_submission                 = $sampleForm['submissions'][0];
          $_submission['language']     = $langTag;
          $sampleForm['submissions'][] = $_submission;
          $totalSubmissions            = count($sampleForm['submissions']);
        }
      }
      for ($l = 0; $l < $totalSubmissions; $l++) {
        $submission = [
          'form_id'          => $formObject->id,
          'submission_msg'   => $sampleForm['submissions'][$l]['submission_msg'],
          'global_error_msg' => $sampleForm['submissions'][$l]['global_error_msg'],
          'limit_reach_msg'  => $sampleForm['submissions'][$l]['limit_reach_msg'],
          'language'         => $sampleForm['submissions'][$l]['language'],
        ];
        $submission = (object) $submission;
        $db->insertObject('#__formea_formsubmissions', $submission);
      }


      $rows = json_decode($formRowJson);

      $totalLayouts = count($rows);
      if ($totalLayouts > 1) {
        //check renderer
        $rendererExtensions = FormeaGeneralHelper::getCoreExtensions(1, [1]);
        if (empty($rendererExtensions)) {
          $processElements['skippedCores'][] = 'MultiPage';
          $msg                               = Text::sprintf('COM_FORMEA_UPLOAD_FORM_NOT_FOUND_ERROR_S', $coreTypeString, 'MultiPage');
          $processElements['logs'][]         = ['level' => -1, 'msg' => $msg];
        }
      }

      $formeaModel->uploadGroupedElementLayout((int) $formObject->id, $rows, true);
    }

    return $processElements;
  }

  private function installSubmissionData($processElements, $formStructure, $formDetail)
  {
    $submissionString = json_encode($formStructure['submissions']);

    foreach ($processElements['elementCode'] as $keyCode => $element_id) {
      $submissionString = str_replace($keyCode, $element_id, $submissionString);
    }
    foreach ($processElements['groupedElementCode'] as $keyCode => $element_id) {
      $submissionString = str_replace($keyCode, $element_id, $submissionString);
    }

    $submissions = json_decode($submissionString, true);

    $totalSubmissions           = count($submissions);
    $db                         = $this->getDatabase();
    $submissionColumns          = $db->getTableColumns('#__formea_submissions');
    $submissionDataColumns      = $db->getTableColumns('#__formea_submission_data');
    $submissionColumIgnore      = [
      'id',
      'form_id'
    ];
    $submissionDataColumnIgnore = [
      'id',
      'form_id',
      'submission_id',
    ];

    $submissionDirPath = JPATH_ROOT . '/media/com_formea/uploads';
    if (!is_dir($submissionDirPath)) {
      Folder::create($submissionDirPath);
    }
    $submissionDirPath      .= '/';
    $submissionSourceFolder = $formDetail['tmp_dir'] . '/submissions/';
    $formId                 = (int) $processElements['form_id'];
    for ($i = 0; $i < $totalSubmissions; $i++) {
      $submission = [];
      foreach ($submissions[$i] as $submissionKey => $submissionValue) {
        if (isset($submissionColumns[$submissionKey]) && !in_array($submissionKey, $submissionColumIgnore) && $submissionKey !== 'data') {
          $submission[$submissionKey] = $submissionValue;
        }
      }
      if (!empty($submission)) {
        $submission['form_id'] = $formId;
        $submission            = (object) $submission;

        $formTitle = OutputFilter::stringUrlSafe($processElements['form_title']);

        $db->insertObject('#__formea_submissions', $submission);
        $submission->id = $db->insertId();

        $totalData = count($submissions[$i]['data']);
        for ($j = 0; $j < $totalData; $j++) {
          $submissionData = [];
          foreach ($submissions[$i]['data'][$j] as $submissionDataKey => $submissionDataValue) {
            if (isset($submissionDataColumns[$submissionDataKey]) && !in_array($submissionDataKey, $submissionDataColumnIgnore)) {
              $submissionData[$submissionDataKey] = $submissionDataValue;
            }
          }

          if (!empty($submissionData)) {
            $submissionData['form_id']       = $formId;
            $submissionData['submission_id'] = $submission->id;
            $submissionData                  = (object) $submissionData;
            $db->insertObject('#__formea_submission_data', $submissionData);
            $submissionData->id = $db->insertId();

            if ((int) $submissions[$i]['data'][$j]['is_link'] && !empty($submissions[$i]['data'][$j]['dir_path'])) {
              $files        = json_decode($submissions[$i]['data'][$j]['dir_path']);
              $totalDirPath = count($files);
              $newDirs      = [];
              $newLinks     = [];
              for ($k = 0; $k < $totalDirPath; $k++) {
                $fileInfo = $files[$k];
                if (isset($fileInfo['basename'])) {

                  //check in the directory
                  if (in_array($fileInfo['basename'], $formStructure['submissionsFolder'])) {
                    if (!is_dir($submissionDirPath . $formTitle . '/' . $submissionData->id)) {
                      Folder::create($submissionDirPath . $formTitle . '/' . $submissionData->id);
                    }

                    $newDir     = $submissionDirPath . $formTitle . '/' . $submissionData->id . '/' . $fileInfo['basename'];
                    $newDirs[]  = $newDir;
                    $newLinks[] = str_replace(JPATH_ROOT . '/', Uri::root(), $newDir);

                    File::copy($submissionSourceFolder . $fileInfo['basename'], $newDir);
                  }
                }
              }

              if (!empty($newDirs) && !empty($newLinks)) {
                $updData            = new stdClass();
                $updData->id        = $submissionData->id;
                $updData->link_path = json_encode($newLinks);
                $updData->dir_path  = json_encode($newDirs);
                $db->updateObject('#__formea_submission_data', $updData, 'id');
              }
            }
          }
        }
      }
    }

    return $processElements;
  }
}
