{"id":233931,"date":"2023-02-26T17:35:00","date_gmt":"2023-02-26T14:35:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233931"},"modified":"2022-11-11T13:14:34","modified_gmt":"2022-11-11T10:14:34","slug":"crear-contenido-programaticamente-a-partir-de-entradas-de-formularios-de-gravedad","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/crear-contenido-programaticamente-a-partir-de-entradas-de-formularios-de-gravedad\/","title":{"rendered":"Crear contenido program\u00e1ticamente a partir de entradas de formularios de gravedad"},"content":{"rendered":"\n<p>Esta publicaci\u00f3n lo guiar\u00e1 sobre c\u00f3mo crear cualquier tipo de contenido (usuarios, publicaciones o algo m\u00e1s personalizado) basado en entradas en un formulario de Gravity Forms. Agregaremos un \u00e1rea en la pantalla de detalles de entrada en el administrador para crear contenido basado en la informaci\u00f3n enviada.<\/p>\n<h2>que haremos<\/h2>\n<p>Crearemos un nuevo metabox en la pantalla de detalles de entrada de Gravity Form. En este metabox agregaremos un bot\u00f3n. La idea es que el usuario final pueda revisar la entrada y, si aprueba los detalles de la entrada, puede presionar el bot\u00f3n para activar la creaci\u00f3n de contenido.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cba9a24f2.png\" data-rel=\"lightbox\" ><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cba9a24f2.png\" alt=\"Crear contenido program\u00e1ticamente a partir de entradas de formularios de gravedad\" ><\/a><\/p>\n<p>Nuestro c\u00f3digo se activar\u00e1 al hacer clic en este bot\u00f3n, realizar la acci\u00f3n necesaria y, opcionalmente, presentaremos un mensaje del resultado al usuario final. Tambi\u00e9n (opcionalmente) agregaremos metadatos a la entrada para que podamos verificar f\u00e1cilmente si el contenido se ha creado a partir de esta entrada antes o no.<\/p>\n<p>Mantendr\u00e9 el c\u00f3digo bastante simple y general para que pueda sustituirlo y modificarlo f\u00e1cilmente para que se ajuste a las necesidades de su proyecto. En el siguiente ejemplo, supondr\u00e9 que queremos crear un usuario program\u00e1ticamente. Pero lo que haga con los detalles de la entrada depende completamente de usted; puede crear una publicaci\u00f3n, actualizar alg\u00fan otro contenido o enviar un correo electr\u00f3nico personalizado si lo desea.<\/p>\n<h2>identificando los campos<\/h2>\n<p>La primera consideraci\u00f3n que tenemos que hacer es c\u00f3mo identificar los campos. En otras palabras, necesitamos saber qu\u00e9 campo es qu\u00e9. Tenga en cuenta que los valores de una entrada en Gravity Forms se refieren a sus ID de campo de formulario. E incluso con acceso a la informaci\u00f3n de cada campo de formulario, necesitamos una forma segura de saber qu\u00e9 campos son qu\u00e9 informaci\u00f3n. Un formulario puede constar de cuatro entradas de texto: necesitamos saber cu\u00e1l de las cuatro entradas de texto son para el nombre.<\/p>\n<p>Tienes algunas alternativas aqu\u00ed. Puede codificar los ID de campo (por ejemplo, determinar que el ID de campo 2 es el apellido), pero esto es muy propenso a errores y no se recomienda. Una forma sencilla es usar una de las entradas de informaci\u00f3n de campo existentes en Gravity Forms, por ejemplo, el nombre de la clase CSS. Pero tenga en cuenta que el usuario final puede proporcionar varios nombres de clase para obtener el estilo que desea, y su c\u00f3digo puede romperse f\u00e1cilmente si no est\u00e1 analizando correctamente esta cadena. La forma en que definitivamente recomiendo es agregar sus propias entradas personalizadas a los campos:<\/p>\n<p>Si desea un m\u00e9todo s\u00f3lido para identificar campos para su c\u00f3digo, definitivamente consulte c\u00f3mo en la publicaci\u00f3n anterior. Pero para mantenerlo simple en esta publicaci\u00f3n, usar\u00e9 la clase CSS y asumir\u00e9 que el usuario no ingresa nada m\u00e1s que los valores que necesitamos en esta \u00e1rea.<\/p>\n<h2>Configurando el formulario<\/h2>\n<p>El primer paso es, naturalmente, configurar el formulario con los campos y tipos de campo que necesita. Y luego inserta los identificadores de campo en sus lugares correctos. Como ejemplo tengo este formulario:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cbaa8ac83.png\" data-rel=\"lightbox\" ><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cbaa8ac83.png\" alt=\"Crear contenido program\u00e1ticamente a partir de entradas de formularios de gravedad\" ><\/a><\/p>\n<p>Y para cada campo que quiero incluir, proporciono una clase de CSS personalizada a la que puedo apuntar en mi c\u00f3digo. Por ejemplo, para el nombre;<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cbab8f543.png\" data-rel=\"lightbox\" ><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cbab8f543.png\" alt=\"Crear contenido program\u00e1ticamente a partir de entradas de formularios de gravedad\" ><\/a><\/p>\n<p>Ahora pasemos al c\u00f3digo y a c\u00f3mo crear una funcionalidad que convierta los env\u00edos en contenido personalizado.<\/p>\n<h2>Agregar un metabox en los detalles de la entrada<\/h2>\n<p>El primer paso es agregar alg\u00fan tipo de desencadenante de acci\u00f3n para crear nuestro contenido personalizado. Un lugar natural est\u00e1 en la pantalla de detalles de entrada. Esto permite al usuario final revisar los valores enviados y luego decidir si crear o no contenido a partir de ellos. Gravity Forms permite a los desarrolladores crear f\u00e1cilmente metaboxes personalizados en estas pantallas.<\/p>\n<p>Para crear un metabox personalizado para ingresar detalles, podemos usar el filtro <code>gform_entry_detail_meta_boxes<\/code>. Es un filtro que devuelve una matriz de todos los metaboxes para mostrar los detalles de entrada. Simplemente agregamos un nuevo elemento de matriz para crear un nuevo metabox y definimos una funci\u00f3n de devoluci\u00f3n de llamada para representar su contenido. Establecemos un buen t\u00edtulo descriptivo en &#8216; <code>title<\/code>&#8216; y definimos su posici\u00f3n para que aparezca en &#8216; <code>side<\/code>&#8216;.<\/p>\n<pre><code>add_filter('gform_entry_detail_meta_boxes', function($meta_boxes, $entry, $form) {\n    $meta_boxes['awp-create-user-metabox'] = [\n        'title' =&gt; __('Create user from entry', 'awp'),\n        'callback' =&gt; 'awp_gf_create_user_metabox_render',\n        'context' =&gt; 'side'\n    ];\n    return $meta_boxes;\n}, 10, 3);<\/code><\/pre>\n<p>Y luego necesitamos definir la funci\u00f3n de devoluci\u00f3n de llamada: <code>awp_gf_create_user_metabox_render()<\/code>en nuestro c\u00f3digo. Esta funci\u00f3n es responsable de representar el contenido del metabox. Como par\u00e1metro de esta funci\u00f3n, obtenemos una serie de argumentos, en los que podemos obtener el formulario y el objeto de entrada;<\/p>\n<pre><code>function awp_gf_create_user_metabox_render($args) {\n    $form = $args['form'];  \/\/ Form array. Here we find all the fields in $form['fields']\n    $entry = $args['entry'];  \/\/ Entry array. Here we find all values in this current submission\n    $render = '';\n    echo $render;\n}<\/code><\/pre>\n<p>Todo lo que tenemos que hacer en esta funci\u00f3n es construir algo de HTML y repetirlo.<\/p>\n<p>En cuanto a agregar un bot\u00f3n para activar una acci\u00f3n, seguiremos el mismo m\u00e9todo que lo hace Gravity Forms. Hay un elemento de formulario que envuelve toda la pantalla de detalles de entrada, y todo lo que tenemos que hacer es agregar un evento onclick en un bot\u00f3n de env\u00edo que cambiar\u00e1 la <code>action<\/code>propiedad &#8216; &#8216;. Definimos nuestro propio nombre de acci\u00f3n personalizado, para que sepamos cu\u00e1ndo se ha activado, y no entra en conflicto con las acciones de Gravity Forms.<\/p>\n<p>Llamemos a nuestra acci\u00f3n personalizada &#8216; <code>awp_gf_create_user<\/code>&#8216; y representemos un bot\u00f3n de env\u00edo con un evento onclick as\u00ed:<\/p>\n<pre><code>function awp_gf_create_user_metabox_render($args) {\n    $form = $args['form'];  \/\/ Form array. Here we find all the fields in $form['fields']\n    $entry = $args['entry'];  \/\/ Entry array. Here we find all values in this current submission\n    $render = '';\n    $action = 'awp_gf_create_user';\n    $render .= sprintf('&lt;input type=\"submit\" value=\"%s\" class=\"button\" onclick=\"jQuery('#action').val('%s');\" \/&gt;', \n        __('Create user', 'awp'), \n        $action\n    );\n    echo $render;\n}<\/code><\/pre>\n<p>Con el c\u00f3digo anterior, obtendremos un nuevo metabox en el costado de la pantalla de detalles de entrada, con este aspecto:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cba9a24f2.png\" data-rel=\"lightbox\" ><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cba9a24f2.png\" alt=\"Crear contenido program\u00e1ticamente a partir de entradas de formularios de gravedad\" ><\/a><\/p>\n<p>Ahora mismo no pasa nada al hacer clic en el bot\u00f3n. Eso es solo porque a\u00fan no hemos escrito ning\u00fan c\u00f3digo para escucharlo.<\/p>\n<h2>Extraer valores de la entrada<\/h2>\n<p>Como se mencion\u00f3 anteriormente, todos los valores enviados en la matriz de entrada se identifican por sus ID de campo.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cbad6bcf2.png\" data-rel=\"lightbox\" ><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151470-61e4cbad6bcf2.png\" alt=\"Crear contenido program\u00e1ticamente a partir de entradas de formularios de gravedad\" ><\/a><\/p>\n<p>En la imagen de arriba, el campo ID 1 es para el nombre, ID 2 es el apellido y as\u00ed sucesivamente. Pero espera, \u00bfqu\u00e9 est\u00e1 pasando con 5.1, 5.3 y dem\u00e1s? En Gravity Forms obtenemos &quot;sub-ID&quot; para un campo especial que acepta m\u00faltiples valores. Agregu\u00e9 un campo de direcci\u00f3n a mi formulario que es un campo, pero m\u00faltiples entradas. Cada entrada dentro de este campo obtiene sus propias ID, adjuntas a la ID principal y un punto. Si no usa ninguno de estos campos de entrada m\u00faltiple, \u00a1genial! El c\u00f3digo se vuelve realmente simple. Pero he incluido este campo especial para que podamos ver c\u00f3mo acceder a \u00e9l.<\/p>\n<p>En este momento, nuestro problema es que el c\u00f3digo no sabe para qu\u00e9 son los ID de campo 1, 2 o 3. Esa informaci\u00f3n se encuentra en la matriz de formularios, m\u00e1s espec\u00edficamente en el <code>$form['fields']<\/code>elemento. Este elemento contiene todos los campos del formulario y tenemos acceso completo a cada objeto de campo. Es aqu\u00ed donde podemos encontrar nuestro m\u00e9todo de identificaci\u00f3n elegido; <code>cssClass<\/code>en mi ejemplo<\/p>\n<p>Simplemente podemos recorrer estos campos y buscar los identificadores que queremos extraer. Pondr\u00e9 todos mis identificadores en una matriz y simplemente podemos verificar si un campo en el bucle es uno de estos.<\/p>\n<p>Pero primero necesitamos saber que se hizo clic en el bot\u00f3n. Esto es bastante simple; simplemente podemos verificar si nuestra acci\u00f3n personalizada reside en la <code>$_POST<\/code>matriz. Pero debido a que estamos trabajando con Gravity Forms, podemos usar <code>[rgpost](https:\/\/docs.gravityforms.com\/rgpost\/)()<\/code>. La funci\u00f3n Gravity Forms <code>rgpost()<\/code>simplemente devuelve el valor de una solicitud POST. Comprobando <code>rgpost('awp_gf_create_user')<\/code>y <code>$_POST['awp_gf_create_user']<\/code>es exactamente lo mismo. Pero usaremos la funci\u00f3n de Gravity Forms.<\/p>\n<pre><code>    ...\n    $render = '';\n    $action = 'awp_gf_create_user';\n\u00a0\n    if (rgpost('action') == $action) {  \/\/ Button was clicked\n        $values = [];\n        \/\/ All identificators\n        $css_classes = ['awp_first_name', 'awp_last_name', 'awp_email', 'awp_address'];\n        foreach ($form['fields'] as $field) {\n            if (in_array($field-&gt;cssClass, $css_classes)) {\n                $values[$field-&gt;cssClass] = $entry[$field-&gt;id];\n            }\n        }\n    }\n    $render .= sprintf('&lt;input type=\"submit\" value=\"%s\" class=\"button\" onclick=\"jQuery('#action').val('%s');\" \/&gt;', \n    ...<\/code><\/pre>\n<p>En l\u00ednea <code>#8<\/code>definimos una matriz con todos los identificadores personalizados que deseamos buscar. Estos son todos los valores que ingres\u00e9 como clase CSS en mi formulario. Luego, en el ciclo de cada campo, verificamos si el campo es uno de estos identificadores. En mi ejemplo, estoy usando la clase CSS para identificar campos, pero recomiendo usar entradas personalizadas. Este c\u00f3digo tampoco funcionar\u00e1 si se dieron varias clases de CSS.<\/p>\n<p>Luego, en la l\u00ednea <code>#12<\/code>, agregamos un nuevo elemento a nuestra matriz de valores finales con el identificador como clave. Luego usamos la ID del campo y hacemos referencia a la matriz de entrada. Al final de este ciclo <code>$values<\/code>, debe completarse con los valores enviados que sean relevantes. Se excluir\u00e1n todos los campos que se hayan dejado vac\u00edos o que no se hayan incluido en la matriz de identificadores.<\/p>\n<p>Si agreg\u00f3 un campo de entrada m\u00faltiple especial, deber\u00e1 agregar un c\u00f3digo adicional para hacer referencia correctamente a las subID. S\u00e9 que <code>awp_address<\/code>es un tipo de campo de direcci\u00f3n. Los tipos de campo de direcci\u00f3n en Gravity Forms siguen un patr\u00f3n fijo de subID, y solo he habilitado tres de las entradas posibles (la direcci\u00f3n de calle 1 tiene subID 1, el c\u00f3digo postal tiene subID 3 y la ciudad tiene subID 5). Para manejar este tipo de campos, necesitamos hacer algo como esto:<\/p>\n<pre><code>        ...\n        foreach ($form['fields'] as $field) {\n            if (in_array($field-&gt;cssClass, $css_classes)) {\n                if ($field-&gt;cssClass == 'awp_address') {\n                    $address = $entry[$field-&gt;id.'.1']. ', '. $entry[$field-&gt;id.'.5']. ' '. $entry[$field-&gt;id.'.3'];\n                    $values[$field-&gt;cssClass] = $address;\n                } else {\n                    $values[$field-&gt;cssClass] = $entry[$field-&gt;id];\n                }\n            }\n        }\n        ...<\/code><\/pre>\n<p>En la l\u00ednea <code>#4<\/code>, concateno todos los valores para que la cadena final tenga un formato de direcci\u00f3n estandarizado de una l\u00ednea (&quot;,&quot;).<\/p>\n<p>Ahora tenemos todos los valores necesarios bien ordenados por claves de identificaci\u00f3n en la matriz <code>$values<\/code>. Lo que haga con esto depende totalmente de usted y de las necesidades de su proyecto. Pero incluir\u00e9 un ejemplo de c\u00f3mo crear un usuario en WordPress.<\/p>\n<h2>Creaci\u00f3n de un nuevo usuario a partir del env\u00edo de la entrada<\/h2>\n<p>Para mantener limpio mi c\u00f3digo, llamar\u00e9 a una funci\u00f3n separada que es responsable de crear un nuevo usuario. Todo lo que necesito es pasar la matriz de valores. Quiero que esta funci\u00f3n devuelva alg\u00fan tipo de indicaci\u00f3n del resultado de esta acci\u00f3n. De esta manera, puedo crear un mensaje independientemente de si el usuario se cre\u00f3 correctamente o si ya existe un usuario con el correo electr\u00f3nico proporcionado.<\/p>\n<pre><code>        ...\n        foreach ($form['fields'] as $field) {\n            if (in_array($field-&gt;cssClass, $css_classes)) {\n                $address = $entry[$field-&gt;id.'.1']. ', '. $entry[$field-&gt;id.'.5']. ' '. $entry[$field-&gt;id.'.3'];\n                    $values[$field-&gt;cssClass] = $address;\n                } else {\n                    $values[$field-&gt;cssClass] = $entry[$field-&gt;id];\n                }\n            }\n        }\n        $result = awp_gf_create_user($values);\n    }\n    ...<\/code><\/pre>\n<p>Entonces simplemente definimos la <code>awp_gf_create_user()<\/code>funci\u00f3n. Incluir\u00e9 un ejemplo simple de c\u00f3mo crear un usuario mediante programaci\u00f3n en WordPress. Esto simplemente pretende ser un ejemplo para mostrar c\u00f3mo usar los valores extra\u00eddos.<\/p>\n<p>Primero verificamos si existe un usuario con el correo electr\u00f3nico dado con <code>[get_user_by](https:\/\/developer.wordpress.org\/reference\/functions\/get_user_by\/)()<\/code>. Si no, usamos <code>[wp_insert_user](https:\/\/developer.wordpress.org\/reference\/functions\/wp_insert_user\/)()<\/code>para agregar un usuario. Tambi\u00e9n he incluido un ejemplo de almacenamiento de metadatos de usuario personalizados (nuestro campo de direcci\u00f3n). Finalmente, nuestro m\u00e9todo deber\u00eda devolver el resultado de la creaci\u00f3n del usuario. Si el usuario ya exist\u00eda, devolvemos -1. De lo contrario, devolvemos el ID de usuario.<\/p>\n<pre><code>function awp_gf_create_user($values) {\n    \/\/ Check if user exists\n    $exists = get_user_by('email', $values['awp_email']);\n    if ($exists) {\n        return -1;\n    }\n\u00a0\n    \/\/ Create user\n    $random_password = wp_generate_password(12, false);\n    $user_id = wp_insert_user([\n        'user_email' =&gt; $values['awp_email'],\n        'user_login' =&gt; $values['awp_email'],\n        'user_pass' =&gt; $random_password,\n        'first_name' =&gt; $values['awp_first_name'],\n        'last_name' =&gt; $values['awp_last_name'],\n        'role' =&gt; 'author'\n    ]);\n    \/\/ Optional: custom user meta\n    if ($user_id) {\n        update_user_meta($user_id, 'address', $values['awp_address']);\n    }\n\u00a0\n    \/\/ Return user ID (or WP_Error) back to metabox render function so we can display an appropriate message\n    return $user_id;\n}<\/code><\/pre>\n<p>De vuelta en nuestro procesamiento de metabox, ahora podemos agregar condicionalmente un mensaje al usuario final en funci\u00f3n del resultado de esto. Este es un ejemplo simple; si el valor devuelto fue -1, ya existe un usuario con el correo electr\u00f3nico proporcionado. Y si el valor devuelto fue mayor que 0, sabemos que cre\u00f3 un usuario con \u00e9xito. Por lo tanto, aparece un mensaje que dice que la creaci\u00f3n del usuario fue exitosa.<\/p>\n<pre><code>    ...\n    $message = '';\n    if (rgpost('action') == $action) {  \/\/ Button was clicked\n        ...\n        $result = awp_gf_create_user($values);\n        if ($result &gt; 0) {\n            $message = __('User successfully created!', 'awp');\n        } else if ($result == -1) {\n            $message = __('An user by that email already exists!', 'awp');\n        }\n    }\n\u00a0\n    if (!empty($message)) {\n        $render .= '&lt;p&gt;'. $message. '&lt;\/p&gt;';\n    }\n    $render .= sprintf('&lt;input type=\"submit\" value=\"%s\" class=\"button\" onclick=\"jQuery('#action').val('%s');\" \/&gt;', \n    ...<\/code><\/pre>\n<h2>Evitar contenido duplicado<\/h2>\n<p>El ejemplo simple anterior deshabilitar\u00e1 hereditariamente la creaci\u00f3n de m\u00faltiples usuarios desde la misma entrada porque verifica si ya existe un usuario con la direcci\u00f3n de correo electr\u00f3nico proporcionada. Pero en otros casos es posible que no tenga esta oportunidad. Entonces, otra estrategia para evitar que los usuarios finales creen contenido duplicado desde la misma entrada es agregar meta de entrada personalizada. En otras palabras; si la acci\u00f3n fue exitosa, agregamos un meta personalizado a esa entrada. Y luego simplemente verificamos si ese meta personalizado existe antes de comenzar la acci\u00f3n.<\/p>\n<p>Gravity Forms ofrece m\u00e9todos para agregar metadatos personalizados a las entradas; <code>[gform_add_meta](https:\/\/docs.gravityforms.com\/gform_add_meta\/)()<\/code>as\u00ed como obtener valores: <code>[gform_get_meta](https:\/\/docs.gravityforms.com\/gform_get_meta\/)()<\/code>.<\/p>\n<pre><code>    ...\n    $message = '';\n    if (rgpost('action') == $action) {  \/\/ Button was clicked\n        $already_created = gform_get_meta($entry['id'], 'awp_created_user');\n        if ($already_created) {\n            $message = __('You have already created an user from this entry!', 'awp');\n        } else {\n            ...\n            $result = awp_gf_create_user($values);\n            if ($result &gt; 0) {\n                gform_add_meta($entry['id'], 'awp_created_user', $user_id, $form['id']);\n                $message = __('User successfully created!', 'awp');\n            } else if ($result == -1) {\n                $message = __('An user by that email already exists!', 'awp');\n            }\n        }\n    }\n    ...<\/code><\/pre>\n<p>En l\u00ednea <code>#4<\/code>buscamos nuestra meta de entrada personalizada. Si existiera (no vac\u00edo), configuramos un mensaje que informa al usuario final que \u00e9l o ella ya ha intentado crear contenido desde esta entrada antes. Si el meta personalizado no exist\u00eda, continuamos creando nuestro contenido. Cuando el contenido se cre\u00f3 con \u00e9xito, debemos agregar el meta personalizado a la entrada (l\u00ednea <code>#10<\/code>).<\/p>\n<h2>Conclusi\u00f3n y c\u00f3digo final<\/h2>\n<p>En este post he intentado dar un ejemplo de c\u00f3mo crear contenido a partir de una entrada en Gravity Forms. Los ejemplos de c\u00f3digo est\u00e1n destinados a darle una idea de c\u00f3mo personalizarlo y cambiarlo para que se ajuste a las necesidades de su proyecto. Definitivamente recomiendo expandir esta funcionalidad para manejar mejor los mensajes de error. Tambi\u00e9n es posible que desee agregar solo este metabox para formularios espec\u00edficos. Pero esto deber\u00eda ser una buena base para construir.<\/p>\n<p>Y aqu\u00ed est\u00e1 el c\u00f3digo final:<\/p>\n<pre><code>add_filter('gform_entry_detail_meta_boxes', function($meta_boxes, $entry, $form) {\n    $meta_boxes['awp-create-user-metabox'] = [\n        'title' =&gt; __('Create user from entry', 'awp'),\n        'callback' =&gt; 'awp_gf_create_user_metabox_render',\n        'context' =&gt; 'side'\n    ];\n    return $meta_boxes;\n}, 10, 3);\n\u00a0\nfunction awp_gf_create_user_metabox_render($args) {\n    $form = $args['form'];  \/\/ Form array. Here we find all the fields in $form['fields']\n    $entry = $args['entry'];  \/\/ Entry array. Here we find all values in this current submission\n    $render = '';\n    $action = 'awp_gf_create_user';\n\u00a0\n    $message = '';\n    if (rgpost('action') == $action) {  \/\/ Button was clicked\n        $already_created = gform_get_meta($entry['id'], 'awp_created_user');\n        if ($already_created) {\n            $message = __('You have already created an user from this entry!', 'awp');\n        } else {\n            $values = [];\n            \/\/ All identificators\n            $css_classes = ['awp_first_name', 'awp_last_name', 'awp_email', 'awp_address'];\n            foreach ($form['fields'] as $field) {\n                if (in_array($field-&gt;cssClass, $css_classes)) {\n                    if ($field-&gt;cssClass == 'awp_address') {\n                        $address = $entry[$field-&gt;id.'.1']. ', '. $entry[$field-&gt;id.'.5']. ' '. $entry[$field-&gt;id.'.3'];\n                        $values[$field-&gt;cssClass] = $address;\n                    } else {\n                        $values[$field-&gt;cssClass] = $entry[$field-&gt;id];\n                    }\n                }\n            }\n\u00a0\n            $result = awp_gf_create_user($values);\n\u00a0\n            if ($result &gt; 0) {\n                gform_add_meta($entry['id'], 'awp_created_user', $user_id, $form['id']);\n                $message = __('User successfully created!', 'awp');\n            } else if ($result == -1) {\n                $message = __('An user by that email already exists!', 'awp');\n            }\n        }\n    }\n\u00a0\n    if (!empty($message)) {\n        $render .= '&lt;p&gt;'. $message. '&lt;\/p&gt;';\n    }\n    $render .= sprintf('&lt;input type=\"submit\" value=\"%s\" class=\"button\" onclick=\"jQuery('#action').val('%s');\" \/&gt;', \n        __('Create user', 'awp'), \n        $action\n    );\n    echo $render;\n}\n\u00a0\nfunction awp_gf_create_user($values) {\n    \/\/ Check if user exists\n    $exists = get_user_by('email', $values['awp_email']);\n    if ($exists) {\n        return -1;\n    }\n    \/\/ Create user\n    $random_password = wp_generate_password(12, false);\n    $user_id = wp_insert_user([\n        'user_email' =&gt; $values['awp_email'],\n        'user_login' =&gt; $values['awp_email'],\n        'user_pass' =&gt; $random_password,\n        'first_name' =&gt; $values['awp_first_name'],\n        'last_name' =&gt; $values['awp_last_name'],\n        'role' =&gt; 'author'\n    ]);\n    \/\/ Optional: custom user meta\n    if ($user_id) {\n        update_user_meta($user_id, 'address', $values['awp_address']);\n    }\n    \/\/ Return user ID (or WP_Error) back to metabox render function so we can display an appropriate message\n    return $user_id;\n}<\/code><\/pre>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Esta publicaci\u00f3n lo guiar\u00e1 sobre c\u00f3mo crear cualquier tipo de contenido (usuarios, publicaciones o algo m\u00e1s personalizado) basado en entradas en un formulario de Gravity Forms.<\/p>\n","protected":false},"author":1,"featured_media":151471,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[892,892,810,914,1110,914,810,840,840,861,861],"tags":[1172],"class_list":["post-233931","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo","category-complementos","category-otro","category-n-a","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/233931","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=233931"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/233931\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/151471"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=233931"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=233931"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=233931"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}