0

I have a code that save meta post and show them to the visitors:

<?php if(is_singular( 'manga' ) ){
                        $manga_link=get_post_meta($post->ID,"featured_fields_manga",true);
                        $count_season = get_post_meta($post->ID,"featured_fields_manga",true);
                        if($manga_link){
                            ?>
                            <div class="download-series">
                                <?php
                                foreach( $count_season as $key){
                                    $num_ar[] = $key['season_serie'];
                                }
                                $num_arr = array_unique($num_ar);
                                foreach($num_arr as $numi){
                                    ?>
                                    <div class="down-row-serie">
                                        <?php
                                        foreach( $manga_link as $season){
                                            $meta = $season['season_serie'];
                                            switch($meta){
                                                case $meta === $numi:
                                                    ?>
                                                    <div class="wppper-line">
                                                        <div class="chapright">
                                                            <ul class="meta">
                                                                <?php if(!empty($season['quality_serie'])){?><li><span>name</span><?php echo $season['quality_serie'];?> </li><?php }?>
                                                            </ul>
                                                        </div>
                                                        <div class="chapleft">
                                                            <ul class="dl">
                                                                <a id="<?php echo get_the_ID(); ?>" class="your_class_to_update">save this in meta field</a>
                                                            </ul>
                                                        </div>
                                                    </div>
                                                    <?php
                                                    break;
                                            }
                                        }
                                        ?>
                                    </div>
                                <?php }?>
                            </div>
                            <?php
                        }} ?>

until now every thing is ok. now i want: after a visitor click "save this in meta field", the "name" and one more data ("chap") should save in a new meta key (i know it's better to save in user meta and now i'm just trying to save in post meta). the code is this (this code has issue because after user clicked "save this in meta field" all "name" and "chap" in this post will save in post meta. I want to save only that one i clicked):

function custom_update_post() {
    $post_id = $_POST['post_id'];
    $post_meta_name = get_post_meta($post_id, 'name-manga-en',true);
    $first_link = get_post_meta($post_id,"featured_fields_manga", true);
    if($first_link){
        ?>
        <?php
        foreach( $first_link as $season){
            ?>
        <?php
    $meta = array(
        'chap'          => $post_meta_name,
        'name'          => $season['quality_serie']
    );
    add_post_meta( $post_id, 'my_meta', $meta );
        }}
}
add_action( 'wp_ajax_custom_update_post', 'custom_update_post' );

js code:

jQuery(document).ready( function($) {
    $('.your_class_to_update').on('click', function() {
        var post_id = $(this).attr( 'id' );
        $.ajax({
            type: 'POST',
            url: ajax_object.ajaxurl,
            data: {
                action: 'custom_update_post',
                post_id: post_id
            }
        });
    });
});

I hope that i explained well. to be more clear see this picture: more explanation for example i want to save only "11 تا 20" not "11 تا 20 and 1 تا 10 and 86". what is wrong?

this is more explanation for what Tom J Nowell asked:

at the first code we have a class named "your_class_to_update". when user clicks on "save this in meta field" that has this class, script loads with ajax and recognize the code that is in the functions.

now about meta data: there is a meta_key in the post meta named "featured_fields_manga". this meta_key has meta_value that stores some data in array. sth like this:

quality_serie: 86 linkdown: link1

quality_serie: 120 linkdown: link2

