Hiya @topy
In short, yes everything you describe is doable.
1) You can create an ACF form and then embed this form onto a page and tell the form that it needs to create a new page, post or custom post type. You can also wrap this code into a check to see if the user is logged in so that only logged in users can access this form.
2) You can set the form to always create ‘draft’ posts by default. Or alternatively, you can make it a changeable field and combine it with a hook to actually make the post draft or published. I’ve actually recently done this myself. You would have a field in your ACF form called ‘status’. Then you create a hook that is triggered when this form is submitted. It would get the value of that field, and use it to set the status of the post.
3) The same code that renders the form onto the page from item 1 above, can be used but with a different parameter that edits a post instead of creating a new one.
For example, on your page where you have the form embedded, right at the top you’d have:
/**
* Is something being edited?
* Is the user trying to do this, the author of the post being edited, or an admin?
* If not, redirect back to home
*/
if (isset($_GET['edit'])) {
// get the post being edited
$thispost = get_post($_GET['edit']);
if (USERID == $thispost->post_author || is_administator()) {
$new_post = $_GET['edit'];
} else {
header('Location: '.get_bloginfo('home'));
exit;
}
} else {
$new_post = 'new_post';
}
So if your post create page is website.com/new-post
then to edit a post using that same form, you’d have website.com/new-post?edit=23
and then you’d be editing post 23.
And to actually embed the form that uses the logic above, you’d have:
$formoptions = array(
'post_title' => true,
'post_content' => false,
'post_id' => $new_post,
'field_groups' => array(256),
'submit_value' => 'Publish',
'return' => get_permalink(142),
'uploader' => 'wp'
);
acf_form($formoptions);
Hope this answers your questions and helps you confirm the purchase of ACF. It definitely is an incredible piece of software and worth absolutely every penny 🙂
FYI: Resolved this… Turns out it had to do with the front-end login form. The live site was on SSL and my dev site was not.
As such, $user_signon = wp_signon( $info, false );
was at the root of the problem. The false
value was saying that the cookie mustn’t be secure, which because the site WAS on SSL, was not storing the cookie correctly and thus not allowing the upload to happen.
This is quite an old post, but I had to do something similar here and I did it in a slightly different way to the solution above so figured I’d share:
In my scenario, the user uploads images (which are correctly assigned a post_parent), and a couple PDF posts (which weren’t being correctly assigned).
function attachment_change_parent($aid,$pid) {
$update_attachment_post = array(
'ID' => $aid,
'post_parent' => $pid
);
wp_update_post($update_attachment_post);
}
Instead of doing a SQL query, I just used the native wp_update_post
function to update the attachment’s post_parent to be the ID of the newly created post.
Then my PDF field was set to return an array, not a post ID. So in my pre_save_post
function, I had to get that ID slightly differently:
attachment_change_parent($_POST['acf']['field_58a18e2988392'][0], $post_id);
…where you’d obviously just update that field key to be the key of your upload field.
Works a dream. Thanks!
Ping 🙂
And on a similar topic, being able to update the marker icon used etc would be useful….
So all-in-all, some clues on how to edit the map options as a whole, for the front-end form.
Thanks 🙂
Ah ok, so I’m essentially creating the new post, and then updating it’s status etc.
Got it tx.
Will give that a go.
@hube2 I tried the above suggestion but post_status
is not being set correctly – it still sets the post as published.
function my_pre_save_post( $post_id ) {
// check if this is to be a new post
if( $post_id != 'new_post' ) {
return $post_id;
}
// Create a new post
$post = array(
'post_status' => $_POST['acf']['field_58aa9af6e90cd'],
);
// insert the post
$post_id = wp_insert_post( $post );
// return the new ID
return $post_id;
}
add_filter('acf/pre_save_post' , 'my_pre_save_post', 10, 1 );
In my case, the field field_58aa9af6e90cd returns either ‘draft’ or ‘publish’
Am I missing something?
Genius @hube2!
Thanks for the point in the right direction, I’ll give this a go.
Side question: When putting unique data into a filter like this, does all the other information from the form – fields, content, title etc – still get set, in _addition_ to whatever I specify/override in my filter?
any reason you couldn’t just use a ‘text’ field and change it to a URL field when your testing is done?
Hi @jakeward – is this an ACF question, or are you more asking how to create a shortcode that returns the current page title?
hi @exalted
I think the problem lies with 'post_status' => 'post'
Your post status should be publish
. post
isn’t a valid option for post_status, so this is why it’s defaulting to a draft post.
Answering my own question:
// puts the scripts + styles into admin
add_action('admin_head', 'ggh_add_my_tc_button');
add_action('admin_enqueue_scripts', 'ggh_button_css');
// puts the scripts + styles into front-end
add_action('wp_print_scripts', 'ggh_add_my_tc_button');
add_action('wp_print_styles', 'ggh_button_css');
Hmm… Well I was passing an array (the same user array that it stores (well that it seemed to store)) and it wasn’t saving… it was saving the user ID 1 to every field it updated.
So not sure about it working with arrays…
But I’ll try tomorrow with a fresh mind to store just the user ID array and see what happens…
Will update.
Thanks!
Ah really? Thanks @hube2
So in order to save data back into that field using update_field
, I’d just pass an array of ID’s (not entire user objects) into the field?
If I’m understanding you correctly, I would do this:
$post_object = array_reverse(get_field('relation'));
$post_object[0]
will now be the last item in that array, so you can then
<div class="titre-soustitre">
<div class="menu-content" data-id="id-<?php echo $post_object[0]['id']; ?>">
<p class="demo bis"><span class="sub"> </span></p>
<a href="#" class="expander"><h1><p class="demo title"><?php echo $post_object[0]['title'] ?></p></h1></a>
<p class="demo bis"><span class="sub"><?php echo $post_object[0]['subhead']; ?></span></p>
</div>
</div>
Ok, I’ve been hacking away and I’ve got the updating of the arrays working perfectly, but it’s not saving data correctly – I’m seeing that the data is serialised, so other than saving a new array, I’m not sure how this should be done?
// retrieved variables from Ajax request
$user = $_REQUEST['user'];
$decision = $_REQUEST['decision'];
$decision_id = $_REQUEST['decision_id'];
// get current decision info
$this_decision = get_field('decision_makers', $decision_id);
// echo '<pre>';print_r(array_search($user, array_column($this_decision, 'ID')));echo '</pre>';;
// store the changed user in a var
$moved_user = $this_decision[array_search($user, array_column($this_decision, 'ID'))];
// echo '<pre>';print_r($moved_user);echo '</pre>';
// remove user from decision_makers
unset($this_decision[array_search($user, array_column($this_decision, 'ID'))]);
echo 'new updated decision';
echo '<pre>';print_r($this_decision);echo '</pre>';
update_field('field_575e67c05fc55', $this_decision, $decision_id);
// add user to either decision_yes or decision_no
switch ($decision) {
case 'yes' :
$yes_users = get_field('decision_yes', $decision_id);
array_push($yes_users, $moved_user);
update_field('field_575fee49f5980', $yes_users, $decision_id);
echo 'new yes users';
echo '<pre>';print_r($yes_users);echo '</pre>';
break;
case 'no' :
$no_users = get_field('decision_yes', $decision_id);
array_push($no_users, $moved_user);
update_field('field_575fee6bf5981', $no_users, $decision_id);
echo 'new no users';
echo '<pre>';print_r($no_users);echo '</pre>';
break;
}
It’s working perfectly in that the last user – the gryphon avatar which is me, WAS a part of the first array, but on running this function, it moved me from the ‘new updated decision’ array, into the ‘new yes users’ array…
Perfect..
But on trying to save these updated arrays into ACF, it’s borking out:
update_field('field_575fee49f5980', $yes_users, $decision_id);
Do I need to handle the serialisation?
just a follow-up thought… I guess i can remove the user by finding the ID in the main array and then removing that item…
but still not sure how to programmatically add a user to one of the other fields, considering how different the user objects are?
Thanks John.
Appreciate the help either way 🙂
for what it’s worth, acf-input.js:9202:
// create new li
var $li = $([
'<li data-id="' + term.term_id + '">',
'<input id="tax-check-' + term.term_id + '" type="' + type + '" value="' + term.term_id + '" name="' + name + '" /> ',
'<label for="tax-check-' + term.term_id + '">' + term.term_label + '</label>',
'</li>'
].join(''));
… that ‘fixes’ the problem for me and now works as expected.
Do you think this change would be done in the core? As previously mentioned, neither of the 3 ways is incorrect by any means. It’s just that the current way doesn’t allow much styling control.
Ideally it should be input, then label.
thanks @hube2
the css method I use is widely accepted and used to create this type of effect… In essence: the input is hidden; the label after the input is styled with a :before to create a ‘fake’ checkbox. then using the sibling CSS method, I can style the label differently when the input is checked/selected:
# normal state
label:before {
content: ' ';
width:15px;
height: 15px;
background:red;
display:block;
float:left;
}
# checked state
input[type=checkbox]:checked + label:before {
background:blue;
}
Simple example, but you get the idea. You can see the effect it has in the image in my first post.
With the input being nested inside the label, this method isn’t possible.
According to W3 spec, label+input or input+label or label>input are all fine. But the first 2 options definitely give more control to developers + designers to style the inputs better with CSS methods.
Side note: I’m assuming you nest inside the label so that the label is clickable to select the input, but using for and id on the label + input would achieve the same result.
Aaaah, you biscuit 🙂
Sorted, thanks very much! Had to add a couple lines to update the user’s cookie so the password change doesn’t log them out immediately.
Here’s the final function that’s working for me:
add_filter('acf/pre_save_post', 'my_update_password');
function my_update_password($post_id) {
if (substr($post_id, 0 , 5) != 'user_') {
// not a user
return $post_id;
}
$new_password = $_POST['acf']['field_55c0cfff1d979']; // update this
$who = str_replace('user_', '', $post_id);
wp_set_password( $new_password, $who );
wp_clear_auth_cookie();
wp_set_current_user ( $who );
wp_set_auth_cookie ( $who );
}
Sorry for the delay in getting back to this…
One question I have, perhaps because I’m not understanding _quite_ how this works, is how to I actually fetch the saved value of that custom field.
IE I have a profile form where the user will type in a password.
Then I have the above function you suggested in my functions.php and I’m using a wp_mail() function to test what its doing/returning…
wp_mail( '[email protected]', 'test', $post_id.' / '.get_field('user_password', $post_id));
IE this is where I’d have the wp_set_password() function.
What I’m getting from the above is
user_1 /
get_field('user_password', $post_id)
isn’t returning anything.
So how do I actually get the value of that field?
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.