• codimex

    (@codimex)


    Hi, I’ve following this tutorial successfully, and I’ve been able to put in a calendar my events based in ACF custom fields. The problem is that I have a date picker field and a time picker field for both the start date and time and end date and time fields. I could change the fields for date/time pickers, but unfortunately, I can’t do that, since events are submitted in the frontend by the owner of the website, and the form plugin I’m using does not have a date/time field (thus, I can’t map that with a ACF date/time field).

    So, I’ve tried to tweak your code to combine my ACF start_date_acf, start_time_acf, end_date_acf and end_time_acf fields into a date/time field and this is what I’ve got so far:

    add_filter(
    "piecal_event_query_args",
    function ($args, $atts) {
    $args["meta_query"] = [
    "relation" => "AND",
    [
    "key" => "$key",
    "value" => "",
    "compare" => "!=",
    ],
    ];
    return $args;
    }, 10, 2);

    add_filter("piecal_start_date_meta_key", function ($key) {
    $key = date("Y-m-d\TH:i:s", strtotime(get_field('start_date_acf', $post->ID) . ' ' . get_field('start_time_acf', $post->ID)));
    return $key;
    });

    add_filter("piecal_end_date_meta_key", function ($key) {
    $key = date("Y-m-d\TH:i:s", strtotime(get_field('end_date_acf', $post->ID) . ' ' . get_field('end_time_acf', $post->ID)));
    return $key;
    });

    This doesn’t have the desired effect. I can feel I’m close to the solution, but I need the final touch (needless to say, I’m not an expert developer). Can you help me with that? Thank you for taking the time to read my question.

