Your IP : 216.73.216.224


Current Path : /var/www/html/libraries/noboss/src/Form/Field/Nbtheme/
Upload File :
Current File : /var/www/html/libraries/noboss/src/Form/Field/Nbtheme/NbthemeHelper.php

<?php
/**
 * @package			No Boss Extensions
 * @subpackage  	No Boss Library
 * @author			No Boss Technology <contact@nobosstechnology.com>
 * @copyright		Copyright (C) 2026 No Boss Technology. All rights reserved.
 * @license			GNU Lesser General Public License version 3 or later; see <https://www.gnu.org/licenses/lgpl-3.0.en.html>
 */

namespace Noboss\Library\Form\Field\Nbtheme;

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Form\FormFactoryInterface;
use Noboss\Library\Util\NbCurlUtil;
use Noboss\Library\Util\NbUrlUtil;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\Language\LanguageFactoryInterface;
use Joomla\Filesystem\Path;

defined('_JEXEC') or die;

/**
 * Classe de campo personalizado para exibição de temas (executado a partir de JS)
 */
class NbthemeHelper {
    /**
     * Proxy server-side para a listagem de exemplos de temas hospedada em No Boss Extensions.
     *
     * Encapsula a chamada HTTP cross-origin que antes era feita direto pelo navegador
     * (`nobossextensions.com/index.php?option=com_nbextensoes&task=externalthemes.getThemesSamples`),
     * permitindo que o JS da modal de temas execute o XHR contra a propria origem
     * e portanto seja compativel com sites que aplicam Content Security Policy
     * com `connect-src 'self'`.
     *
     * Acessivel via:
     * WEBSITE/index.php?option=com_nobossajax&library=noboss.src.Form.Field.Nbtheme.NbthemeHelper&method=getThemesSamples&format=raw
     *
     * Recebe via POST: token, extension, loadlegend, language.
     * Retorna o mesmo JSON que o servidor remoto devolve (campos: license_valid, samples).
     */
    public static function getThemesSamples() {
        $app  = Factory::getApplication();
        $post = $app->input->post;

        // Repassa exatamente os mesmos campos que o JS enviava direto ao servidor remoto
        $dataPost = array(
            'token'      => $post->get('token', ''),
            'extension'  => $post->get('extension', ''),
            'loadlegend' => $post->get('loadlegend', '0'),
            'language'   => $post->get('language', '*'),
            'isBeta'     => $post->get('isBeta', '0'),
        );  

        $url = NbUrlUtil::getUrlNbExtensions($dataPost['isBeta']).'/index.php?option=com_nbextensoes&task=externalthemes.getThemesSamples&format=raw';

        $values = new \stdClass();
        $values->license_valid = '1';
        $values->samples       = new \stdClass();

        try {
            $curlRequest = NbCurlUtil::request('POST', $url, http_build_query($dataPost), null, 20);
        } catch (\Throwable $e) {
            // Mantem contrato esperado pelo JS: license_valid + samples
            // (em caso de falha o JS exibe banner de erro via fail() e o usuario consegue prosseguir)
            exit(json_encode($values));
        }

        // Falha de conexao ou HTTP fora do range 2xx
        if (empty($curlRequest) || empty($curlRequest->success)) {
            exit(json_encode($values));
        }

        $response = isset($curlRequest->data) ? $curlRequest->data : '';

        // Servidor remoto ja devolve JSON formatado igual ao esperado pelo JS:
        // { "license_valid": "0|1", "samples": { ... } }
        // Repassa o conteudo cru para preservar o formato.
        if (is_string($response) && $response !== '') {
            exit($response);
        }

        exit(json_encode($values));
    }

