Wordpress - Validating custom fields through backend - php

First off, I'm using advanced custom fields plugin, and I'm using a repeater. I have a custom post type that triggers when pressing "publish" when creating a new post, what it does, is that it adds a row to my repeater field.
Basiclly it takes the info from other fields and comes up with the proper information that the row created must have by making some calculations.
this is my function:
function investment_save($post_id)
{
$post = get_post();
$poststat = get_post_status($post_id);
$fecha = current_time(d-M-Y);
$fecha2 = "Inversión ".$fecha;
if($poststat == "publish" && !have_rows('datos_especificos'))
{
remove_action( 'save_post', 'investment_save' );
$my_post = array(
'ID' => $post_id,
'post_title' => $fecha2,
);
wp_update_post( $my_post );
$fech = get_field('fecha_de_inicio_de_la_inversion');
$sald = get_field('monto_de_la_inversion');
$tasa = get_field('tasa_de_interes');
$cap = get_field('uso_de_interes');
$elsald0 = $tasa/12*0.01*$sald;
$elsald=number_format($elsald0,2);
if($cap=="pagar")
{
$cap2=$elsald;
$cantr=0;
}else{
$cap2=0;
$cantr=$elsald;
}
$sf = $sald+$cantr;
$field_key = "datos_especificos";
$value = get_field($field_key, $post_id);
$value[] = array("fecha" => $fech,
"saldo" => $sald,
"inversion_en_el_periodo" => "0",
"interes_causado_en_el_periodo" => $elsald,
"cantidad_pagada" => $cap2,
"cantidad_reinvertida" => $cantr,
"saldo_final" => $sf);
update_field( $field_key, $value, $post_id );
}
}
add_action( 'save_post', 'investment_save' );
This works properly, however, I have a new task in which everytime I press update, I must check if $cr+$cp equal $icelp in all rows, if they not, i must adjust the values from them, so this is the kind of code I'd like to use:
$sum = $cp + $cr;
if($sum>$icelp)
{
$dif=$sum-$icelp;
if($cp>=$cr)
{
$cp=$cp-$dif;
}else
{
$cr=$cr-$dif;
}
}
if($sum<$icelp)
{
$dif=$icelp-$sum;
if($cp>=$cr)
{
$cr=$cr+$dif;
}else
{
$cp=$cp+$dif;
}
}
Ive tried using an"else", also using an "if", but I just can't make it work. Please Someone help me I've been breaking my head for days

Related

How to retrieve at Frontend the values of WordPress custom fields created for Media Library Images (Full example included)

