Trouble getting file url of file attachment in cloneable group
- This topic has 21 replies, 3 voices, and was last updated 4 years, 12 months ago by
sgtscience.
-
AuthorPosts
-
March 17, 2020 at 11:41 PM #18563
sgtscience
ParticipantHi I am trying to make an attached files drop down button for WooCommerce Products. Everything is working fine but I am having trouble getting the file url to place in a link. Here are my registered fields:
add_filter( 'rwmb_meta_boxes', 'prefix_register_file_attachments' ); function prefix_register_file_attachments( $meta_boxes ) { $meta_boxes[] = array( 'id' => 'File_Attachments', 'title' => esc_html__( 'File Attachments' ), 'post_types' => array( 'product' ), 'context' => 'advanced', 'priority' => 'default', 'autosave' => 'true', 'fields' => array( array( 'id' => 'file_attachments', 'type' => 'group', 'group_title' => 'Attachment {#}', 'collapsible' => true, 'save_state' => true, 'clone' => true, 'sort_clone' => true, 'fields' => array( array( 'id' => 'file_name', 'type' => 'text', 'name' => 'File Name', ), array( 'id' => 'attachment', 'type' => 'file_advanced', 'name' => esc_html__( 'Attach File' ), 'desc' => esc_html__( 'Upload your pdf files to show on single product page' ), 'force_delete' => false, ), ), ), ), ); return $meta_boxes; }
These work fine in the backend. Here is my code to display the results:
add_action( 'woocommerce_after_add_to_cart_button', 'product_download_button', 5 ); function product_download_button() { ?> <div class="dropdown"> <button class="product-downloads-button" onclick="return false;">DOWNLOADS <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <?php $file_attachments = rwmb_meta( 'file_attachments' ); if ( ! empty( $file_attachments ) ) { foreach ( $file_attachments as $file_attachment ) { $file_name = isset( $file_attachment['file_name'] ) ? $file_attachment['file_name'] : ''; $file_info = get_attached_file( $file_attachment['attachment'] ); echo '<a href="' . $file_info['url'] . '" target="_blank" rel="noopener noreferrer">' . $file_name . '</a>'; } } ?> </div> </div> <?php }
The $file_name returns just fine but when I turned on WP_DEBUG it returns:
Notice: Undefined index: attachment
for this line:
$file_info = get_attached_file( $file_attachment['attachment'] );
Could you please advise?
March 17, 2020 at 11:51 PM #18564sgtscience
Participantsorry here is the code:
add_filter( 'rwmb_meta_boxes', 'prefix_register_file_attachments' ); function prefix_register_file_attachments( $meta_boxes ) { $meta_boxes[] = array( 'id' => 'File_Attachments', 'title' => esc_html__( 'File Attachments' ), 'post_types' => array( 'product' ), 'context' => 'advanced', 'priority' => 'default', 'autosave' => 'true', 'fields' => array( array( 'id' => 'file_attachments', 'type' => 'group', 'group_title' => 'Attachment {#}', 'collapsible' => true, 'save_state' => true, 'clone' => true, 'sort_clone' => true, 'fields' => array( array( 'id' => 'file_name', 'type' => 'text', 'name' => 'File Name', ), array( 'id' => 'attachment', 'type' => 'file_advanced', 'name' => esc_html__( 'Attach File' ), 'desc' => esc_html__( 'Upload your pdf files to show on single product page' ), 'force_delete' => false, ), ), ), ), ); return $meta_boxes; }
add_action( 'woocommerce_after_add_to_cart_button', 'product_download_button', 5 ); function product_download_button() { ?> <div class="dropdown"> <button class="product-downloads-button nectar-button large regular accent-color regular-button" onclick="return false;">DOWNLOADS <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <?php $file_attachments = rwmb_meta( 'file_attachments' ); if ( ! empty( $file_attachments ) ) { foreach ( $file_attachments as $file_attachment ) { $file_name = isset( $file_attachment['file_name'] ) ? $file_attachment['file_name'] : ''; $file_info = get_attached_file( $file_attachment[‘attachment’] ); echo '<a href="' . $file_info['url'] . '" target="_blank">' . $file_name . '</a>'; } } ?> </div> </div> <?php }
March 18, 2020 at 2:35 PM #18568Anh Tran
KeymasterHi, you need to check if the file is uploaded in your group, like this:
if ( isset( $file_attachment['attachment'] ) ) { $file_info = get_attached_file( $file_attachment[‘attachment’] ); echo ... }
March 18, 2020 at 9:54 PM #18581sgtscience
ParticipantHi thanks for the response. The if statement is a nice touch. I tried that out and now I am not getting a php error, but the url is still not returning. Here is the updated code:
add_action( 'woocommerce_after_add_to_cart_button', 'product_download_button', 5 ); function product_download_button() { ?> <div class="dropdown"> <button class="product-downloads-button nectar-button large regular accent-color regular-button" onclick="return false;">DOWNLOADS <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <?php $file_attachments = rwmb_meta( 'file_attachments' ); if ( ! empty( $file_attachments ) ) { foreach ( $file_attachments as $file_attachment ) { $file_name = isset( $file_attachment['file_name'] ) ? $file_attachment['file_name'] : ''; if ( isset( $file_attachment['attachment'] ) ) { $file_info = get_attached_file( $file_attachment['attachment'] ); echo '<a href="' . $file_info['url'] . '" target="_blank">' . $file_name . '</a>'; } } } ?> </div> </div> <?php }
and here is what the resulting link is on the frontend:
<a href="" target="_blank" rel="noopener noreferrer">Spec Sheet</a>
When Iecho $file_info;
nothing is returned so I'm guessing$file_info = get_attached_file( $file_attachment['attachment'] );
is not actually retrieving anything for some reason...March 20, 2020 at 3:04 PM #18599Anh Tran
KeymasterHi,
The function you use
get_attached_file
is not correct. It returns the file path instead of array, see the docs.To get the file URL, you can use
wp_get_attachment_url
file.if ( isset( $file_attachment['attachment'] ) ) { $file_url = wp_get_attachment_url( $file_attachment['attachment'] ); echo '<a href="' . $file_url . '" target="_blank">' . $file_name . '</a>'; }
March 20, 2020 at 9:23 PM #18614sgtscience
ParticipantHi Thanks again, unfortunately this is still not returning anything for
$file_url
.echo $file_url;
also returns nothing, but it passes the if loop and outputs the html and the file name fine, so it does know that there is an attachment, it just can't get any info from it. Even ifget_attached_file()
was the wrong use case in the previous example, it still should have returned a value, but it didn't, correct?March 21, 2020 at 9:57 AM #18623Anh Tran
KeymasterIf it outputs nothing, probably the file is already deleted from the WordPress admin (maybe someone has deleted the file in the Media Library). If that's the case, you can make a better check with this:
if ( isset( $file_attachment['attachment'] ) && get_attached_file( $file_attachment['attachment'] ) ) { $file_url = wp_get_attachment_url( $file_attachment['attachment'] ); echo '<a href="' . $file_url . '" target="_blank">' . $file_name . '</a>'; }
March 21, 2020 at 11:08 AM #18624sgtscience
ParticipantUnfortunately that is not working either. When I tried that nothing shows up in the dropdown. The file is attached and it exists in the media library. I tried removing it and re-attaching it also.
March 22, 2020 at 1:01 AM #18651sgtscience
ParticipantI did a test with the code using the file attachment only not in a group like this and it works fine:
add_action( 'woocommerce_after_add_to_cart_button', 'product_download_button_test', 5 ); function product_download_button_test() { ?> <div class="dropdown"> <button class="product-downloads-button nectar-button large regular accent-color regular-button" onclick="return false;">DOWNLOADS <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <?php $file_attachments = rwmb_meta( 'attachment_test' ); if ( ! empty( $file_attachments ) ) { foreach ( $file_attachments as $file_attachment ) { if ( isset( $file_attachment ) ) { $file_url = ( $file_attachment['url'] ); ?> <a href="<?php echo $file_url; ?>" target="_blank"><?php echo $file_attachment['name']; ?> </a> <?php } } } ?> </div> </div> <?php }
But when it seems as soon as the file attachment is in a group, I can return any info from it. This is the same only with the file attachment in a group:
add_action( 'woocommerce_after_add_to_cart_button', 'product_download_button_test', 5 ); function product_download_button_test() { ?> <div class="dropdown"> <button class="product-downloads-button nectar-button large regular accent-color regular-button" onclick="return false;">DOWNLOADS <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <?php $file_attachments = rwmb_meta( 'attachment_test' ); if ( ! empty( $file_attachments ) ) { foreach ( $file_attachments as $file_attachment ) { if ( isset( $file_attachment ) ) { $file_url = ( $file_attachment['url'] ); ?> <a href="<?php echo $file_url; ?>" target="_blank"><?php echo $file_attachment['name']; ?> </a> <?php } } } ?> </div> </div> <?php }
I get an error "undefined index url" and when I try to use
wp_get_attachment_url()
orget_attached_file()
it returns nothing.
It seems like whatever I try to do to get info from$file_attachment['attachment']
, or when a file attachment is in a group, it is always empty.March 22, 2020 at 8:12 AM #18652sgtscience
ParticipantSorry I repeated that code block, Here is the second one properly:
add_action( 'woocommerce_after_add_to_cart_button', 'product_download_button', 5 ); function product_download_button() { ?> <div class="dropdown"> <button class="product-downloads-button nectar-button large regular accent-color regular-button" onclick="return false;">DOWNLOADS <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <?php $file_attachments = rwmb_meta( 'file_attachments' ); if ( ! empty( $file_attachments ) ) { foreach ( $file_attachments as $file_attachment ) { $file_name = isset( $file_attachment['file_name'] ) ? $file_attachment['file_name'] : ''; if ( isset( $file_attachment['attachment'] ) ) { $file_url = $file_attachment['attachment']; ?> <a href="<?php echo $file_url['url']; ?>" target="_blank"><?php echo $file_name; ?> </a> <?php } } } ?> </div> </div> <?php }
March 23, 2020 at 9:59 AM #18658Anh Tran
KeymasterI got it. We forget that the returned value of the
file_advanced
field is an array! So we need to get only the first file ID.if ( isset( $file_attachment['attachment'] ) ) { $file_id = reset( $file_attachment['attachment']; // Get the first file only. $file_url = wp_get_attachment_url( $file_id ); echo '<a href="' . $file_url . '" target="_blank">' . $file_name . '</a>'; }
March 23, 2020 at 12:41 PM #18665sgtscience
ParticipantThat did it! I was wracking my brain on this trying so many different things. Thank you very much for your help!
April 2, 2020 at 1:44 AM #18809sgtscience
ParticipantHi Anh,
Just following up on this. When using the code you helped fix here:
add_action( 'woocommerce_after_add_to_cart_button', 'product_download_button', 5 ); function product_download_button() { $file_attachments = rwmb_meta( 'file_attachments' ); if ( ! empty( $file_attachments ) ) { ?> <div class="dropdown"> <button class="product-downloads-button nectar-button large regular accent-color regular-button" onclick="return false;">DOWNLOADS <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <?php foreach ( $file_attachments as $file_attachment ) { $file_name = isset( $file_attachment['file_name'] ) ? $file_attachment['file_name'] : ''; if ( isset( $file_attachment['attachment'] ) ) { $file_id = reset( $file_attachment['attachment'] ); // Get the first file only. $file_url = wp_get_attachment_url( $file_id ); echo '<a href="' . $file_url . '" target="_blank">' . $file_name . '</a>'; } } } ?> </div> </div> <?php }
Even if there is no name or attachment for the file, the download button still shows on the product page even though there is nothing in it. I made another similar custom group field with a text and color picker and when I use this:
$special_colours = rwmb_meta( 'special_colours' ); if ( ! empty( $special_colours ) ) {
When there is nothing in the fields for the product nothing displays, as it should correctly. Is this maybe because as you mentioned previously that the
file_advanced
is array and soif ( ! empty( $file_attachments ) ) {
still sees that theattachment
item in the group is not empty? Is there a way around this so that the download button is not displayed if there is nothing in the fields for that product?April 2, 2020 at 10:05 AM #18814Long Nguyen
ModeratorHi,
Because you've enabled the attribute
save_state
so the file attachments always return an array$file_attachments = rwmb_meta( 'file_attachments' );
This attribute means when you add more groups but not put any name or file, it will save the last state when publishing the product. Take a look at my screenshot https://cl.ly/e883f5d356f2
Change the attribute
'save_state' => false
and refresh your site, the button will not display if there are empty fields in the first group.April 3, 2020 at 4:34 AM #18827sgtscience
ParticipantHi Long,
Thanks for the reply I gave that a shot and unfortunately it didn't work. I also took a look at some products and it looks like some are showing the special colour content while others are not even when there is no name or colour selected. Here is the colour code for reference:
add_filter( 'rwmb_meta_boxes', 'prefix_register_special_colours' ); function prefix_register_special_colours( $meta_boxes ) { $meta_boxes[] = array( 'id' => 'Special_Colours', 'title' => esc_html__( 'Special Order Colours' ), 'post_types' => array( 'product' ), 'context' => 'advanced', 'priority' => 'default', 'autosave' => 'true', 'fields' => array( array( 'id' => 'special_colours', 'type' => 'group', 'group_title' => 'Colour {#}', 'collapsible' => true, 'save_state' => true, 'clone' => true, 'sort_clone' => true, 'fields' => array( array( 'id' => 'colour_name', 'type' => 'text', 'name' => 'Colour Name', ), array( 'id' => 'special_colour', 'type' => 'color', 'name' => esc_html__( 'Special Colour' ), 'desc' => esc_html__( 'Select a colour to appear on the product page as a special order colour' ), ), ), ), ), ); return $meta_boxes; }
add_action( 'woocommerce_before_add_to_cart_button', 'product_special_colours', 5 ); function product_special_colours() { $special_colours = rwmb_meta( 'special_colours' ); if ( ! empty( $special_colours ) ) { echo '<table class="variations" cellspacing="0"> <tbody> <tr> <td class="label"> <label for="so_color">Special Order Colours</label> </td> <td class="value woo-variation-items-wrapper"> <ul class="variable-items-wrapper color-variable-wrapper">'; foreach ( $special_colours as $special_colour ) { $colour_name = isset( $special_colour['colour_name'] ) ? $special_colour['colour_name'] : ''; if ( isset( $special_colour['special_colour'] ) ) { $colour = isset( $special_colour['special_colour'] ) ? $special_colour['special_colour'] : ''; echo '<li class="special_colour" style="background-color: ' . $colour . ' "> <span class="tooltip">' . $colour_name . '</span> </li>'; } } echo '</ul> </td> <td> <p>To order one of our special special order colours please <a href="/contact/">contact us</a>. <br> Please note that shipping of special orders can take up to 12 weeks.</p> </td> </tr> </tbody> </table>'; } }
-
AuthorPosts
- You must be logged in to reply to this topic.