How to attach media file to woocommerce order? - wordpress

I want to attach media file after payment completion of order, for that I am using the filter "woocommerce_order_status_completed" with below snippet. But it is not attaching files to downloads tab of my account page.
add_filter( 'woocommerce_order_status_completed', 'attach_files' );
function attach_files($order_id){
$order = wc_get_order($order_id);
$md5_num = md5( 'http://localhost/wordpress/wp-content/uploads/abc.png');
$files[$md5_num] = array(
'download_url' => 'http://localhost/wordpress/wp-content/uploads/abc.png',
'download_name' => 'Download',
'downloads_remaining' => '1',
'access_expires' => NULL,
'download_id' => '7f7e4923ff94b7928c0b8b5e93fb4f89',
'product_id' => 17,
'order_id' => $order_id,
'order_key' => 'wc_order_5a382bef811e6',
'file' => array (
'name' => 'Download',
'file' => 'http://localhost/wordpress/wp-content/uploads/abc.png',
),
);
update_post_meta($order_id,'_files',$files);
}
Please help me to solve this.

Related

Created woocommerce product attribute programmatically and added terms to them but terms are not showing in Product->Attributes

I have created woo-commerce product attributes programmatically by the following code:
$data = array(
'name' => 'My attribute',
'slug' => wc_sanitize_taxonomy_name(wp_unslash('My attribute')),
'type' => 'select',
'order_by' => 'menu_order',
'has_archives' => 1
);
wc_create_attribute( $data );
and this code adds attributes successfully and are visible to the list of woo-commerce in Products->Attributes, but after that, I tried adding some terms to them which are not affected to the attribute list by using following code:
wp_insert_term( 'term_1' ,'pa_'.$data['slug']);
also, I confirm that when I dump the result of var_dump(get_term_by('name','term_1','pa_'.$data['slug'])) I get result with term id,name,slug,term_taxonomy_id etc., but the problem it these terms are not visible on the woocommerce product attributes and so does on product editing page.
Because I've searched myself a lot before reaching out to a working solution that works for Woocommerce 3.8+, I give this answer in order others to get help on a really confusing topic such as Woocommerce Attributes.
I've created two methods/functions: createAttribute and createTerm based on the sample code that Woocomerce provides as an example: See code
function createAttribute(string $attributeName, string $attributeSlug): ?\stdClass {
delete_transient('wc_attribute_taxonomies');
\WC_Cache_Helper::incr_cache_prefix('woocommerce-attributes');
$attributeLabels = wp_list_pluck(wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_name');
$attributeWCName = array_search($attributeSlug, $attributeLabels, TRUE);
if (! $attributeWCName) {
$attributeWCName = wc_sanitize_taxonomy_name($attributeSlug);
}
$attributeId = wc_attribute_taxonomy_id_by_name($attributeWCName);
if (! $attributeId) {
$taxonomyName = wc_attribute_taxonomy_name($attributeWCName);
unregister_taxonomy($taxonomyName);
$attributeId = wc_create_attribute(array(
'name' => $attributeName,
'slug' => $attributeSlug,
'type' => 'select',
'order_by' => 'menu_order',
'has_archives' => 0,
));
register_taxonomy($taxonomyName, apply_filters('woocommerce_taxonomy_objects_' . $taxonomyName, array(
'product'
)), apply_filters('woocommerce_taxonomy_args_' . $taxonomyName, array(
'labels' => array(
'name' => $attributeSlug,
),
'hierarchical' => FALSE,
'show_ui' => FALSE,
'query_var' => TRUE,
'rewrite' => FALSE,
)));
}
return wc_get_attribute($attributeId);
}
function createTerm(string $termName, string $termSlug, string $taxonomy, int $order = 0): ?\WP_Term {
$taxonomy = wc_attribute_taxonomy_name($taxonomy);
if (! $term = get_term_by('slug', $termSlug, $taxonomy)) {
$term = wp_insert_term($termName, $taxonomy, array(
'slug' => $termSlug,
));
$term = get_term_by('id', $term['term_id'], $taxonomy);
if ($term) {
update_term_meta($term->term_id, 'order', $order);
}
}
return $term;
}
So they can be used like:
createAttribute('Colors', 'my-colors');
createTerm('Red', 'my-red', 'my-colors', 10);
createTerm('Green', 'my-green', 'my-colors', 20);
createTerm('Blue', 'my-blue', 'my-colors', 30);

$order->get_checkout_payment_url() different behavior for product and subscription

I'm trying to create subscription order by code. I'm using the latest version of Woocommerce and Woocommerce Subscription plugins. It's working fine, but I got different order-pay page when the order contains subscription product.
When the order contains a subscription, I got all the billing and the shipping fields. If the order only contains simple products, I got a summary about the order and the payment methods. I would like the same behavior for subscriptions.
Example link:
https://test.eu/hu/cart/order-pay/4467/?pay_for_order=true&key=wc_order_161651fdsf56
I generate the link with the method get_checkout_payment_url and I got similar link in both cases, but if the order contains a subscription, I 'm redirected to the cart page immediately.
Does anybody faced with same problem?
Thank you for any help!
Best regards,
Mark
$start_date = $order_data['created_at'];
$billing_address = array(
'first_name' => $order_data['first_name'],
'last_name' => $order_data['last_name'],
'company' => $order_data['company_name'],
'email' => $order_data['email'],
'phone' => $order_data['phone_number'],
'address_1' => $order_data['street_address'],
'address_2' => $order_data['apartment_suite_unit'],
'city' => $order_data['town'],
'postcode' => $order_data['zip_code'],
'country' => $order_data['country']
);
$shipping_address = array(
'first_name' => $order_data['shipping_first_name'],
'last_name' => $order_data['shipping_last_name'],
'company' => $order_data['shipping_company_name'],
'address_1' => $order_data['shipping_street_address'],
'address_2' => $order_data['shipping_apartment_suite_unit'],
'city' => $order_data['shipping_town'],
'postcode' => $order_data['shipping_zip_code'],
'country' => $order_data['shipping_country']
);
$email = $order_data['email'];
if (!$user = get_user_by('email', $email)) $user = get_user_by('id', wc_create_new_customer($email));
$order = wc_create_order(array('customer_id' => $user->ID));
update_post_meta($order->ID, "phone_order", true);
foreach ($order_data['ordered_items'] as $item) {
$product = wce_get_product($item, $currency);
$order->add_product( $product, $item['quantity']);
}
$order->set_address( $billing_address, 'billing' );
$order->set_address( $shipping_address, 'shipping' );
$order->set_currency( $currency );
$order->set_payment_method( $order_data['payment_method'] );
$order->calculate_totals();
$order->calculate_taxes();
// Előfizetés
foreach ($order_data['ordered_items'] as $item) {
if (WC_Subscriptions_Product::is_subscription($item['id'])) {
$product = wce_get_product($item, $currency);
$sub = wcs_create_subscription(array('order_id' => $order->id, 'billing_period' => $period, 'billing_interval' => $interval, 'start_date' => $start_date));
$sub->add_product( $product, $item['quantity']/*, $args*/);
$sub->set_address( $billing_address, 'billing' );
$sub->set_address( $shipping_address, 'shipping' );
$sub->calculate_totals();
}
}
$payment_link = $order->get_checkout_payment_url();
return $payment_link;
}