Viewing 4 replies - 1 through 4 (of 4 total)
  • Plugin Author Jonathan Jernigan

    (@apexws)

    Hey there,

    I consulted CGPT here for help modifying the code and it said that your snippet is close, but required a little tweaking. This suggestion is untested but should work:

    // This filter modifies the query to include only events with a valid start date.
    add_filter(
    "piecal_event_query_args",
    function ($args, $atts) {
    $args["meta_query"] = [
    "relation" => "AND",
    [
    "key" => "start_date_acf", // Change to your actual date meta key
    "value" => "",
    "compare" => "!=",
    ],
    ];

    return $args;
    },
    10,
    2
    );

    // This filter sets the start date using combined date and time fields for the event.
    add_filter("piecal_start_date_meta_key", function ($key) {
    global $post; // Access the current post ID
    $start_date = get_field('start_date_acf', $post->ID);
    $start_time = get_field('start_time_acf', $post->ID);

    if ($start_date && $start_time) {
    // Combine date and time fields into a format compatible with Pie Calendar
    $key = date("Y-m-d\TH:i:s", strtotime("$start_date $start_time"));
    }

    return $key;
    });

    // This filter sets the end date using combined date and time fields for the event.
    add_filter("piecal_end_date_meta_key", function ($key) {
    global $post; // Access the current post ID
    $end_date = get_field('end_date_acf', $post->ID);
    $end_time = get_field('end_time_acf', $post->ID);

    if ($end_date && $end_time) {
    // Combine date and time fields into a format compatible with Pie Calendar
    $key = date("Y-m-d\TH:i:s", strtotime("$end_date $end_time"));
    }

    return $key;
    });

    I asked CGPT for a plain text summary of the differences between your snippet and its suggestion:
    Here’s a plain-text breakdown of the changes made:

    1. Defining the Event Filter:
      • In your original code, the meta_query was looking for an empty or non-existent key but didn’t specify which custom field (ACF field) to check. I updated this part to target the start_date_acf field specifically so that only events with a valid start date will appear.
    2. Combining Date and Time Fields:
      • The original code had separate fields for date and time but didn’t combine them into a single, usable datetime format.
      • I updated the code to:
        • Retrieve the ACF date and time fields separately.
        • Combine them using PHP’s strtotime function to create a single datetime value.
        • Format that datetime into the Y-m-d\TH:i:s format, which Pie Calendar expects to work correctly.
    3. Global $post Variable:
      • The original code didn’t handle the post ID context, so I included global $post to make sure we’re pulling data from the correct post.
      • Using global $post allows the function to work with the current post without directly passing a post ID, but as we discussed, it has some potential risks.
    Thread Starter codimex

    (@codimex)

    Thank you for taking the time to help. I feel we are really close to the solution. This is the furthest I’ve gotten by mixing your answer with my intuition:

    add_filter("piecal_event_query_args", function ($args, $atts) {
    $args["meta_query"] = [
    "relation" => "AND",
    [
    "key" => "start_date_acf",
    "value" => "",
    "compare" => "!=",
    ],
    ];
    return $args;
    }, 10, 2);

    add_filter("piecal_event_start_datetime", function ($start_datetime, $post_id) {
    global $post;
    $start_date = get_field('start_date_acf', $post_id);
    $start_time = get_field('start_time_acf', $post_id);
    if ($start_date && $start_time) {
    $start_datetime = date("Y-m-d\TH:i:s", strtotime("$start_date $start_time"));
    }
    return $start_datetime;
    }, 10, 2);

    add_filter("piecal_event_end_datetime", function ($end_datetime, $post_id) {
    global $post;
    $end_date = get_field('end_date_acf', $post_id);
    $end_time = get_field('end_time_acf', $post_id);
    if ($end_date && $end_time) {
    $end_datetime = date("Y-m-d\TH:i:s", strtotime("$end_date $end_time"));
    }
    return $end_datetime;
    }, 10, 2);

    Now, all the events are shown in the actual current date and time, all piled in the same calendar cell (now’s date and time). If I refresh the page, the date and time of the event in the calendar also updates to match the actual date and time of this very moment. I’ve tried adding and removing global $post; but no success. And after a series of prompts to CGPT, it has come to an almost identical version of your own original code. Any new ideas? Why are the filters ignoring ACF field values? Is it due to a ACF date or time field format? Might this line Y-m-d\TH:i:s be the culprit?

    Thank you again for your willingness to help. I feel we’re really close to the solution!!!

    Thread Starter codimex

    (@codimex)

    Hi again. After burying CGPT with prompts asking for help, it’s stuck in a loop, suggesting once again the same code, which display all events piled up in the same cell (at the present moment, date and time). This is the shortest code I’ve got so far, based on your tutorial code, but unfortunately achieving the same wrong results. The first filter works fine, but the last two filters don’t pull the information from each post correctly:

    add_filter("piecal_event_query_args", function ($args, $atts) {
    $args["meta_query"] = [
    "relation" => "AND",
    [
    "key" => "start_date_acf",
    "value" => "",
    "compare" => "!=",
    ],
    ];
    return $args;
    }, 10, 2);

    add_filter("piecal_start_date_meta_key", function ($key) {
    global $post;
    $key = date("Y-m-d H:i:s", strtotime(get_field('start_date_acf', $post->ID) . ' ' . get_field('start_time_acf', $post->ID)));
    return $key;
    });

    add_filter("piecal_end_date_meta_key", function ($key) {
    global $post;
    $key = date("Y-m-d H:i:s", strtotime(get_field('end_date_acf', $post->ID) . ' ' . get_field('end_time_acf', $post->ID)));
    return $key;
    });

    I wish you can help me with finding directions towards the solution (considering I’m not an expert coder). Thank you!

    Thread Starter codimex

    (@codimex)

    After spending sooo many hours trying to figure it out, I finally came to a solution. Just in case someone faces the same issue. Disclaimer: I’m not an expert coder, and things probably could be done in a better way. Here it goes:

    1) In order to keep a frontend event submitter with four different fields (start_date_acf, start_time_acf, end_date_acf and end_time_acf), first you need to make sure that the ACF format of the fields are as follows:

      • start_date_acf: Y-m-d
      • start_time_acf: H:i:s (H:i also has proven to work for me)
      • end_date_acf: Y-m-d
      • end_time_acf: H:i:s (H:i also has proven to work for me)

      2) Then, I created two extra date/time fields (start_datetime_acf and end_datetime_acf ), both with format Y-m-d H:i:s, to merge the respecitve start date and time fields and end date and time fields.

      3) Then, I added this code to make Pie Calendar fetching start_datetime_acf and end_datetime_acf:

      add_filter("piecal_event_query_args", function ($args, $atts) {
      $args["meta_query"] = [
      "relation" => "AND",
      [
      "key" => "start_date_acf",
      "value" => "",
      "compare" => "!=",
      ],
      ];
      return $args;
      }, 10, 2);

      add_filter("piecal_start_date_meta_key", function ($key) {
      $key = "start_datetime_acf";
      return $key;
      });

      add_filter("piecal_end_date_meta_key", function ($key) {
      $key = "end_datetime_acf";
      return $key;
      });

      4) Then, I added this code, so that every time an event updates in the backend, the start_datetime_acf and end_datetime_acf fields are populated from start_date_acf, start_time_acf, end_date_acf and end_time_acf fields.

      function update_event_datetime( $post_id ) {
      if ( get_post_type($post_id) == 'product' ) {
      if ( wp_is_post_revision( $post_id ) )
      return;
      global $post;
      $start_datetime = (get_field('start_date_acf') . ' ' . get_field('start_time_acf'));
      update_post_meta($post_id, 'start_datetime_acf', $start_datetime);
      $end_datetime = (get_field('end_date_acf') . ' ' . get_field('end_time_acf'));
      update_post_meta($post_id, 'end_datetime_acf', $end_datetime);
      }
      }
      add_action( 'save_post', 'update_event_datetime', 10, 2 );

      5) Then, once the event is submitted from the frontend, just update it in the backend, and the two fields will be correctly merged and the calendar properly populated.

      Probably not the most optimal solution, but it’s tested and works. The issue is that if any of the events doesn’t have start_datetime_acf and end_datetime_acf field values populated, you’l get a fatal error (nothing too serious if you add those codes via Code Snippets plugin).

      Thank you, and feel free to close this ticket, unless you come up to a better idea.

    Viewing 4 replies - 1 through 4 (of 4 total)
    • You must be logged in to reply to this topic.