    /**
     * Carrega uma modal para a escolha de temas e exemplos de um modulo
     */
    public static function loadModuleSample() {
        $app = Factory::getApplication();
        $post = $app->input->post;
        
        // pega o idioma vindo da requisicao ajax
        $langCode = $post->get('lang');

        $language = Factory::getApplication()->getLanguage();

        // Carrega o idioma do site
        $lang = Factory::getContainer()->get(LanguageFactoryInterface::class)->createLanguage($langCode, (bool) $app->get('debug_lang'));
        $app->loadLanguage($lang);

        // Carrega arquivo tradução da library no boss
        $lang->load('lib_noboss', JPATH_SITE.'/libraries/noboss');

        $extensionToken = $post->get('token', '');
        $extension = $post->get('extensionName', 'banners');
        $model = $post->get('model', 'model1');
        $sampleId = $post->get('sampleId', "demo_{$extension}_{$model}_default");
        $itemsFormName = $post->get('itemsFormName', []);
        $addModals = $post->get('addModals', []);
        $fieldsNames = $post->get("fieldsNames", []);
        $language = $lang->get('tag', 'en-GB');
        $mainSubform = $post->getString('loadModeSubform', '');
        $isBeta = $post->get('isBeta', '0');

        // Ensure arrays are arrays to prevent implode errors
        if (!is_array($itemsFormName)) {
            $itemsFormName = [];
        }
        if (!is_array($addModals)) {
            $addModals = [];
        }
        if (!is_array($fieldsNames)) {
            $fieldsNames = [];
        }

        // TODO: codigo abaixo pode ser descomentando se quiser testar o script direto no navegador forcando uma extensao  e acessando a url https://localhost/nb/extensions/pt/?option=com_nobossajax&library=noboss.src.Form.Field.Nbtheme.NbthemeHelper&method=loadModuleSample&format=raw
        // $extensionToken = '536f40a0542b1ad75dfad213a4bd37ca';
        // $extension = 'banners';
        // $mainSubform = 'model1';

        // Extensao esta sendo carregada no site demo
        if (strpos(Uri::root(), 'nobossextensions.com/demos') !== false) {
            $siteDemo = true;
        }
        else{
            $siteDemo = false;
        }
        
        $url = NbUrlUtil::getUrlNbExtensions($isBeta).'/index.php?option=com_nbextensoes&task=externalthemes.getSample&format=raw';

        // Cria o objeto que será retornado
        $values = new \stdClass();
        $values->success = 0;

        // Configura dados do POST.
        $dataPost = array(
            'token'     => $extensionToken,
            'sampleId'  => $sampleId,
            'model'  => $model,
            'language'  => $language,
            'itemsFormName' => $itemsFormName,
            'addModals' => $addModals,
            'fieldsNames' => $fieldsNames,
            'mainSubform' => $mainSubform,
            'websiteRequest' => Uri::root()
        );

        $dataPost = http_build_query($dataPost);

        try {
            $curlRequest = NbCurlUtil::request('POST', $url, $dataPost, null, 20);
        } catch (\Throwable $e) {
            $values->message = $e->getMessage();
            exit(json_encode($values));
        }

        if (!$curlRequest->success) {
            $values->message = $curlRequest->message;
            exit(json_encode($values));
        }

        $response = $curlRequest->data;

        // echo '<pre>';
        // var_dump($response);
        // exit;
        
        // Verifica se não deu erro de exemplo não encontrado
        if (trim($response) == "SAMPLE_NOT_FOUND"){
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_NOT_FOUND');
            exit(json_encode($values));
        }
        
        try{
            // Decodifica a resposta do servidor
            $response = \json_decode($response, true);
        } catch (\Exception $e){
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_JSON_PARSE_SERVER');
            exit(json_encode($values));
        }

        // Nenhum conteudo retornado em response
        if (empty($response)){
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_NO_RESPONSE_FROM_SERVER');
            exit(json_encode($values));
        }

        // Ensure response arrays are arrays to prevent implode errors
        if (!is_array($response)) {
            $response = [];
        }
        if (isset($response['items']) && !is_array($response['items'])) {
            $response['items'] = [];
        }
        if (isset($response['fields']) && !is_array($response['fields'])) {
            $response['fields'] = [];
        }
        if (isset($response['modals']) && !is_array($response['modals'])) {
            $response['modals'] = [];
        }

        // Token invalido: personaliza mensagem conforme situacao
        if(!$siteDemo && array_key_exists('valid_token', $response)){
            // Token nao existe na base local
            if($response['valid_token'] == 0){
                $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_TOKEN_NOT_VALID');
            }
            // A licenca do usuario nao inclui o tema escolhido
            else if ($response['in_plan'] == 0){
                $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_TOKEN_PLAN_NOT_INLCUDED');
            }
            // Nao esta no periodo de atualizacoes
            else if ($response['inside_support_updates'] == 0){
                $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_TOKEN_SUPPORT_UPDATES_EXPIRATED');
            }
            
            $values->data = "INVALID_TOKEN";
            exit(json_encode($values));
        }

        if ($values) {
            // Nome da extensao foi definido no xml
            if ($extension){
                // Carrega arquivo tradução da extensao em que a modal está sendo chamada
                $lang->load("mod_noboss{$extension}", JPATH_ROOT."/modules/mod_noboss{$extension}");
            }      

            // echo '<pre>';
            // var_dump($response['items']);
            // exit;

            // Carrega o xml da extensão
            $xml = simplexml_load_file(JPATH_ROOT."/modules/mod_noboss{$extension}/mod_noboss{$extension}.xml");

            $fields = $xml->config->fields;

            // Foi setado fields especificos a terem conteudo de exemplo copiado
            if(!empty($response['fields'])){
                foreach ($response['fields'] as $fieldName => $value) {
                    try {
                        $xmlField = $fields->xpath('//field[@name="'.$fieldName.'"]');
                        $field = $xmlField[0];

                        try{
                            // Extensao esta no novo formato p/ J5
                            if(is_dir(JPATH_SITE."/modules/mod_noboss{$extension}/src")){
                                $extensionUcFirst = ucfirst($extension);

                                // Monta o xml que sera usado pelo getinstance
                                $newXml = '<form addfieldprefix="Noboss\Library\Form\Field"><fieldset addfieldprefix="Noboss\Module\\'.$extensionUcFirst.'\Site\Field" name="basic" >'.$field->asXML().'</fieldset></form>';

                                //echo $newXml; exit;
                            }
                        
                            // TODO: qnd todas extensoes estiverem migradas para novo formato do J5 podemos remover esse else e deixar soh o conteudo do if acima
                            // Extensao esta no formato antigo que exige plugin de compatibilidade
                            else{
                                // Monta o xml que sera usado pelo getinstance
                                $newXml = '<form addfieldpath="libraries/noboss/forms/fields"><fieldset addfieldpath="modules/mod_noboss'.$extension.'/fields" name="basic" >'.$field->asXML().'</fieldset></form>';
                            }

                            // Instancia o form
                            $formFactory = Factory::getContainer()->get(FormFactoryInterface::class);
                            $form = $formFactory->createForm($fieldName, array('control' => 'jform[params]'));
                            $form->load($newXml);
                        
                        } catch (\Exception $e){
                            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_XML_INVALID');
                            exit(json_encode($values));
                        }

                        // // se tiver valor seta no campo
                        // if(!empty($value)){
                            // Seta os valores do field
                            $form->setValue($fieldName, null, ($response['fields'][$fieldName]));
                        // }
                        
                        // adiciona na resposta o html do field
                        $response['fields'][$fieldName] = $form->getField($fieldName)->renderField();
                    } catch (\Throwable $e) {
                        $values->message = 'Error processing field ' . $fieldName . ': ' . $e->getMessage();
                        exit(json_encode($values));
                    }
                }
            }
            
            // Foi setado ao menos um subform a ter conteudo de exemplo copiado
            if(!empty($response['items'])){

                foreach($response['items'] as $subformName => $val){                  
                    try{
                        // Extensao esta no novo formato p/ J5
                        if(is_dir(JPATH_SITE."/modules/mod_noboss{$extension}/src")){
                            $xmlSubform = $fields->xpath('//field[@name="'.$subformName.'" and starts-with(@type,"NbSubform")]');

                            $subform = $xmlSubform[0]; 

                            $extensionUcFirst = ucfirst($extension);

                            // Monta o xml que sera usado pelo getinstance
                            $newXml = '<form addfieldprefix="Noboss\Library\Form\Field"><fieldset addfieldprefix="Noboss\Module\\'.$extensionUcFirst.'\Site\Field" name="basic" >'.$subform->asXML().'</fieldset></form>';

                            //echo $newXml; exit;
                        }
                        // TODO: qnd todas extensoes estiverem migradas para novo formato do J5 podemos remover esse else e deixar soh o conteudo do if acima
                        // Extensao esta no formato antigo que exige plugin de compatibilidade
                        else{
                            $xmlSubform = $fields->xpath('//field[@name="'.$subformName.'" and starts-with(@type,"nobosssubform")]');

                            $subform = $xmlSubform[0]; 

                            // Monta o xml que sera usado pelo getinstance
                            $newXml = '<form addfieldpath="libraries/noboss/forms/fields"><fieldset addfieldpath="modules/mod_noboss'.$extension.'/fields" name="basic" >'.$subform->asXML().'</fieldset></form>';
                        }
                        
                        // Instancia o formulário
                        $formFactory = Factory::getContainer()->get(FormFactoryInterface::class);
                        $form = $formFactory->createForm($subformName, array('control' => 'jform[params]'));
                        $form->load($newXml);

                    } catch (\Exception $e){
                        $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_XML_INVALID');
                        exit(json_encode($values));
                    }

                    try {
                        // Seta os valores do subform
                        $subformValue = $response['items'][$subformName];
                        if (!is_array($subformValue) || empty($subformValue)) {
                            $subformValue = null; // Let subform use default empty row
                        }
                        $form->setValue($subformName, null, $subformValue);

                        $response['items'][$subformName] = $form->getField($subformName)->renderField();
                    } catch (\Throwable $e) {
                        $values->message = 'Error processing subform ' . $subformName . ': ' . $e->getMessage();
                        exit(json_encode($values));
                    }
                }
            }

            $values->success = 1;
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_SUCCESS');
            $values->data = $response;
        }
        
        exit(json_encode($values));
    }	
    