New fields aren't created after updating a custom module. DRUPAL 7

I have a custom module on my site. I try to install an update with a new field for my vocabulary, but the field doesn't appear.
hook_update:
function mymodule_update_7118()
{
$field_name = 'field_newfield';
if ( field_info_field( $field_name ) ) {
return;
}
$field = array(
'field_name' => $field_name,
'type' => 'list_integer',
'settings' => array(
'allowed_values' => array(
'Yes' => 1, //heard that adding a NO value may cause problems, although it doesn't work with a no value either.
),
),
);
$field = field_create_field( $field );
$instance = array(
'field_name' => $field['field_name'],
'entity_type' => 'taxonomy',
'bundle' => 'vocab_name',
'label' => 'Label',
'widget' => array(
'active' => 1,
'module' => 'options',
'settings' => array(),
'type' => 'options_select',
'weight' => '3',
),
);
field_create_instance($instance);
}
Logs contain several recordings of Internalization module creating a string to translate this field. Also all needed tables are created in the database, but they are all empty.
For creating a new custom field you must do it like a custom module. The steps can be found out at https://drupal.stackexchange.com/questions/140517/how-to-create-new-field-type
You can find the excellent field_example module from the Examples Module which is always the first place to look. Examples module can be downloaded from https://www.drupal.org/project/examples

Setting a default option using CMB2 select field type

I am using CMB2's select to pull in a list of posts that a user can choose from in a custom meta box.
I have added a "blank" option to the options array, but I can't figure out how to make that the default option (ie. <option selected="selected" value="">I'm blank</option>).
I need to do this so I can use an if statement that says if the field is blank, don't show the output box on the site. Right now, even if the user hasn't specifically chosen an option, an option with a value is passed through.
Here's the meta box code:
$link_post_types = array('charter', 'page');
$meta_boxes['ms_metabox'] = array(
'id' => 'ms_metabox',
'title' => __( 'Page Links', 'cmb2' ),
'object_types' => array( 'page' ),
'context' => 'normal',
'priority' => 'high',
'show_names' => true,
'fields' => array(
array(
'name' => __( 'Page Link', 'cmb2' ),
'desc' => __( 'Choose the page this will link to', 'cmb2' ),
'id' => $prefix . 'page_link',
'type' => 'select',
'options' => ms_get_posttype_options($link_post_types),
),
),
);
function ms_get_posttype_options($argument) {
$get_post_args = array(
'post_type' => $argument,
'posts_per_page' => -1,
'orderby' => 'type',
'order' => ASC
);
$options = array();
foreach ( get_posts( $get_post_args ) as $post ) {
$post_type = get_post_type( $post->ID);
$title = get_the_title( $post->ID );
$permalink = get_permalink( $post->ID);
$options[] = array(
'name' => $title . ' : ' . $post_type,
'value' => $permalink,
);
}
$empty_option[] = array(
'name' => 'Please select an option',
'value' => '',
);
$options = array_merge($empty_option, $options);
return $options;
}
There is a default argument but when I tried to apply it as in the example, it didn't work.
Thanks for any help!
I halfway figured it out. The posts I was having problems with were old ones where I had already been messing with the values before I added the blank option - when I created new posts, the default option was the blank one (since it was the first array in the merge).
If anyone has a more foolproof solution I'd like to hear it though!
You can add the following to the meta box fields array:
show_option_none' => true

Pass file to Wordpress wp_handle_upload

I'm trying to pass file to Wordpress wp_handle_upload. Normally it should get $_FILES array, so I tried to create it manually, like
$uploadedfile = array ( 'filePhoto' => array ( 'name' => $name, 'type' => 'image/png', 'tmp_name' => $file, 'error' => 0, 'size' => 178890, ), );
$upload_overrides = array( 'test_form' => false );
$movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
But the file for some reason isn't copied to uploads directory. Any hints?
Thanks
What you want is wp_handle_sideload
upload is only for actual uploads! :)

Resources