I'm currently working with the plugin Google Calendar Events. I'd like to add the ability for users to choose (via a select drop-down menu) which feed they're viewing and then have the calendar automatically display the selected feed. Does anyone know how to do this?
I know that you can use the shortcode to choose what feeds to display, but I'd rather not create an individual page for each feed, and then have links to them (there are 10+ feeds and one is added and deleted with regularity, so it's just not feasible to manually create a calendar for each individual feed).
I've added this code to the gce-script.js file in the plugin:
function changeFeeds(){
var values = jQuery("#gce-view-feed").val();
jQuery("#result").replaceWith(values);
}
jQuery("option").click(function(){
location.reload();
});
jQuery("select").change(changeFeeds);
changeFeeds();
...Where the id "gce-view-feed" is the select menu's id and id "result" is where I display the results. This works great, except how do I then pass that result to the plugin so that it uses it?
Feed ids are defined by a PHP variable $feed_ids. I think the best place to edit the variable is this line of code in the google-calendar-events.php file:
//Check that any feeds have been added
if ( is_array( $options ) && ! empty( $options ) ) {
extract( shortcode_atts( array(
'id' => '',
'type' => 'grid',
'title' => null,
'max' => 0,
'order' => 'asc'
), $atts ) );
$no_feeds_exist = true;
$feed_ids = array();
if ( '' != $id ) {
//Break comma delimited list of feed ids into array
$feed_ids = explode( ',', str_replace( ' ', '', $id ) );
//Check each id is an integer, if not, remove it from the array
foreach ( $feed_ids as $key => $feed_id ) {
if ( 0 == absint( $feed_id ) )
unset( $feed_ids[$key] );
}
//If at least one of the feed ids entered exists, set no_feeds_exist to false
foreach ( $feed_ids as $feed_id ) {
if ( isset($options[$feed_id] ) )
$no_feeds_exist = false;
}
} else {
foreach ( $options as $feed ) {
$feed_ids[] = $feed['id'];
}
$no_feeds_exist = false;
}
But I don't know how to pass the jQuery value to the $feed_ids variable. Is there a way to do this? And if not, is there another way to dynamically select an option and then pass it to a PHP variable?
Related
I'm trying to display some order item meta data as checkboxes instead of plain text via the woocommerce_order_item_display_meta_value hook (hope my terminology is right. I'm new to this woocommerce game).
add_filter( 'woocommerce_order_item_display_meta_value', 'modify_order_item_display_value' , 10, 3 );
function modify_order_item_display_value( $display_value, $meta, $wc_order_item ) {
$meta_data = $meta->get_data();
if( $meta_data['key'] === '_Packed' ) {
$display_value = __('<input type="checkbox" name="mycheckbox" id="mycheckbox" value="1" />', 'woocommerce' );
}
return $display_value;
}
If I do something like $display_value = '<p>TEST</p>'; it comes out fine. When I try to use an input it doesn't show up. Looking at DOM in the browser I can get down to the <td> that should contain my input and the HTML just isn't there.
Does woocommerce_order_item_display_meta_value filter out input fields?
Is there another way to get a checkbox for order item meta data ?
I don't know if this is the right way to do it but it works. I'd love any feedback about the "woocommercyness" of it...
STEP1
Use woocommerce_hidden_order_itemmeta to hide my field so it doesn't get shown "the normal way"
add_filter( 'woocommerce_hidden_order_itemmeta', 'myplugin_hide_order_item_meta_fields' );
function myplugin_hide_order_item_meta_fields( $fields )
{
$fields[] = '_Packed';
return $fields;
}
STEP 2
Use woocommerce_after_order_itemmeta to display my field in a custom way after all of the other Meta data.
Note that I give the checkbox an ID based on the order item id. In other code I need to see if these IDs are passed in requests or not
add_action( 'woocommerce_after_order_itemmeta', 'myplugin_order_meta_customized_display',10, 3 );
function myplugin_order_meta_customized_display( $item_id, $item, $product )
{
$packed = $item->get_meta('_Packed') === 'Y';
echo "<div>";
woocommerce_form_field("packed_$item_id",
array(
'type' => 'checkbox',
'label' => __('Packed', 'woocommerce'),
'required' => false,
'class' => array('input-checkbox')
), $packed);
echo "</div>";
}
STEP 3
Use the REQUEST to set the meta datafunction myplugin_set_meta_from_post($order_id, $order)
I call a wrapper from the actions woocommerce_checkout_order_processed and save_post_shop_order. The actuions get the order id - I lookup the order (because I'm doing other stuff, not just the crazy meta display)
function myplugin_set_meta_from_post($order_id, $order)
{
// For each meta data in each order item
// If it is '_Packed' then see if a corresponding packed_<id> parameter
// is in the request and update the item's meta data accordingly.
//
foreach ($order->get_items() as $item_key => $item ) {
$item_meta = $item->get_meta_data();
foreach($item_meta as $meta)
{
if ($meta->__get('key') === '_Packed')
{
$k = 'packed_'.$item->get_id();
$packed = 'Y';
if ( ! isset( $_REQUEST[ $k ] ) || empty( $_REQUEST[ $k ] ) ) {
$packed = 'N';
}
if ($packed != $item->get_meta('_Packed'))
{
$item->update_meta_data('_Packed', $packed);
}
}
}
}
}
Trying to create new fields for my form dynamically, as I'm getting json from 3rd party API. Based on this json, I need a number of fields added to my form - not fixed number. So, I'm doing this, hooking it onto gform_pre_render:
add_filter( 'gform_pre_process', 'create_products_gforms' );
add_filter( 'gform_admin_pre_render', 'create_products_gforms' );
add_filter( 'gform_pre_render', 'create_products_gforms' );
function create_products_gforms( $form ) {
$helper = new NSHelper();
$state_name = $_POST['input_7'] ?? '';
$code_value = $helper->get_state_code_by_name( $state_name );
// Only fetch products if current form id is 33, state code is defined
// and if there are products for this state.
if ( $form['id'] != 33 || !$code_value ) {
return $form;
}
// Get product list from NetSuit API based on state code
$products_json_data = get_products_data( $code_value );
$products = json_decode( json_decode( $products_json_data ) );
$new_field_id = 0;
foreach( $form['fields'] as $field ) {
if( $field->id > $new_field_id ) {
$new_field_id = $field->id;
}
}
$new_field_id++;
foreach ( $products as $product_object ) {
// Prepare field properties
$props = array(
'id' => $new_field_id,
'type' => 'singleproduct',
'label' => $product_object->onlinedisplayname,
'basePrice' => floatval( $product_object->price ),
'enableCalculation' => true
);
// Create new gravity forms field and add it to the form object
$nf = GF_Fields::create( $props );
// Hack - insert into array at specific position
// Needed to display product fields before other fields
// in the form
array_splice( $form['fields'], 11, 0, array($nf) );
$new_field_id++;
}
GFAPI::update_form( $form );
$form['dynamic_fields_ids'] = $added_fields_ids;
return $form;
}
This works, ie, it shows fields properly on the frontend. Now, the issue with this is that, once form is submitted, all the fields except these dynamically added ones are in the submission. But these are not. I assumed this has to do that these fields aren't registered in the form, so I also tried GFAPI::update_form( $form );, but that didn't help with submission part, though it udpates my form with new fields in the backend too.
Any ideas?
Based on your use-case, Milos, I would suggest using the gform_form_post_get_meta filter:
https://docs.gravityforms.com/gform_form_post_get_meta/
This will fire every time the form is fetched from the database and the most sure-fire way of guaranteeing your fields will be present.
If you prefer to be more surgical and stick with the gform_pre_render approach, you'll want to apply the same function on a couple other filters:
gform_pre_process
gform_admin_pre_render
I'm facing a big problem with product variations and their attributes in woocommerce. I'm trying to display a table with each attribute for each availabe product variation. But Woocommerce saves the attributes in post meta complete in lowercase, replaces slashes and german special characters like ü,ö,ä etc. I get the attributes with $variation->get_variation_attributes().
I've searched the database for the save values you can see for example in the dropdown in the admin panel, but they are saved like this without a link to the variation they are assigned to:
a:5:{s:10:"bestell-nr";a:6:{s:4:"name";s:11:"Bestell-Nr.";s:5:"value";s:9:"1 | 2 | and so on...
How can I get the attributes in their correct format to display?
Actually product attributes are actually terms in custom taxonomies, so you just need to get the terms in that particular taxonomy. All attribute taxonomies are prefaced with 'pa_'. So a size attribute would be a 'pa_size' taxonomy. And the variation ID is the post ID for a variation.
But depending on how you want to display it, WooCommerce has a built-in function for displaying all a variation's attributes:
The following will display a definition list of all of a variations attributes.
echo wc_get_formatted_variation( $product->get_variation_attributes() );
And passing a second parameter of true will display a flat list:
echo wc_get_formatted_variation( $product->get_variation_attributes(), true );
This seems to work for me. Hope this helps.
$post = get_post();
$id = $post->ID;
$product_variations = new WC_Product_Variable( $id );
$product_variations = $product_variations->get_available_variations();
print_r($product_variations);
This can be found in the class-wc-product-variable.php
So basically if you look around on that page you can find a bunch of useful functions.
Here is something i put together.
$product_children = $product_variations->get_children();
$child_variations = array();
foreach ($product_children as $child){
$child_variations[] = $product_variations->get_available_variation($child);
}
print_r($child_variations);
I only wanted to publish one of the variation attributes rather than all of them; contributing this code in case it's helpful to anyone else.
get_variation_attributes() gets all the attributes
wc_get_formatted_variation() returns a formatted version of the array it's handed
$attributes = $productVariation->get_variation_attributes() ;
if ( $attributes [ 'attribute_pa_colour' ] ) {
$colour = [ 'attribute_pa_colour' => $attributes [ 'attribute_pa_colour'] ];
echo wc_get_formatted_variation ( $colour );
}
The way I do it is by using "get_post_meta":
echo get_post_meta( $variation_id, 'attribute_name_field', true);
Hopes this helps someone.
I used wp_get_post_terms to get correct variance attributes.
global $product;
$variations = $product->get_available_variations();
$var = [];
foreach ($variations as $variation) {
$var[] = $variation['attributes'];
}
var_dump($var);
//xxx to get attribute values with correct lower-upper-mixed-case
foreach ($var as $key => $arr) {
foreach ($arr as $orig_code => $lowercase_value) {
$terms_arr = wp_get_post_terms( $product->id, str_replace('attribute_','',$orig_code), array( 'fields' => 'names' ) );
foreach ($terms_arr as $term) {
if (strtolower($term) == $lowercase_value) {
$var[$key][$orig_code] = $term;
break;
}
}
}
}
var_dump($var);
The results:
Before hard code
array (size=1)
0 =>
array (size=2)
'attribute_pa_width' => string 'none' (length=4)
'attribute_pa_code' => string 'valancese' (length=9)
After hard code:
array (size=1)
0 =>
array (size=2)
'attribute_pa_width' => string 'None' (length=4)
'attribute_pa_code' => string 'ValanceSe' (length=9)
Just went through this ...here is my solution. It handles multiple attributes and all the variations. You just have to know the attribute slug.
$items = $order->get_items();
foreach( $items as $item_id => $product )
{
$ProductName = $product->get_name(); /
if($product->is_type( 'simple' ))
$CoreProductName = $ProductName; // No variance
else
{
list($CoreProductName, $ThrowAway) = explode(" - ",$ProductName, 2);
$variation_id = $product['variation_id'];
$variation = new WC_Product_Variation($variation_id);
$attributes = $variation->get_variation_attributes();
$SelectedAttribute1 = $attributes['attribute_YOUR_SLUG1_PER_PRODUCT'];
$SelectedAttribute2 = $attributes['attribute_YOUR_SLUG2_PER_PRODUCT'];
}
}
I have 2 custom content types created by Pods CMS: fights and events. In the fights content type there is a relationship field for the event. How would I select all fights from the database by a specific event id? I tried querying the pods relationships table manually but that gave me incorrect results.
$fights = pods( 'fights' );
$params = array(
'where' => 'event.id = 3'
);
$fights->find( $params );
// loop through a while( $fights->fetch() ) and use $fights->field() to get the values of each field
That should do it, but you'll want to look at the 'find' documentation for your specific content type case as event.id may not be what you want (you may want event.ID).
http://pods.io/docs/code/pods/
http://pods.io/docs/code/pods/find/
http://pods.io/docs/code/pods/field/
http://pods.io/docs/code/pods/display/
Using this function you can easily display all individual relational fields with shortcode:
function get_pod_fields($atts) {
$a = shortcode_atts( array('field' => '', 'pod'=> '', 'relation'=> '', 'type'=>'', 'as'=>'url'), $atts );
$pod = pods( $a['pod'], get_the_id() );
$related = $pod->field( $a['relation']);
$field = get_post_meta( $related['ID'], $a['field'], true );
if($a['type'] == "image") {
if($a['as'] == "image") {
$field = '<img src="'.$field = $field['guid'].'"></img>';
} else {
$field = $field['guid'];
}
} else {
$field = $field;
}
return $field;
}
add_shortcode( 'podfields', 'get_pod_fields' );
[podfields field="profile_picture" type="image" pod="therapy" as="image" relation="therapist"]
I am building a drupal 7 (7.20) website with a "project" content type which contains multiple image fields (i do not want to use galleries).
I would like to be able to perform a mass delete operation on these fields from the node edit page. From what I have gathered I have to override theme_file_widget_multiple and return a tableselect instead of a table and then use a button plus javascript to delete the images from the database.
Am I missing something obvious ? This seems like alot of work for something so trivial.
EDIT:
I have had some progress with this:
function mytheme_file_widget_multiple($variables) {
$element = $variables ['element'];
$headers = array ();
$headers ['info'] = t ( '' );
$widgets = array ();
foreach ( element_children ( $element ) as $key ) {
$widgets [] = &$element [$key];
}
usort ( $widgets, '_field_sort_items_value_helper' );
$rows [] = array ();
$i = 0;
foreach ( $widgets as $key => &$widget ) {
// Save the uploading row for last.
if ($widget ['#file'] == FALSE) {
$widget ['#description'] = $element ['#file_upload_description'];
continue;
}
$operations_elements = array ();
foreach ( element_children ( $widget ) as $sub_key ) {
if (isset ( $widget [$sub_key] ['#type'] ) && $widget [$sub_key] ['#type'] == 'submit') {
$operations_elements [] = &$widget [$sub_key];
}
}
$information = drupal_render ( $widget );
$rows [$i ++] ['info'] = $information;
}
$output = '';
$output = drupal_render_children ( $element );
$form ['element'] = array (
'#type' => 'tableselect',
'#header' => $headers,
'#options' => $rows,
'#js_select' => TRUE,
'#empty' => t ( 'No data' ),
'#attributes' => array () );
$output .= empty ( $rows ) ? "" : drupal_render ( $form );
return $output;
}
This was included in my theme's template file however the tableselect does not have checkboxes. This is driving me crazy.. Can someone please tell me what I am doing wrong ?
From what I have gathered I have to create a module which overrides the fieldset preprocess functions..
Here are the references:
1) https://drupal.org/node/1905244
This article seems to try to do what you want to.
2) Also check out https://drupal.org/project/views_bulk_operations
this might be useful.
3) if not then you will need to make your own widget:
https://api.drupal.org/api/drupal/modules%21field%21field.module/group/field/7
https://drupal.org/project/examples ( has all the examples you will need )
all the best.