    /**
     * Carrega uma modal para a escolha de temas e exemplos de um componente
     */
    public static function loadComponentSample() {
        $app = Factory::getApplication();
        $post = $app->input->post;

        // pega o idioma vindo da requisicao ajax
        $langCode = $post->get('lang');

        $language = Factory::getApplication()->getLanguage();

         // Carrega o idioma do site
        $lang = Factory::getContainer()->get(LanguageFactoryInterface::class)->createLanguage($langCode, (bool) $app->get('debug_lang'));
        $app->loadLanguage($lang);

        // Carrega arquivo tradução da library no boss
        $lang->load('lib_noboss', JPATH_SITE.'/libraries/noboss');

        // Token da extensão
        $extensionToken = $post->get('token'); 
        // Pega o nome da extensão
        $extension = $post->get('extensionName', '');
        // Nome da extensao foi definido no xml
        if ($extension){
            // Carrega arquivo tradução da extensao em que a modal está sendo chamada
           $lang->load("com_noboss{$extension}", JPATH_ROOT."/administrator/components/com_noboss{$extension}");
        }
        // Pega o nome do tema escolhido
        $model = $post->get('model', 'model1');
        // Pega o modelo da extensão
        $sampleId = $post->get('sampleId', "demo_{$extension}_{$model}_default");
        // Pega a a tag de linguagem atual
        $language = Factory::getApplication()->getLanguage()->get('tag');

        $isBeta = $post->get('isBeta', '0');

        $url = NbUrlUtil::getUrlNbExtensions($isBeta).'/index.php?option=com_nbextensoes&task=externalthemes.getSample&format=raw';
        // Cria o objeto que será retornado
        $values = new \stdClass();
        $values->success = 0;

        // Configura dados do POST.
        $dataPost = array(
            'token'     => $extensionToken,
            'sampleId'  => $sampleId,
            'model'     => $model,
            'language'  => $language,
            'component' => true
        );

        // Faz uma requisição curl usando a library
        try {
            $curlRequest = NbCurlUtil::request('POST', $url, $dataPost, null, 20);
        } catch (\Throwable $e) {
            $values->message = $e->getMessage();
            exit(json_encode($values));
        }

        if (!$curlRequest->success) {
            $values->message = $curlRequest->message;
            exit(json_encode($values));
        }

        $rawBody = $curlRequest->data;

        $response  = \json_decode($rawBody, true);
        $jsonError = \json_last_error();

        if ($jsonError !== JSON_ERROR_NONE) {
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_JSON_PARSE_SERVER');
            exit(\json_encode($values));
        }

        // Remoto: json_encode(false) quando getSample nao encontra modulo na posicao (ver ExternalthemesModel::getSample)
        if ($response === false) {
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_NOT_FOUND');
            exit(\json_encode($values));
        }

        if (!\is_array($response)) {
            if (\is_string($response) && $response !== '') {
                $again = \json_decode($response, true);
                if (\json_last_error() === JSON_ERROR_NONE && \is_array($again)) {
                    $response = $again;
                }
            }
        }

        if (!\is_array($response)) {
            $response = [];
        }

        // Params as vezes vêm aninhados em "params" (Registry / export)
        if (isset($response['params']) && (\is_array($response['params']) || \is_object($response['params']))) {
            $nested = (array) $response['params'];
            unset($response['params']);
            $response = \array_merge($response, $nested);
        }

        if (isset($response['fields']) && !\is_array($response['fields'])) {
            $response['fields'] = [];
        }
        if (isset($response['modals']) && !\is_array($response['modals'])) {
            $response['modals'] = [];
        }

        $flatModalKeyPattern = '/_display_(external_area|items_customization|search_form|categories)_/i';
        $metaKeys            = [
            'valid_token', 'in_plan', 'inside_support_updates',
            'module_tag', 'header_tag', 'modals', 'fields', 'modalsJson',
            'items', 'itemsloadmode',
        ];

        // Resposta de modulos usa "modals"; o JS (nobosstheme.js) so le "modalsJson"
        if (!empty($response['modals']) && empty($response['modalsJson'])) {
            $response['modalsJson'] = $response['modals'];
        }

        // component=true: JSON plano dos params — nao exigir ausencia de "fields" (pode existir nos params do modulo)
        if (empty($response['modalsJson'])) {
            $fromFlat = [];
            foreach ($response as $key => $value) {
                if (!\is_string($key) || \in_array($key, $metaKeys, true)) {
                    continue;
                }
                if (\preg_match($flatModalKeyPattern, $key)) {
                    $fromFlat[$key] = (\is_array($value) || \is_object($value))
                        ? \json_encode($value, JSON_UNESCAPED_UNICODE)
                        : $value;
                }
            }
            if (!empty($fromFlat)) {
                $response['modalsJson'] = $fromFlat;
            }
        }

        $fieldsExisting = (isset($response['fields']) && \is_array($response['fields'])) ? $response['fields'] : [];
        if (\count($fieldsExisting) === 0) {
            $fields      = [];
            $modalIndex = \array_flip(\array_keys($response['modalsJson'] ?? []));
            foreach ($response as $key => $value) {
                if (!\is_string($key) || \in_array($key, $metaKeys, true)) {
                    continue;
                }
                if (isset($modalIndex[$key])) {
                    continue;
                }
                $fields[$key] = $value;
            }
            $response['fields'] = $fields;
        }

        if (!isset($response['modalsJson']) || !\is_array($response['modalsJson'])) {
            $response['modalsJson'] = [];
        }
        if (!isset($response['fields']) || !\is_array($response['fields'])) {
            $response['fields'] = [];
        }

        // Verifica se o token é invalido ou o periodo de suporte expirou
        if(array_key_exists('valid_token', $response)){
            // Varifica se o token existe
            if($response['valid_token'] == 0){
                $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_TOKEN_NOT_VALID');
            // Verifica se o plano inclui o modelo
            } else if ($response['in_plan'] == 0){
                $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_TOKEN_PLAN_NOT_INLCUDED');
            // Caso seja custom, verifica se está no periodo do suporte
            } else if ($response['inside_support_updates'] == 0){
                $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_TOKEN_SUPPORT_UPDATES_EXPIRATED');
            }
            $values->data = "INVALID_TOKEN";
            exit(json_encode($values));
        }
        

        // Carrega o XML do formulario do componente (J5: forms/*.xml; legado: models/forms/group.xml)
        $componentBase     = Path::clean(JPATH_ADMINISTRATOR . '/components/com_noboss' . $extension);
        $extensionLower    = strtolower((string) $extension);
        $formXmlCandidates = [
            $componentBase . '/forms/' . $extensionLower . '.xml',
            $componentBase . '/forms/faq.xml',
            $componentBase . '/forms/group.xml',
            $componentBase . '/models/forms/group.xml',
        ];
        $formXmlPath = null;
        foreach ($formXmlCandidates as $candidate) {
            if (\is_file($candidate)) {
                $formXmlPath = $candidate;
                break;
            }
        }

        if ($formXmlPath === null) {
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_XML_INVALID');
            exit(json_encode($values));
        }

        $xml = \simplexml_load_file($formXmlPath);
        if ($xml === false) {
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_XML_INVALID');
            exit(json_encode($values));
        }

        try{
            // Extensao esta no novo formato p/ J5
            if(is_dir(JPATH_ROOT."/administrator/components/com_noboss{$extension}/src")){
                $extensionUcFirst = ucfirst($extension);

                // Monta inicio do xml que sera usado pelo getinstance
                $xmlFields = '<form addfieldprefix="Noboss\\Library\\Form\\Field"><fieldset addfieldprefix="Noboss\\Component\\' . $extensionUcFirst . '\\Administrator\\Field" name="basic" >';

                //echo $xmlFields; exit;
            }
            // TODO: qnd todas extensoes estiverem migradas para novo formato do J5 podemos remover esse else e deixar soh o conteudo do if acima
            // Extensao esta no formato antigo que exige plugin de compatibilidade
            else{
                // Monta inicio do xml que sera usado pelo getinstance
                $xmlFields = '<form addfieldpath="libraries/noboss/forms/fields"><fieldset addfieldpath="administrator/components/com_noboss'.$extension.'/models/fields" name="basic" >';
            }

            // Percorre todos os fields a serem adicionados no form
            foreach ($response['fields'] as $key => $value) {
                try {
                    $field = $xml->xpath('//field[@name="'.$key.'"]');
                    $field = $field[0];
                    if(!empty($field)){
                        $xmlFields .= $field->asXML();
                    }
                } catch (\Throwable $e) {
                    $values->message = 'Error processing field ' . $key . ': ' . $e->getMessage();
                    exit(json_encode($values));
                }
            }
            $xmlFields .= "</fieldset></form>";   

            // Instancia o formulario
            $formFactory = Factory::getContainer()->get(FormFactoryInterface::class);
            $form = $formFactory->createForm('sample_data', array('control' => 'jform'));
            $form->load($xmlFields);

        } catch (\Exception $e){
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_ERROR_XML_INVALID');
            exit(json_encode($values));
        }
        // percorre cada campo de dado de exemplo
        foreach ($response['fields'] as $key => $value) {
            try {
                // pega o objeto form do campo atual
                $field = $form->getField($key);

                if(!empty($field)){
                    // seta o valor
                    $field->setValue($value);
                    // renderiza o html desse field na resposta da requisicao
                    $response['fields'][$key] = $field->renderField();
                }
                else{
                    unset($response['fields'][$key]);
                }
            } catch (\Throwable $e) {
                $values->message = 'Error processing field ' . $key . ': ' . $e->getMessage();
                exit(json_encode($values));
            }
        }

        if ($values) {
            
            // seta como sucesso a requisicao
            $values->success = 1;
            // mensagem de sucesso
            $values->message = Text::_('LIB_NOBOSS_FIELD_NOBOSSTHEME_GENERATE_EXAMPLES_SUCCESS');
            // adiciona os json das modais no valor que sera retornado
            $values->data = $response;
        }
        // Retorna em formato json
        exit(json_encode($values));
    }
}