Suporte » Temas » Como salvar dados do metabox com foreach

Visualizando 15 respostas - 1 até 15 (de um total de 16)
  • Moderador Felipe Elia

    (@felipeelia)

    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 o my_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 php print_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, 4 meses atrás por Felipe Elia.
    • Esta resposta foi modificada 7 anos, 4 meses atrás por Felipe Elia.
    Criador do tópico Gisele

    (@gislef)

    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ção add_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 🙂

    Moderador Felipe Elia

    (@felipeelia)

    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 );
    		}		
    
    	}
    });
    Criador do tópico Gisele

    (@gislef)

    Antes não estava conseguindo responder ao topico, retirei o codigo JSON e consegui mandar a resposta

    • Esta resposta foi modificada 7 anos, 4 meses atrás por Gisele.
    Criador do tópico Gisele

    (@gislef)

    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, 4 meses atrás por Gisele.
    Moderador Felipe Elia

    (@felipeelia)

    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.

    Moderador Felipe Elia

    (@felipeelia)

    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 🙂

    Criador do tópico Gisele

    (@gislef)

    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?

    Moderador Felipe Elia

    (@felipeelia)

    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 seu value 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?

    Criador do tópico Gisele

    (@gislef)

    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.

    • Esta resposta foi modificada 7 anos, 4 meses atrás por Gisele.
    • Esta resposta foi modificada 7 anos, 4 meses atrás por Gisele.
    Moderador Felipe Elia

    (@felipeelia)

    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?

    Criador do tópico Gisele

    (@gislef)

    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 );		
    
    	}
    });
    • Esta resposta foi modificada 7 anos, 4 meses atrás por Gisele.
    • Esta resposta foi modificada 7 anos, 4 meses atrás por Gisele.
    • Esta resposta foi modificada 7 anos, 4 meses atrás por Gisele.
    Criador do tópico Gisele

    (@gislef)

    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.

    • Esta resposta foi modificada 7 anos, 4 meses atrás por Gisele.
    • Esta resposta foi modificada 7 anos, 4 meses atrás por Gisele.
    Criador do tópico Gisele

    (@gislef)

    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, 4 meses atrás por Gisele.
    Moderador Felipe Elia

    (@felipeelia)

    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!

Visualizando 15 respostas - 1 até 15 (de um total de 16)
  • O tópico ‘Como salvar dados do metabox com foreach’ está fechado para novas respostas.