i can echo these data with the first code and show them to user. now i want that when user click on "save this in meta field" (it's beside every multiple data. for example beside 86 and link1 (you can see this in the picture)) only 86 be saved in a new meta_key. note that my first and third code is working fine. the problem is the second code (function that saves this data after user clicked). this wrong code saves all the values with "quality_serie". is it clear now?

10
  • the javascript is missing from your question
    – Tom J Nowell
    Aug 16, 2021 at 0:51
  • there is no problem in js code. I edited the question and added the js. tnks for your reply
    – saeed
    Aug 16, 2021 at 12:43
  • I'm struggling to understand how it knows which meta and its value it needs to save in the AJAX call, only the post ID is being sent. Where are these fields coming from and what is the purpose of this functionality? Can you provide some context behind this? It's very difficult to understand what this is trying to implement. Are you trying to set a particular quality_serie as the single featured quality_serie of that post? This looks like an X Y problem
    – Tom J Nowell
    Aug 16, 2021 at 13:58
  • You just posted your reply as the solution to your question, you need to edit your question to include the information. Now people will think that you've found your solution and no longer need help
    – Tom J Nowell
    Aug 16, 2021 at 15:50
  • I've deleted your answer, can you include the information directly in your question? Remember this isn't a discussion forum. Use the edit link underneath the tags to modify and improve your question. Also, your response was very technical, but provided no background context explaining what you're trying to implement, what does the button actually do from a user perspective? What is the feature that you're trying to implement by doing this?
    – Tom J Nowell
    Aug 16, 2021 at 15:50

1 Answer 1

1

Ok so we have things, and we want to favourite/unfavourite them as done. First, we need 2 functions:

  • saeed_is_favourited( int $post_id, string $thing_to_favourite ) ( where $thing_to_favourite is the thing we're marking as saved/favourited/etc, and $default is the value to return if we don't know yet
  • saeed_set_favourited( int $post_id, string $thing_to_favourite, bool $favourited ) where we set $thing_to_favourite on that post as favourited or not favourited

Then you will need a way to send an AJAX request to call saeed_set_favourited with the requested value.

We will store if it's favourited in user meta using a user meta with a key like this:

saeed_favourite_123_ABC

Where 123 is the post ID, and ABC is the thing we're favouriting/not favouriting. This thing is a string, any string of your choosing. In the examples I give, it is completely arbitrary. It is not the slug of a post or a meta key, or a username. I could use those if I wanted, or I could make them up.


Here is an attempt at implementing saeed_is_favourited

function saeed_is_favourited( int $post_id, string $thing_to_favourite ) : bool {
    $user_id = get_current_user_id();
    $meta_key = 'saeed_favourited_' . $post_id . '_' . $thing_to_favourite;
    $result = get_user_meta( $user_id, $meta_key, true );
    return boolval( $result );
}

Used like this:

if ( saeed_is_favourited( get_the_ID(), 'apples' ) ) {
    echo "you have favourited apples on this post";
} else {
    echo "you have not favourited apples on this post";
}

Here is an attempt at implementing saeed_set_favourited

function saeed_set_favourited( int $post_id, string $thing_to_favourite, bool $favourited ) : void {
    $user_id = get_current_user_id();
    $meta_key = 'saeed_favourited_' . $post_id . '_' . $thing_to_favourite;
    update_user_meta( $user_id, $meta_key, $favourited );
}

Notice that I used update_user_meta, not add_user_meta. add_user_meta can create multiple meta key/value pairs, meta keys are not unique.


Finally, we need a way to set if it has been favourited or not. Here is an old style Admin AJAX handler:

function saeed_ajax_favourite_a_thing() : void {
    $post_id = 0;
    if ( ! empty( $_POST['post_id'] ) {
        $post_id = intval( $_POST['post_id'] );
    } else {
        wp_die( 'a post_id number is needed, none was provided' );
    }

    $thing_to_favourite = '';
    if ( ! empty( $_POST['thing_to_favourite'] ) {
        $thing_to_favourite = $_POST['thing_to_favourite'];
    } else {
        wp_die( 'a thing_to_favourite is needed, none was provided' );
    }

    $favourite = false;
    if ( ! empty( $_POST['favourite'] ) {
        $favourite = boolval( $_POST['favourite'] );
    } else {
        wp_die( 'a favourite is needed, either true or false, none was provided' );
    }
    saeed_set_favourited( $post_id, $thing_to_favourite, $favourite );
}
add_action( 'wp_ajax_saeed_ajax_favourite_a_thing', 'saeed_ajax_favourite_a_thing' );

You would then pass a post ID, a thing_to_favourite representing the thing you want to favourite, and a true/false for wether it is to be favourited or unfavourited.

E.g. this would favourite apple:

        $.ajax({
            type: 'POST',
            url: ajax_object.ajaxurl,
            data: {
                action: 'saeed_ajax_favourite_a_thing',
                post_id: post_id
                thing_to_favourite: 'apple',
                favourite: true
            }
        });

You should consider looking into the more modern REST API endpoints as a cleaner replacement for this AJAX handler.

You can also use saeed_is_favourited to construct your frontend, and the AJAX to toggle the items on/off.

Because it used user meta, the favouriting will work on a per user basis.

You will want to check is_user_logged_in() as this code will not work for logged out users.

Note that none of this code is tested, you may need to make modifications after integrating it into your code

4
  • thanks for your answer. $key shouldn't be static. it should get the $key from post meta "featured_fields_manga" (one of the "quality_serie" that we clicked). the problem is here. I don't know how to distinguish one "quality_serie" with another "quality_serie" in this post. if we can distinguish this, then we can put it in the meta_value and problem will be solved
    – saeed
    Aug 16, 2021 at 19:04
  • I do not understand, what is a quality_serie? You've jumped ahead without explaining any of the context or backstory. I know that you think it's unnecessary, but it is necessary. Your data structure is a mystery, you focus on just this sub-section without explanation. You've narrowed things down too far and made them too specific
    – Tom J Nowell
    Aug 16, 2021 at 19:33
  • As I understand it, you already have a loop for each season: foreach( $manga_link as $season){ and code to display each item, so I do not see the problem? Just use $season['quality_serie'] as the key. The key can literally be anything you want, $key is not referring to a user meta or post meta, it's just a unique identifier
    – Tom J Nowell
    Aug 16, 2021 at 19:38
  • I have renamed it to thing_to_favourite to emphasise that the functions/AJAX are not wanting a meta key. In my examples apple is not a meta key. Your featured_fields_manga contains values. Use the values!
    – Tom J Nowell
    Aug 16, 2021 at 19:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.