I have 2 different working methods at functions.php for backend. Each method below has 2 hooks; 1 to display the new custom field & another hook to save\update the values:
Method 1:
function media_hacks_attachment_field_to_edit( $form_fields, $post ){
// https://codex.wordpress.org/Function_Reference/wp_get_attachment_metadata
$media_author = get_post_meta( $post->ID, 'media_author', true );
$form_fields['media_author'] = array(
'value' => $media_author ? $media_author : '',
'label' => __( 'Author' )
);
return $form_fields;
}
add_filter( 'attachment_fields_to_edit', 'media_hacks_attachment_field_to_edit', null, 2 );
//Saving value on Update (method 1)
function media_hacks_edit_attachment( $attachment_id ){
if ( isset( $_REQUEST['attachments'][$attachment_id]['media_author'] ) ) {
$media_author = $_REQUEST['attachments'][$attachment_id]['media_author'];
update_post_meta( $attachment_id, 'media_author', $media_author );
}
}
add_action( 'edit_attachment', 'media_hacks_edit_attachment' );
Method 2:
function my_image_attachment_fields_to_edit($form_fields, $post) {
// $form_fields is a special array of fields to include in the attachment form
// $post is the attachment record in the database
// $post->post_type == 'attachment'
// (attachments are treated as posts in Wordpress)
// add our custom field to the $form_fields array
// input type="text" name/id="attachments[$attachment->ID][custom1]"
$form_fields["custom1"] = array(
"label" => __("Custom Text Field"),
"input" => "text", // this is default if "input" is omitted
"value" => get_post_meta($post->ID, "_custom1", true)
);
// if you will be adding error messages for your field,
// then in order to not overwrite them, as they are pre-attached
// to this array, you would need to set the field up like this:
$form_fields["custom1"]["label"] = __("Custom Text Field");
$form_fields["custom1"]["input"] = "text";
$form_fields["custom1"]["value"] = get_post_meta($post->ID, "_custom1", true);
return $form_fields;
}
// attach our function to the correct hook
add_filter("attachment_fields_to_edit", "my_image_attachment_fields_to_edit", null, 2);
//Saving value on Update (method 2)
function my_image_attachment_fields_to_save($post, $attachment) {
// $attachment part of the form $_POST ($_POST[attachments][postID])
// $post attachments wp post array - will be saved after returned
// $post['post_type'] == 'attachment'
if( isset($attachment['custom1']) ){
// update_post_meta(postID, meta_key, meta_value);
update_post_meta($post['ID'], '_custom1', $attachment['custom1']);
}
return $post;
}
add_filter("attachment_fields_to_save", "my_image_attachment_fields_to_save", null, 2);
Here's the good result at backend Media Library (Custom Text Field & Author):
This was it for the Backend dashboard.
My question is for the Frontend:
Now how can I retrieve & display values of these 2 custom fields at the FRONTEND?
Here's my failed try at a template php page:
<tr id='MySpecialRow'>
<td colspan='2' style='background:#000;color:#fff;'>
<?php
$args = array('cat' => 8);
$query = new WP_Query($args);
if ($query->have_posts()) {
// some code here if you want.
while ($query->have_posts()) {
$query->the_post();
$untitled_meta = rwmb_meta('image_advanced_8hswqfsoqai', '', get_the_ID());
foreach ($untitled_meta as $image) {
$media_author = get_post_meta( get_the_ID(), 'media_author', true );
echo get_the_ID();//correctly prints post id
echo $media_author;//prints nothing :(
}
}
}
?>
</td>
</tr>
Small notes:
get_the_ID() does print the post id, but $media_author has no value :(
I'm doing a WordPress posts query loop because the gallery containing the custom fields exists in a Post. In other words I don't have the post Id since I'm at a Page template.
The array you got has the image post object ID as the array keys, so you need to use the extended foreach syntax to get access to the key as well.
foreach ($untitled_meta as $id => $image) {
$media_author = get_post_meta( $id, 'media_author', true );
Normally when looping over array data you rather seldom need access to the key as well, but when you do, PHP offers the $key => $value syntax to get access to the key as well, https://www.php.net/manual/en/control-structures.foreach.php

PHP foreach update custom field

I use ACF Pro google maps.
The Plugin stores the map data in an array. So far so good.
Now, I like to run through the array and directly store the date in new custom fields.
This works, but I like to give the fields my own name, not the names from the ARRAY (lat & lng).
Can anyone explain how I can use my own names for the custom fields spot_lat & spot_lng?
function my_copy_date_filter($post_id)
{
$post_type = get_post_type($post_id);
if ($post_type != 'spot') {
return;
}
$date = get_field('spot_location', $post_id);
if ($date) {
$lat_lng = [];
foreach (array('lat', 'lng') as $i => $k) {
if (isset($date[$k])) {
update_post_meta($post_id, $k, $date[$k]);
}
}
}
}
add_filter('acf/save_post', 'my_copy_date_filter', 20);
Thanks for any suggestion,
Denis
Create 2 new acf fields named spot_lat and spot_lng
Then try this code
function my_copy_date_filter($post_id) {
$post_type = get_post_type($post_id);
if ($post_type != 'spot') {
return;
}
$date = get_field('spot_location', $post_id);
if( $date ) {
update_field( 'spot_lat', $date[ 'lat' ], $post_id );
update_field( 'spot_lng', $date[ 'lng' ], $post_id );
}
}
add_filter('acf/save_post', 'my_copy_date_filter', 20);

Wordpress update data from api

I have a plugin to create posts with data from an API. I have to check the state of the data on the api every time, if there is a change, it will update the posts and acf fields. I have a post title check so as not to duplicate posts. But how can I check posts correctly so that I can update acf fields every time if there is new data and not duplicate posts?
if( isset( $_POST['enable'] ) ) {
// JOB API
$url='https://api.com/test/';
$result = file_get_contents( $url );
$result_data = json_decode( $result );
foreach ($result_data as $job) {
$ref_code = $job->RefCode;
$post_title = $job->JobTitle;
$post_exists = post_exists( $post_title );
$job_id = $job->JobId;
$job_date = date('Y-m-d h:i:s', strtotime($job->Published));
if (!get_page_by_title($post_title, 'OBJECT', 'jobs') ) {
$data = array(
'post_type' => 'jobs',
'post_title' => $post_title,
'post_status' => 'publish',
'post_date' => $job_date,
'post_date_gmt' => $job_date
);
$post_id = wp_insert_post( $data );
wp_set_object_terms( $post_id, 'regulare-job', 'jobscat', 'post_tag' );
// Job DATA API
$job_api_url ='https://api.com/test/' . $ref_code;
$job_api_result = file_get_contents( $job_api_url );
$result_data = json_decode( $job_api_result );
//Update ACF fields
update_field( 'location', $job->RegionCity, $post_id );
update_field( 'job_intro', $result_data->Intro, $post_id );
update_field( 'job_offer', $result_data->data[0]->Text, $post_id );
update_field( 'job_requirement', $result_data->data[1]->Text, $post_id );
update_field( 'text_c2', $result_data->data[2]->Text, $post_id );
update_field( 'single_job_ref_code', $result_data->RefCode, $post_id );
}
}
}
I customized your code with some parts how i achieved it for myself.
It might need some customization. (See comments within code for additional info)
What I do:
1.) check if post is already existing based on your title (and get its id)
2.) if it is already existing => update data (ACF-Fields)
3.) if it is not existing => create new post and update meta data (ACF-Fields)
To fill the acf-fields I use a custom function based on ACF-Field-Keys.
You can also create a custom cron job to run this function every (minute, hour...)
function api_fetcher_function(){
if( isset( $_POST['enable'] ) ) {
// JOB API
$url='https://api.com/test/';
$result = file_get_contents( $url );
$result_data = json_decode( $result );
foreach ($result_data as $job) {
$ref_code = $job->RefCode;
$post_title = sanitize_title($job->JobTitle);
/* check if CPT-Post with given slug already exists */
$existing_post = get_page_by_path($post_title,'OBJECT', 'jobs');
$job_id = $job->JobId;
$job_date = date('Y-m-d h:i:s', strtotime($job->Published));
/* if post doesnt exist create a new one */
if($existing_post === null){
$inserted_post = wp_insert_post([
'post_name' => $post_title,
'post_title' => $post_title,
'post_type' => 'jobs',
'post_status' => 'publish',
'post_date' => $job_date,
'post_date_gmt' => $job_date
]);
/* continue after successful insert (single item) */
/* special error handling can be placed within if */
if( is_wp_error($inserted_post)){
continue;
}
/* Update Meta Info of new post */
updateJobsMeta($job, $inserted_post);
}else{
$existing_job_id = $existing_post->ID;
/*you can add some additional check if you have some timestamps within your api and ACF */
/*$existing_jobs_timestamp might not be needed => based on your available data*/
$existing_jobs_timestamp = get_field('updated_at', $existing_job_id);
/*if you have some timestamps to use*/
if($job->Published >= $existing_jobs_timestamp){
updateJobsMeta($job ,$existing_job_id);
}
/*if you dont have some timestamps to use just remove the if around the update function and the $existing_jobs_timestamp*/
}
}
}
}
function updateJobsMeta($job ,$id){
$ref_code = $job->RefCode;
$job_api_url ='https://api.com/test/' . $ref_code;
$job_api_result = file_get_contents( $job_api_url );
$result_data = json_decode( $job_api_result );
/* Update Fillable list based on your needs => keys can be found within your acf group in wp-backend (might be hidden by default) */
$fillable = [
'field_5f312082435dd' => $job->JobId,
'field_5f312095435de' => $job->JobTitle,
'acf_field_key....' => $job->Published
...
];
/* updates fields based on acf-key */
foreach($fillable as $key => $name){
update_field( $key, $name, $id);
}
}

