Como salvar dados do metabox com foreach
-
Olá,
Tem duas imagens que coloquei no banco de dados na tabela wp_postmeta manualmente, com o valor do meta key:my-image-for-post
, indicando claro o id do post:consigo imprimir no metabox essas imagens que já estao no db ao editar o post. Assim:
$url =get_post_meta($post->ID,'my-image-for-post', false); foreach ($url as $field) { ?> <img src="<?php echo $field;?>" style="width:200px;" /> <?php };
Mas estou tentando salvar as mutiplas imagens que seleciono no metabox ao editar o post.
Consigo selecionar imagens com gerenciador de imagens do wordpress e com jquery preencher a urls e inserir name=’my_image_URL’ no input de cada imagem selecionada:
$("#show").after("<input class='upload_image' type='text' size='36' name='my_image_URL' value= " +attachment.url+ " /></br><img src=" +attachment.url+" class='my_image' src='' width='80px'></br>");
Dentro da
<div id="show">
exibe as imagens selecionadas e os inputs são preenchidos com a url de cada imagem a ser salva.O meta box esta funcionando OK, mas quando vou salvar o post as alterações do conteudo continua ok, mas não salva as imagens do metabox no db, tentei das duas formas abaixo:
1
add_action( 'save_post', function ($post_id) { if (isset($_POST['my_image_URL'])){ $urls = $_POST['my_image_URL']; Foreach ($urls as $url){ $key1_values = get_post_custom_values( 'my-image-for-post', $post_id ); Foreach($key1_values as $value){ update_post_meta($post_id, 'my-image-for-post', $url, $value); } } } });
2 forma que tentei
add_action( 'save_post', function ($post_id) { if (isset($_POST['my_image_URL'])){ $urls = $_POST['my_image_URL']; Foreach ($urls as $url){ update_post_meta($post_id, 'my-image-for-post',$url); } } });
Mas não salva as urls na tabela wp_postmeta, o que posso estar fazendo errado?
Agradeço ajuda
-
Oi @gislef,
Se entendi bem você quer montar um array de inputs, certo? Para isso o valor do atributo
name
do elemento que você está criando deve ser sucedido de[]
, dessa forma:$("#show").after("<input class='upload_image' type='text' size='36' name='my_image_URL[]' value= " +attachment.url+ " /></br><img src=" +attachment.url+" class='my_image' src='' width='80px'></br>");
(note omy_image_URL[]
)Para fazer o debug e acompanhar o que está chegando na função associada ao hook
save_post
você também pode usar a função phpprint_r
, dessa forma:$urls = $_POST['my_image_URL']; print_r( $urls );
Além disso atenção ao termo
foreach
, o F é minúsculo.Outro ponto importante, que você provavelmente notará em seguida, é que a cada chamada para
update_post_meta
a imagem anterior será excluída. O melhor caminho é chamar a função delete_post_meta antes e depois adicionar os valores com add_post_meta.Não esqueça de voltar para dizer se evoluiu na questão e, se for o caso, marcar seu tópico como resolvido, ok?
- Esta resposta foi modificada 7 anos, 9 meses atrás por Felipe Elia.
- Esta resposta foi modificada 7 anos, 9 meses atrás por Felipe Elia.
Exatamente! Muito obrigada Felipe
add_action( 'save_post', function ($post_id) { if (isset($_POST['my_image_URL'])){ $urls = $_POST['my_image_URL']; $posts_metas = get_post_meta( $post_id, 'my-image-for-post' ); if ($posts_metas === ''){ foreach ($urls as $url){ add_post_meta( $post_id, 'my-image-for-post',$url ); } } }else{ foreach ($urls as $url){ foreach( $posts_metas as $value ) { if($value != $url){ add_post_meta( $post_id, 'my-image-for-post',$url ); }elseif($value === $url ){ update_post_meta( $post_id, 'my-image-for-post', $url ); }else{ add_post_meta( $post_id, 'my-image-for-post',$url ); } } } } });
Com sua indicação consegui cadastrar, com a primeira parte do código se não tiver nada no DB esta cadastrando as imagens selecionadas, mas ainda estou com dificuldades para verificar se já existe as urls no DB, se já existir não fazer nada ou executar a função
update_post_meta()
, e caso não existir executar a funçãoadd_post_meta()
. Tentei de diversas formas nas últimas 3 horas e ainda não consegui, contando que estou a mais de uma semana aprendendo e tentando fazer funcionar esse metabox de imagens :/Se for possivel, agradeço mais essa ajuda 🙂
Oi @gislef,
Não sei se entendi a sua necessidade, mas dê uma olhada no código que eu montei abaixo. ACHO que resolve o seu problema:
add_action( 'save_post', function ( $post_id ) { if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; // Para não fazer nada nos salvamentos automáticos do WP if ( isset( $_POST['my_image_URL'] ) ) { // Só faz alguma coisa se existia o campo no formulário enviado delete_post_meta( $post_id, 'my-image-for-post' ); // Exclui TODOS os valores, assim só ficam os que o usuário enviou $urls = $_POST['my_image_URL']; foreach ( $urls as $url ) { // Para cada url adiciona o valor add_post_meta( $post_id, 'my-image-for-post', $url ); } } });
Antes não estava conseguindo responder ao topico, retirei o codigo JSON e consegui mandar a resposta
- Esta resposta foi modificada 7 anos, 9 meses atrás por Gisele.
Obrigada Felipe, ufa! é um grande avanço
O unico porém é que esta apagando todas, não sendo possivel excluir ou alterar uma ou algumas das imagens.
Eu fiz a mesma pergunta no forum WordPress em inglês e recebi uma resposta agora a pouco, indicando que não é necessario o foreach para salvar, fiz o teste e salvou uma unica linha no DB, com o conteudo aparentemente em JSON
Assim acho interessante pois se for apagar todas imagens é só excluir a linha.
Estou conseguindo exibir o conteudo serializado normalmente (já que o wordpress deserealiza automaticamente) dentro do foreach de exibição das imagens que estão no DB
Mas no caso de editar, add ou excluir, uma da imagens que esta no DB serializada tem ideia de como faço?
Por enquanto encontrei a função wp_update_attachment_metadata(), não sei se é a função correta nesse caso ou como utilizar
https://codex.wordpress.org/Function_Reference/wp_update_attachment_metadata
- Esta resposta foi modificada 7 anos, 9 meses atrás por Gisele.
Oi @gislef,
Embora pareça, não é JSON, são só dados serializados. Você não deve acessar esses dados diretamente. Ao usar a função get_post_meta o WP automaticamente transformará essa string em um array.
Acredito que se você usar somente
add_action( 'save_post', function ( $post_id ) { if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( isset( $_POST['my_image_URL'] ) ) { update_post_meta( $post_id, 'my-image-for-post', $_POST['my_image_URL'] ); } });
já faça como explicado lá no fórum em inglês, não? Para acessar as informações é só usar
get_post_meta( $post->ID, 'my-image-for-post' );
como você já vinha fazendo mesmo.
Para adicionar, editar ou excluir uma imagem você vai precisar pegar o array com get_post_meta, alterar e salvá-lo novamente com update_post_meta 🙂
Ainda não testei o código, tenho que fazer os inputs em jquery.
Mas pensei ser necessario uma sequencia primeiro excluir, depois atualizar e depois adicionar:
add_action( 'save_post', function ( $post_id ) { if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( isset( $_POST['delete_my_image_URL'] ) ) { // imagens selecionadas para deletar $urls_del = $_POST['delete_my_image_URL']; delete_post_meta($post_id, 'my-image-for-post', $urls_del); } if ( isset( $_POST['update_my_image_URL'] ) ) { // imagens selecionadas para deletar $urls_up = $_POST['update_my_image_URL']; $metas_atual = get_post_meta( $post_id, 'my-image-for-post'); update_post_meta( $post_id, 'my-image-for-post', $urls_up, $metas_atual); } if ( isset( $_POST['add_my_image_URL'] ) ) { // imagens para adicionar $urls_add = $_POST['add_my_image_URL']; add_post_meta( $post_id, 'my-image-for-post', $urls_add ); } });
seria assim?
Olhando parece estar certo sim, mas o mais usual não é deixar o usuário selecionar o que deletar, editar ou adicionar e sim tratar tudo isso junto, alterando a presença e valores dos inputs. Explico: ao exibir o formulário haverá uma série de inputs com
name="my_image_URL[]"
. Se o usuário quiser excluir uma imagem, você deve excluir esse input (remover mesmo o elemento do html), se quiser alterar, você deve permiti-lo alterar seuvalue
de alguma forma. Depois, no submit no formulário, você pegará o array de inputs my_image_URL e verificará como ficou, dessa forma seu código fica mais enxuto e fica mais intuitivo para o usuário, não?Pensei assim, com jquery quando o usuario passar o mouse em uma das imagens vai aparecer pra ele dois icones: excluir e alterar, se ele escolher excluir vai sumir a imagem visualmente, e ser criado input hiden delete_my_image_URL e com a url da imagem a ser excluída.
No caso de ele adicionar novas imagens e se arrepender das novas imagens antes de apertar o submit, como vai estar com o
name=add_my_image_URL
(tambem input hiden) pode simplesmente excluir sem criar o input hiden para delete, já que a imagem que seria adicionada e foi excluida antes de enviar não esta no DB nem precisa ser excluida de la.Então @gislef, daria certo, mas seria o caminho mais longo. Você pode manter um array de input hidden como está pensando, mas quando o usuário escolher excluir você simplesmente dá um .remove() no input hidden associado àquela imagem. Quando ele adicionar uma imagem você cria um input novo, se ele excluir, você exclui o input da mesma forma. Assim, quando ele der o submit do formulário os inputs no array refletirão exatamente o que o usuário fez, deu pra entender?
Ah! acredito que entendi,
então basicamente seria se o usuario excluir uso o.remove()
pra remover , assim não vai ter mais o input, se ele adicionar acrescenta input hiden, no caso nem vai precisar do atualizar e deixo somente as opções adicionar e excluir.E na action uso o primeiro codigo sobre add_action que você passou:
add_action( 'save_post', function ( $post_id ) { if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; // Para não fazer nada nos salvamentos automáticos do WP if ( isset( $_POST['my_image_URL'] ) ) { // Só faz alguma coisa se existia o campo no formulário enviado delete_post_meta( $post_id, 'my-image-for-post' ); // Exclui TODOS os valores, assim só ficam os que o usuário enviou $urls = $_POST['my_image_URL']; add_post_meta( $post_id, 'my-image-for-post', $urls ); } });
Feliz!!!!! Finalmente funcionando, mili obrigadas Felipe 😀
Apenas mais uma duvida, sabe como faço para o bootstrap funcionar dentro do metabox na edição da pagina/post?
Coloquei o código do metabox no function.php, não criei um plugin.
Não entendo o motivo, mas quando clico no icone
dashicons-no
para excluir, a ação ocorre corretamente, isso no foreach com dados vindos do banco de dados:<?php foreach ($urls as $url) { ?> <div class="remove_this_image"> <span class="dashicons dashicons-no" style='float: right;'></span> <img src="<?php echo $url;?>" class="img-responsive" /> <input type="hidden" name="my_image_URL[]" value="<?php echo $url;?>"> </div> <?php }; } ?>
mas no jquery ao adicionar as imagens, selecionando pelo gerenciador de arquivos. adiciona corretamente as mesma tags html do código acima:
custom_uploader.on('select', function() { var selection = custom_uploader.state().get('selection'); selection.map( function( attachment ) { attachment = attachment.toJSON(); $("#show").append("<div class='remove_this_image'><span class='dashicons dashicons-no' style='float: right;'></span><img src=" +attachment.url+" class='img-responsive' /><input type='hidden' name='my_image_URL[]' value=" +attachment.url+"></div>"); }); });
para excluir estou fazendo assim:
$('.dashicons-no').click ( function(e){//ao clicar no icone close e.preventDefault(); $(this).closest('.remove_this_image').remove();//remove a div inteira: imagem, input e o próprio ícone });
Só não esta removendo as tags htmls criadas pelo jquery, mesmo estando idênticas as do foreach.
Alguma ideia de como resolver isso?
Sobre o Bootstrap consegui resolver
- Esta resposta foi modificada 7 anos, 9 meses atrás por Gisele.
Oi @gislef, que bom que conseguiu evoluir!!! Fico realmente feliz com isso.
Sobre a sua dúvida, o que acontece é que quando você chama
$('.dashicons-no').click(function( e ) {
o jQuery só associa ao clique dos elementos que já estão presentes no HTML. Para que o jQuery continue aplicando esse comportamento nas divs que você criar depois, você deve usar:$( 'body' ).on( 'click', '.dashicons-no', function( e ) {
Não esqueça de voltar novamente para contar se resolveu e, se for o caso, marcar seu tópico como resolvido. Parabéns pelo progresso!
- O tópico ‘Como salvar dados do metabox com foreach’ está fechado para novas respostas.