Wordpress Snippet - Word synonymous replace in title when status change from draft to publish

I am trying to create wordpress snippet that run when post change status from 'draft' to 'publish'. When post change status, my snippet found words in title a replace them with synonymous. I found wordpress action 'draft_to_publish'. But i don't know how get wordpress title to string and how to save post with new title and slug.
Here is a idea
[https://pastebin.com/CBYAZRfr]
Any ideas? :(
Can you check with your code inside this hook
// define the draft_to_publish callback
function action_draft_to_publish( $array ) {
// make action magic happen here...
};
// add the action
add_action( 'draft_to_publish', 'action_draft_to_publish', 10, 1 );
Like this you can do it
function action_post_draft_to_publish($post){
if( $post->post_type == 'post' ) : //Check Post Type, You may update it accordingly for your need
$title = $post->post_title;
// Convert title to lowercase
$lowTitle = mb_convert_case($title, MB_CASE_LOWER, "UTF-8");
// Synonymous for replace
$synonymous = array(
'beautiful' => 'perect',
'vehicle' => 'car',
);
// Loop with word check and replace
foreach($synonymous as $key => $value) {
if( is_string($key) ) {
$stringKey = $key;
// Replace in title
if (strpos($lowTitle, $stringKey) !== false) {
$lowTitle = str_replace($stringKey, $value, $lowTitle);
}
}
}
wp_update_post( array(
'ID' => $post->ID,
'post_title' => $lowTitle //Use Your Updated Title Which You Want to Use
) );
endif; //Endif
}
add_action('draft_to_publish', 'action_post_draft_to_publish', 20);
You can use this code snippet:
function draft_to_publish( $post ) {
$title = $post['post_title'];
$lowTitle = mb_convert_case($title, MB_CASE_LOWER, "UTF-8");
// Synonymous for replace
$synonymous = array(
'beautiful' => 'perect',
'vehicle' => 'car',
);
// Loop with word check and replace
foreach ($synonymous as $key => $value) {
if(is_string($key)) {
$stringKey = $key;
// Replace in title
if (strpos($lowTitle, $stringKey) !== false) {
$lowTitle = str_replace($stringKey, $value, $lowTitle);
}
}
}
// Update post
$my_post = array(
'ID' => $post['ID'],
'post_title' => $lowTitle, // new title
);
// Update the post into the database
wp_update_post( $my_post );
}
add_action( 'draft_to_publish', 'draft_to_publish' );

Custom Fields not showing in custom post type post

I have a custom post type named "Designer" Each posts will be using different unique Advanced Custom Fields as each posts has unique templates.With the below code I am able to give rules for each posts in Designer post type and save but the custom fields are not displaying on post edit pages on backend.
Normally this code should ork but no idea what happend to the code
Please Help.
add_filter('acf/location/rule_types', 'acf_location_rules_types');
function acf_location_rules_types( $choices )
{
$choices['Custom Post types']['cpt_parent'] = 'Custom post type parent';
return $choices;
}
add_filter('acf/location/rule_values/cpt_parent', 'acf_location_rules_values_cpt_parent');
function acf_location_rules_values_cpt_parent( $choices )
{
$args = array(
'hierarchical' => true,
'_builtin' => false
);
$posttypes = get_post_types( $args );
if( $posttypes )
{
foreach( $posttypes as $posttype ):
if( $posttype != 'acf' ):
$args = array(
'post_type' => 'designer',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$customposts = get_posts( $args );
if ( $customposts ) {
foreach( $customposts as $custompost ){
$choices[ $custompost->ID] = $custompost->post_title;
}
}
endif;
endforeach;
}
return $choices;
}
//MATCH THE RULE
add_filter('acf/location/rule_match/cpt_parent', 'acf_location_rules_match_cpt_parent', 10, 3);
function acf_location_rules_match_cpt_parent( $match, $rule, $options )
{
global $post;
$selected_post = (int) $rule['value'];
// post parent
$post_parent = $post->post_parent;
if( $options['page_parent'] ) {
$post_parent = $options['page_parent'];
}
if ($rule['operator'] == "=="){
$match = ( $post_parent == $selected_post );
}
elseif ($rule['operator'] != "!="){
$match = ( $post_parent != $selected_post );
}
return $match;
}
Your Artist Collection field group is set to only appear on one post, the post Designer Post 1 which is a Designer Post type.
I don't understand what all the code is for? Just create a different field group for each post that needs a different field group and a separate rule for each.
Ok sorry I understand the issue now and I have recreated the issue on my local install.
On the line of code below you are looking for the post_parent but I think you should be looking for the ID.
I changed this:
$post_parent = $post->post_parent;
to this:
$post_parent = $post->ID;
and it's working for me.
If I understand your problem correctly, in wp-admin post edit page click on screen options on the upper right corner. In the menu that appears make sure the Custom fields is selected. This will make the custom fields appear for edit.

Categories