I'm using WooCommerce in a marketplace website and I am looking for a solution to disable the "downloadable product" functionality. Mainly I want that it doesn't appear in vendor's backend.
By Claudio Sanches (#claudiosanches):
Go to WooCommerce > Settings > Account and clean the downloads endpoint field.
This will disable the downloads page.
I got this answer here By Christophvh .
Go to WooCommerce > Settings > Advanced and remove the entry for Downloads in the Account endpoints section, just leave it Blank. And the menu will not be visible anymore. Just take a look my Attached Image.
function CM_woocommerce_account_menu_items_callback($items) {
unset( $items['downloads'] );
return $items;
}
add_filter('woocommerce_account_menu_items', 'CM_woocommerce_account_menu_items_callback', 10, 1);
Used this in place of the above
This code worked for me. I got it from the Woocommerce Support.
https://wordpress.org/support/topic/remove-virtual-downloadable-products-selection/
function my_remove_product_type_options( $options ) {
// uncomment this if you want to remove virtual too.
// if ( isset( $options['virtual'] ) ) {
// unset( $options['virtual'] );
// }
if ( isset( $options['downloadable'] ) ) {
unset( $options['downloadable'] );
}
return $options;
}
add_filter( 'product_type_options', 'my_remove_product_type_options' );
Not sure if I understood it correctly but if you are willing to remove "Downloads" navigation option from the "My Account" page then continue reading :)
Create Child Theme to your currently used theme. If you are not well known what it is read this: https://codex.wordpress.org/Child_Themes
Now copy navigation.php from ...\wp-content\plugins\woocommerce\templates\myaccount\ to the Child Theme folder ...\wp-content\themes\yourtheme-child\woocommerce\myaccount\
Open navigation.php in your Child theme folder. Find line with function wc_get_account_menu_items() and rename the function to for example wc_get_account_menu_items_custom()
Open functions.php in your Child theme folder. Paste inside the file below function. Save the file and that's all. Now the "My Account" page is without "Downloads" navigation option.
function wc_get_account_menu_items_custom() {
$endpoints = array(
'orders' => get_option( 'woocommerce_myaccount_orders_endpoint', 'orders' ),
'edit-address' => get_option( 'woocommerce_myaccount_edit_address_endpoint', 'edit-address' ),
'payment-methods' => get_option( 'woocommerce_myaccount_payment_methods_endpoint', 'payment-methods' ),
'edit-account' => get_option( 'woocommerce_myaccount_edit_account_endpoint', 'edit-account' ),
'customer-logout' => get_option( 'woocommerce_logout_endpoint', 'customer-logout' ),
);
$items = array(
'dashboard' => __( 'Dashboard', 'woocommerce' ),
'orders' => __( 'Orders', 'woocommerce' ),
'edit-address' => __( 'Addresses', 'woocommerce' ),
'payment-methods' => __( 'Payment Methods', 'woocommerce' ),
'edit-account' => __( 'Account Details', 'woocommerce' ),
'customer-logout' => __( 'Logout', 'woocommerce' ),
);
// Remove missing endpoints.
foreach ( $endpoints as $endpoint_id => $endpoint ) {
if ( empty( $endpoint ) ) {
unset( $items[ $endpoint_id ] );
}
}
// Check if payment gateways support add new payment methods.
if ( isset( $items['payment-methods'] ) ) {
$support_payment_methods = false;
foreach ( WC()->payment_gateways->get_available_payment_gateways() as $gateway ) {
if ( $gateway->supports( 'add_payment_method' ) || $gateway->supports( 'tokenization' ) ) {
$support_payment_methods = true;
break;
}
}
if ( ! $support_payment_methods ) {
unset( $items['payment-methods'] );
}
}
return apply_filters( 'woocommerce_account_menu_items_custom', $items );
}
Note: This is edited original WooCommerce function. There are just deleted array fields mentioning "Downloads" option.
Hope this helps.
Ok so based on all of the answers above, I've put together an "all-in-one" solution which disables:
The download endpoint.
The checkbox options from the admin product editor.
The dropdown options from Product Type Filter.
The downloads metabox from orders.
File: class-disablewoocommerceproducttypes.php
class DisableWooCommerceProductTypes {
/**
* #var array Product types in this property will be disabled.
*/
public $disabled = [
'virtual',
'downloadable'
];
/**
* #var array WooCommerce uses different references for the same product types.
*/
private $aliases = [
'downloadable' => [ 'downloads' ]
];
/**
* #var int The priority of these overrides.
*/
public $priority = PHP_INT_MAX;
/**
* #var null|string|array $product_types Accepts a string or array of 'virtual' and/or 'downloadable' product types.
*/
public function __construct( $product_types = null ) {
if ( $product_types ) {
$this->disabled = (array)$product_types;
}
add_filter( 'product_type_options', [ $this, 'disable_admin_options' ], $this->priority );
add_filter( 'woocommerce_account_menu_items', [ $this, 'disable_frontend_nav_items' ], $this->priority );
add_filter( 'add_meta_boxes', [ $this, 'disable_admin_metabox' ], $this->priority );
add_filter( 'woocommerce_products_admin_list_table_filters', [ $this, 'disable_admin_filters' ], $this->priority );
// Disable the downloads endpoint
if ( $this->is_disabled( 'downloadable' ) ) {
add_filter( 'default_option_woocommerce_myaccount_downloads_endpoint', '__return_null' );
add_filter( 'option_woocommerce_myaccount_downloads_endpoint', '__return_null' );
}
}
/**
* Quickly check if a product type is disabled. Returns primary key if $type is an alias and disabled.
*
* #param string $type
* #param bool $aliases Check for aliases.
* #return bool|string
*/
private function is_disabled( string $type, bool $aliases = true ) {
$basic_check = in_array( $type, $this->disabled );
if ( $aliases && !$basic_check ) {
foreach ( $this->aliases as $_type => $_aliases ) {
if ( in_array( $type, $_aliases ) && $this->is_disabled( $_type, false ) ) {
return $_type;
}
}
}
return $basic_check;
}
/**
* Remove product type checkboxes from product editor.
*
* #param array $types
* #return array
*/
public function disable_admin_options( $types ) {
foreach ( $types as $key => $value ) {
if ( $this->is_disabled( $key ) ) {
unset( $types[ $key ] );
}
}
return $types;
}
/**
* Removes product type page from `wc_get_account_menu_items()`
*
* #param array $items
* #return array
*/
public function disable_frontend_nav_items( $items ) {
foreach ( $items as $key => $value ) {
if ( $this->is_disabled( $key ) ) {
unset( $items[ $key ] );
}
}
return $items;
}
/**
* Removes the downloads metabox from orders.
*/
public function disable_admin_metabox() {
if ( $this->is_disabled( 'downloadable' ) ) {
remove_meta_box( 'woocommerce-order-downloads', 'shop_order', 'normal' );
}
}
/**
* Add our admin product table filter modifier.
*
* #param array $filters
* #return array
*/
public function disable_admin_filters( $filters ) {
if ( isset( $filters[ 'product_type' ] ) ) {
$filters[ 'product_type' ] = [ $this, 'disable_product_type_filters' ];
}
return $filters;
}
/**
* Remove disabled product types from the admin products table filters.
*/
public function disable_product_type_filters() {
$current_product_type = isset( $_REQUEST['product_type'] ) ? wc_clean( wp_unslash( $_REQUEST['product_type'] ) ) : false; // WPCS: input var ok, sanitization ok.
$output = '<select name="product_type" id="dropdown_product_type"><option value="">' . esc_html__( 'Filter by product type', 'woocommerce' ) . '</option>';
foreach ( wc_get_product_types() as $value => $label ) {
$output .= '<option value="' . esc_attr( $value ) . '" ';
$output .= selected( $value, $current_product_type, false );
$output .= '>' . esc_html( $label ) . '</option>';
if ( 'simple' === $value ) {
if ( !$this->is_disabled( 'downloadable' ) ) {
$output .= '<option value="downloadable" ';
$output .= selected( 'downloadable', $current_product_type, false );
$output .= '> ' . ( is_rtl() ? '←' : '→' ) . ' ' . esc_html__( 'Downloadable', 'woocommerce' ) . '</option>';
}
if ( !$this->is_disabled( 'virtual' ) ) {
$output .= '<option value="virtual" ';
$output .= selected( 'virtual', $current_product_type, false );
$output .= '> ' . ( is_rtl() ? '←' : '→' ) . ' ' . esc_html__( 'Virtual', 'woocommerce' ) . '</option>';
}
}
}
$output .= '</select>';
echo $output; // WPCS: XSS ok.
}
}
File: functions.php
include_once get_theme_file_path( 'path/to/class-disablewoocommerceproducttypes.php' );
new DisableWooCommerceProductTypes();
By default the above will disable both downloadable and virtual product types.
To disable a single product type simply pass the type to the class constructor...
// Example usage for just `downloadable` product type
new DisableWooCommerceProductTypes( 'downloadable' );
// Example usage for just `virtual` product type
new DisableWooCommerceProductTypes( 'virtual' );
There are a couple of extra steps to completely remove the functionality.
Reviewing them all:
as per Osmar Sanches and MD Ashik answers, clear the endpoint on WooCommerce > Settings > Advanced > Downloads
add the filter product_type_options as per Maher Aldous answer
remove the "Dropdown Options from Product Type Filter" as per this blog post by Misha Rudrasyth:
add_filter( 'woocommerce_products_admin_list_table_filters', function( $filters ) {
if( isset( $filters[ 'product_type' ] ) ) {
$filters[ 'product_type' ] = 'misha_product_type_callback';
}
return $filters;
});
function misha_product_type_callback(){
$current_product_type = isset( $_REQUEST['product_type'] ) ? wc_clean( wp_unslash( $_REQUEST['product_type'] ) ) : false;
$output = '<select name="product_type" id="dropdown_product_type"><option value="">Filter by product type</option>';
foreach ( wc_get_product_types() as $value => $label ) {
$output .= '<option value="' . esc_attr( $value ) . '" ';
$output .= selected( $value, $current_product_type, false );
$output .= '>' . esc_html( $label ) . '</option>';
}
$output .= '</select>';
echo $output;
}
Remove the metabox "Downloadable product permissions" from Orders (edit and new):
add_filter('add_meta_boxes', function() {
remove_meta_box('woocommerce-order-downloads', 'shop_order', 'normal');
}, 99 );
CSS fix... no tampering with the functions.
.woocommerce-MyAccount-navigation-link--downloads {
display: none;
}
Was having the same problem and just fixed it.
Open this file:
...\www\Your_website_folder\wp-content\plugins\woocommerce\includes\wc_account-functions.php
now search for the wc_get_account_menu_items() function (line 78)
now replace this line (line 91)
'downloads' => __( 'Downloads', 'woocommerce' ),
with this one
/* 'downloads' => __( 'Downloads', 'woocommerce' ),*/
That's it.
Related
I'm trying to display the attribute description of an attribute on a single product page in an accordeon. I've read a lot of tutorials and about term description, i tried it via ACF fields, but i didnt' find a way to handle this.
I found this thread here on stackoverflow but it is just for the title of an attribute: Woocommerce - Display single product attribute(s) with shortcodes in Frontend
Is there a solution to display the descripton of an attribute in Woocommerce as a shortcode? Maybe there is one standard woocommerce shortcode?
Here is an example code, I am not making an accordion here, but I am providing $values array with term_id, name, slug & description You can use the array and create an accordion with your own design.
/**
* Callback to `vkh_display_attribute_accordian` shortcode.
*
* #param array $atts Shortcode attributes.
* #return string Shortcode output.
* #throws Exception Throws an error when available.
*/
function vkh_display_attribute_accordian_shortcode( $atts ) {
// Don't run if admin page or not a single product page.
if ( is_admin() || ! is_product() ) {
return;
}
// Prepare shortcode attributes.
$atts = shortcode_atts(
array(
'name' => '',
),
$atts,
'vkh_display_attribute_accordian'
);
try {
if ( empty( $atts['name'] ) ) {
throw new Exception( __( 'Please pass the attribute slug as name attribute. e.g. [vkh_display_attribute_accordian name="#YOUR_ATTRIBUTE_SLUG"].', 'text-domain' ) );
}
global $product;
$attributes = $product->get_attributes();
if ( empty( $attributes ) ) {
throw new Exception( __( 'Product does not have any attributes.', 'text-domain' ) );
}
$selected_attr = '';
foreach ( $attributes as $attribute ) {
if ( $attribute->is_taxonomy() && $attribute->get_name() === $atts['name'] ) {
$selected_attr = $attribute;
break;
}
}
if ( empty( $selected_attr ) || ! $selected_attr->is_taxonomy() ) {
throw new Exception( __( 'Unable to find matching attributes.', 'text-domain' ) );
}
$attribute_values = wc_get_product_terms( $product->get_id(), $attribute->get_name(), array( 'fields' => 'all' ) );
if ( empty( $attribute_values ) ) {
throw new Exception( __( 'Product does not have any attribute values.', 'text-domain' ) );
}
$values = array_map(
function( $_term ) {
return (object) array(
'term_id' => $_term->term_id,
'name' => $_term->name,
'slug' => $_term->slug,
'description' => term_description( $_term ),
);
},
$attribute_values
);
ob_start();
var_dump( $values );
$content = ob_get_clean();
return '<pre>'.$content.'</pre>';
} catch ( Exception $e ) {
if ( $e->getMessage() ) {
if ( current_user_can( 'manage_options' ) ) {
return '<p>' . esc_html( $e->getMessage() ) . '</p>';
}
}
}
}
add_shortcode( 'vkh_display_attribute_accordian', 'vkh_display_attribute_accordian_shortcode' );
I have a wordpress plugin that I'm looking to call one of the functions on a custom template. The function I want to call is get_ship_now_adjust_date_link.
Is it possible to just do the following on a template:
echo get_ship_now_adjust_date_link( $subscription['id'] );
Here's the plugins full code:
<?php
namespace Javorszky\Toolbox;
add_filter( 'wcs_view_subscription_actions', __NAMESPACE__ . '\\add_ship_reschedule_action', 10, 2 );
add_action( 'wp_loaded', __NAMESPACE__ . '\\handle_ship_now_adjust_date_request' );
/**
* Extra actions on the subscription. Only there if the subscription is active.
*
* #param array $actions existing actions on the subscription
* #param \WC_Subscription $subscription the subscription we're adding new actions to
* #return array $actions
*/
function add_ship_reschedule_action( $actions, $subscription ) {
$next_timestamp = $subscription->get_time( 'next_payment' );
if ( 0 != $next_timestamp && 'active' == $subscription->get_status() ) {
$new_actions = array(
'ship_now_recalculate' => array(
'url' => get_ship_now_adjust_date_link( $subscription ),
'name' => Utilities\replace_key_dates( Utilities\get_button_text( 'ship_reschedule_button_text', 'Ship now and recalculate from today' ), $subscription ),
),
);
$actions = array_merge( $actions, $new_actions );
}
return $actions;
}
/**
* URL to be used on the "Ship now and adjust the date" button.
*
* #param \WC_Subscription $subscription Subscription we're getting the link for
* #return string URL to trigger shipping now and keeping the date with
*/
function get_ship_now_adjust_date_link( $subscription ) {
if ( version_compare( \WC_Subscriptions::$version, '2.6.0', '>=' ) ) {
$completed_payments = $subscription->get_payment_count('completed');
} else {
$completed_payments = $subscription->get_completed_payment_count();
}
$action_link = Utilities\strip_custom_query_args();
$action_link = add_query_arg( array( 'subscription_id' => $subscription->get_id(), 'ship_now_adjust_date' => 1 ), $action_link );
$action_link = wp_nonce_url( $action_link, $subscription->get_id() . '_completed_adjust_' . $completed_payments );
return $action_link;
}
/**
* Hooked into `wp_loaded`, this is responsible for charging the subscription now and adjusting the date if certain
* GET variables are present.
*/
function handle_ship_now_adjust_date_request() {
if ( isset( $_GET['ship_now_adjust_date'] ) && isset( $_GET['subscription_id'] ) && isset( $_GET['_wpnonce'] ) && !isset( $_GET['wc-ajax'] ) ) {
$user_id = get_current_user_id();
$subscription = wcs_get_subscription( $_GET['subscription_id'] );
$nonce = $_GET['_wpnonce'];
if ( Utilities\Process\process_ship_now_adjust_date( $user_id, $subscription, $nonce ) ) {
wc_add_notice( _x( 'Your order has been placed!', 'Notice after ship now adjust date request succeeded.', 'jg-toolbox' ) );
wp_safe_redirect( wc_get_endpoint_url( 'view-subscription', $subscription->get_id(), wc_get_page_permalink( 'myaccount' ) ) );
exit;
}
}
}
try to use \Javorszky\Toolbox\get_ship_now_adjust_date_link
I have a WordPress Woo-commerce store with the Pro version of the delivery drivers for woo-commerce plugin (https://wordpress.org/plugins/delivery-drivers-for-woocommerce/).
Everything works fine as any user who is of user role : 'delivery driver' can view and claim all orders that are processed through the website, at the moment using woo-commerce delivery/shipping zones settings I have configured it so only customers who reside in a certain city can place an order and I am only approving delivery drivers in that area.
But I want to roll this out to other cities, I can add the postcodes so users can order from those postcodes but the problem is with the delivery drivers plugin - drivers will see all orders from all cities in their dashboard. I only want the drivers to view and claim orders in the city they reside in (the city they have assigned themselves to).
Here is the code to the functionality that displays all orders placed on the website to user role type 'delivery driver' :
driver-dashboard-shortcode.php
<?php
/**
* The Unclaimed Orders Shortcode.
**/
function ddwc_pro_dashboard_shortcode() {
// Check if user is logged in.
if ( is_user_logged_in() ) {
// Get the user ID.
$user_id = get_current_user_id();
// Get the user object.
$user_meta = get_userdata( $user_id );
// If user_id doesn't equal zero.
if ( 0 != $user_id ) {
// If claim delivery button is pushed.
if ( ! empty( $_GET['claim_delivery'] ) ) {
// Get deliver ID to claim.
$claim_delivery = $_GET['claim_delivery'];
// Update order status.
$order = wc_get_order( $claim_delivery );
$order->update_status( 'driver-assigned' );
// Update order with driver ID.
update_post_meta( $claim_delivery, 'ddwc_driver_id', $user_id, -1 );
// Redirect URL.
$redirect_url = apply_filters( 'ddwc_pro_claim_order_redirect_url', get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ) . '/driver-dashboard/?orderid=' . $claim_delivery, $claim_delivery );
// Redirect driver to the order details.
wp_redirect( $redirect_url );
}
// Get all the user roles as an array.
$user_roles = $user_meta->roles;
// Check if the role you're interested in, is present in the array.
if ( in_array( 'driver', $user_roles, true ) ) {
// Set variable for driver ID.
if ( isset( $_GET['orderid'] ) && ( '' != $_GET['orderid'] ) ) {
$driver_id = get_post_meta( $_GET['orderid'], 'ddwc_driver_id', true );
}
/**
* Args for Orders with no driver ID attached.
*/
$args = array(
'post_type' => 'shop_order',
'posts_per_page' => -1,
'post_status' => 'any',
'post_parent' => 0
);
/**
* Get Orders with Driver ID attached
*/
$unclaimed_orders = get_posts( $args );
/**
* If there are orders to loop through.
*/
if ( $unclaimed_orders ) {
// Total for table thead.
$total_title = '<td>' . esc_attr__( 'Total', 'ddwc' ) . '</td>';
do_action( 'ddwc_pro_unclaimed_orders_table_before' );
echo '<table class="ddwc-dashboard">';
echo '<thead><tr><td>' . esc_attr__( 'Date', 'ddwc-pro' ) . '</td><td>' . esc_attr__( 'Address', 'ddwc-pro' ) . '</td>' . apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_total_title', $total_title ) . '<td></td></tr></thead>';
echo '<tbody>';
do_action( 'ddwc_pro_unclaimed_orders_table_tbody_before' );
foreach ( $unclaimed_orders as $driver_order ) {
// Get Driver ID (if set).
$driver_id_setting = get_post_meta( $driver_order->ID, 'ddwc_driver_id', TRUE );
// Get an instance of the WC_Order object.
$order = wc_get_order( $driver_order->ID );
// Get the required order data.
$order_data = $order->get_data();
$currency_code = $order_data['currency'];
$currency_symbol = get_woocommerce_currency_symbol( $currency_code );
$order_id = $order_data['id'];
$order_status = $order_data['status'];
$order_date_created = $order_data['date_created']->date( 'm-d-Y' );
## CART INFORMATION:
$order_total = $order_data['total'];
## BILLING INFORMATION:
$order_billing_city = $order_data['billing']['city'];
$order_billing_state = $order_data['billing']['state'];
$order_billing_postcode = $order_data['billing']['postcode'];
## SHIPPING INFORMATION:
$order_shipping_city = $order_data['shipping']['city'];
$order_shipping_state = $order_data['shipping']['state'];
$order_shipping_postcode = $order_data['shipping']['postcode'];
// Create address to use in the table.
$address = $order_billing_city . ' ' . $order_billing_state . ', ' . $order_billing_postcode;
// Set address to shipping (if available).
if ( isset( $order_shipping_city ) ) {
$address = $order_shipping_city . ' ' . $order_shipping_state . ', ' . $order_shipping_postcode;
}
// Allowed statuses.
$status_array = apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_status_array', array( 'processing' ) );
// Display unassigned orders.
if ( in_array( $order_status, $status_array ) && ( -1 == $driver_id_setting || '' === $driver_id_setting ) ) {
echo '<tr>';
echo '<td>' . $order_date_created . '</td>';
echo '<td>' . apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_table_address', $address ) . '</td>';
if ( isset( $order_total ) ) {
$order_total = '<td>' . $currency_symbol . $order_total . '</td>';
echo apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_total', $order_total );
} else {
echo '<td>-</td>';
}
echo '<td>' . apply_filters( 'ddwc_pro_driver_dashboard_unclaimed_orders_button_text', __( 'CLAIM', 'ddwc-pro' ) ) . '</td>';
echo '</tr>';
} else {
// Do nothing.
}
}
do_action( 'ddwc_pro_unclaimed_orders_table_tbody_after' );
echo '</tbody>';
echo '</table>';
do_action( 'ddwc_pro_unclaimed_orders_table_after' );
// Driver dashboard button.
$dashboard_button = '← ' . __( 'Driver Dashboard', 'ddwc-pro' ) . '';
// Filter "Driver Dashboard" button.
echo apply_filters( 'ddwc_pro_back_to_driver_dashboard_button', $dashboard_button );
} else {
do_action( 'ddwc_pro_assigned_orders_empty_before' );
// Message - No assigned orders.
$empty = '<h3 class="ddwc assigned-orders">' . __( 'Assigned Orders', 'ddwc-pro' ) . '</h3>';
$empty .= '<p>' . __( 'You do not have any assigned orders.', 'ddwc-pro' ) . '</p>';
echo apply_filters( 'ddwc_pro_assigned_orders_empty', $empty );
do_action( 'ddwc_pro_assigned_orders_empty_after' );
}
} else {
// Set the Access Denied page text.
$access_denied = '<h3 class="ddwc access-denied">' . __( 'Access Denied', 'ddwc-pro' ) . '</h3><p>' . __( 'Sorry, but you are not able to view this page.', 'ddwc-pro' ) . '</p>';
// Filter Access Denied text.
echo apply_filters( 'ddwc_access_denied', $access_denied );
}
} else {
// Do nothing.
}
} else {
apply_filters( 'ddwc_pro_dashboard_login_form', wp_login_form() );
}
}
add_shortcode( 'ddwc_pro_dashboard', 'ddwc_pro_dashboard_shortcode' );
I had thought of a way to implement this functionality - I have created a custom field (just for delivery drivers) in the woocommerce account details section 'my-account/edit-account'. The field is a dropdown list of cities a delivery driver can assign to himself in his account details.
And I want to call a function that checks if the 'town/city' address label matches the selected city in a drivers profile, if it does then the driver can see that order (orders). If a driver has not selected a city in that drop-down then he will not see any orders.
Here is how I have added the drop-down city list:
<?php
/**
* Get additional account fields.
*
* #return array
*/
function iconic_get_account_fields() {
return apply_filters( 'iconic_account_fields', array(
'city_select' => array(
'type' => 'select',
'label' => __( 'Select City', 'iconic' ),
'hide_in_account' => false,
'hide_in_admin' => false,
'required' => false,
'options' => array(
'' => __( 'Select an option...', 'iconic' ),
1 => __( 'Manchester', 'iconic' ),
2 => __( 'Birmingham', 'iconic' ),
3 => __( 'London', 'iconic' ),
),
'bank_name' => array(
'type' => 'text',
'label' => __( 'Bank Name', 'iconic' ),
'hide_in_account' => false,
'hide_in_admin' => false,
'required' => false,
),
) );
}
/**
* Add post values to account fields if set.
*
* #param array $fields
*
* #return array
*/
function iconic_add_post_data_to_account_fields( $fields ) {
if ( empty( $_POST ) ) {
return $fields;
}
foreach ( $fields as $key => $field_args ) {
if ( empty( $_POST[ $key ] ) ) {
$fields[ $key ]['value'] = '';
continue;
}
$fields[ $key ]['value'] = $_POST[ $key ];
}
return $fields;
}
add_filter( 'iconic_account_fields', 'iconic_add_post_data_to_account_fields', 10, 1 );
/**
* Add field to account area.
*/
function iconic_print_user_frontend_fields() {
$fields = iconic_get_account_fields();
$is_user_logged_in = is_user_logged_in();
foreach ( $fields as $key => $field_args ) {
$value = null;
if ( ! iconic_is_field_visible( $field_args ) ) {
continue;
}
if ( $is_user_logged_in ) {
$user_id = iconic_get_edit_user_id();
$value = iconic_get_userdata( $user_id, $key );
}
$value = isset( $field_args['value'] ) ? $field_args['value'] : $value;
woocommerce_form_field( $key, $field_args, $value );
}
}
add_action( 'woocommerce_edit_account_form', 'iconic_print_user_frontend_fields', 10 ); // my account
/**
* Get user data.
*
* #param $user_id
* #param $key
*
* #return mixed|string
*/
function iconic_get_userdata( $user_id, $key ) {
if ( ! iconic_is_userdata( $key ) ) {
return get_user_meta( $user_id, $key, true );
}
$userdata = get_userdata( $user_id );
if ( ! $userdata || ! isset( $userdata->{$key} ) ) {
return '';
}
return $userdata->{$key};
}
/**
* Get currently editing user ID (frontend account/edit profile/edit other user).
*
* #return int
*/
function iconic_get_edit_user_id() {
return isset( $_GET['user_id'] ) ? (int) $_GET['user_id'] : get_current_user_id();
}
/**
* Save registration fields.
*
* #param int $customer_id
*/
function iconic_save_account_fields( $customer_id ) {
$fields = iconic_get_account_fields();
$sanitized_data = array();
foreach ( $fields as $key => $field_args ) {
if ( ! iconic_is_field_visible( $field_args ) ) {
continue;
}
$sanitize = isset( $field_args['sanitize'] ) ? $field_args['sanitize'] : 'wc_clean';
$value = isset( $_POST[ $key ] ) ? call_user_func( $sanitize, $_POST[ $key ] ) : '';
if ( iconic_is_userdata( $key ) ) {
$sanitized_data[ $key ] = $value;
continue;
}
update_user_meta( $customer_id, $key, $value );
}
if ( ! empty( $sanitized_data ) ) {
$sanitized_data['ID'] = $customer_id;
wp_update_user( $sanitized_data );
}
}
add_action( 'personal_options_update', 'iconic_save_account_fields' ); // edit own account admin
add_action( 'edit_user_profile_update', 'iconic_save_account_fields' ); // edit other account
add_action( 'woocommerce_save_account_details', 'iconic_save_account_fields' ); // edit WC account
/**
* Is this field core user data.
*
* #param $key
*
* #return bool
*/
function iconic_is_userdata( $key ) {
$userdata = array(
'user_pass',
'user_login',
'user_nicename',
'user_url',
'user_email',
'display_name',
'nickname',
'first_name',
'last_name',
'description',
'rich_editing',
'user_registered',
'role',
'jabber',
'aim',
'yim',
'show_admin_bar_front',
);
return in_array( $key, $userdata );
}
/**
* Is field visible.
*
* #param $field_args
*
* #return bool
*/
function iconic_is_field_visible( $field_args ) {
$visible = true;
$action = filter_input( INPUT_POST, 'action' );
if ( is_admin() && ! empty( $field_args['hide_in_admin'] ) ) {
$visible = false;
} elseif ( ( is_account_page() || $action === 'save_account_details' ) && is_user_logged_in() && ! empty( $field_args['hide_in_account'] ) ) {
$visible = false;
}
return $visible;
}
/**
* Add fields to admin area.
*/
function iconic_print_user_admin_fields() {
$fields = iconic_get_account_fields();
?>
<h2><?php _e( 'Additional Information', 'iconic' ); ?></h2>
<table class="form-table" id="iconic-additional-information">
<tbody>
<?php foreach ( $fields as $key => $field_args ) { ?>
<?php
if ( ! iconic_is_field_visible( $field_args ) ) {
continue;
}
$user_id = iconic_get_edit_user_id();
$value = iconic_get_userdata( $user_id, $key );
?>
<tr>
<th>
<label for="<?php echo $key; ?>"><?php echo $field_args['label']; ?></label>
</th>
<td>
<?php $field_args['label'] = false; ?>
<?php woocommerce_form_field( $key, $field_args, $value ); ?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<?php
}
add_action( 'show_user_profile', 'iconic_print_user_admin_fields', 30 ); // admin: edit profile
add_action( 'edit_user_profile', 'iconic_print_user_admin_fields', 30 ); // admin: edit other users
/**
* Validate fields on frontend.
*
* #param WP_Error $errors
*
* #return WP_Error
*/
function iconic_validate_user_frontend_fields( $errors ) {
$fields = iconic_get_account_fields();
foreach ( $fields as $key => $field_args ) {
if ( empty( $field_args['required'] ) ) {
continue;
}
if ( ! isset( $_POST['register'] ) && ! empty( $field_args['hide_in_account'] ) ) {
continue;
}
if ( empty( $_POST[ $key ] ) ) {
$message = sprintf( __( '%s is a required field.', 'iconic' ), '<strong>' . $field_args['label'] . '</strong>' );
$errors->add( $key, $message );
}
}
return $errors;
}
add_filter( 'woocommerce_save_account_details_errors', 'iconic_validate_user_frontend_fields', 10 )
I am a novice to programming (especially PHP) I have tried different ways in adding a if statement to check if I can make functionality where before it displays the list of orders in the table, it checks if the drivers selected city matches the city in the customers address and then displays the same orders as the city the driver resides in, if not no orders should be displayed.
But I keep breaking my site, any assistance would be appreciated (as im beginning to think maybe this is not the file to add this sort of function).
Here's what I would do:
On the site options side (custom, or trough woocommerce delivery zone options):
Admin store a list of cities, with name and ID
You could do an ACF option field list, where you can fill a City name, and an ID (or postcode) (to prevent make queries based on cities name only)
Woocommerce also has delivery options where you can store shipping areas, so you could store your cities here and use them. Depending on how you integrated with Woocommerce.
On the user/driver side:
Your additional city field should let the user be able to select multiple cities from the list you defined
Data will store as a user_meta a serialized array of IDs or Postcode from selected cities
So each driver has a postcode/IDs of cities stored as user meta, that he can edits
On the order checkout process side :
If the postcode of delivery address is "locked" to the available cities list you made: great
If the postcode is a free field, you'll need to add something so the order is associated with a postcode/ID of the available city you've defined. To be able to match drivers and orders.
Depending on your checkout process, you could add an order field so the customer selects a city based on your admin list. Or make the postal_code field limited to your list. You need something so an order can be matched to one of the cities from your list.
On the driver orders list page :
You'll edit the WP_query querying that query orders, to add a meta_query
meta_query will query orders based on the postcode/IDs of user_meta from the current user driver
You are able to foreach on the user meta array values, and add meta_query "OR" for each drivers cities ID/Postcode to the orders query
order matching one of the driver's city IDs/postcodes will be displayed
I'm trying to bypass the single product page so I've created a custom template page for my subscriptions. On this page I'm generating the buttons to either allow users to signup for a specific subscription or switch their subscription. The problem I'm running into is getting the Switch Subscription URL to go to cart instead of the single product page.
The function below will test whether the user is logged in, if they are not show the add subscription to cart URL. If they are show the switch subscription url which I'm trying to just add it to cart ( or go straight to checkout ).
/**
* Get Subscription URL ( Initial or Switch Subscription ) by Subscription ID
*
* #param Integer $subscription_id
*
* #return void
*/
function woo_subscriptions_checkout_url( $subscription_id, $echo = true ) {
$subscription_id = intval( $subscription_id );
$subscription_url = do_shortcode( '[add_to_cart_url id="' . $subscription_id . '"]' );
if( is_user_logged_in() && function_exists( 'wcs_get_users_subscriptions' ) ) {
$user_subscriptions = wcs_get_users_subscriptions();
if( ! empty( $user_subscriptions ) ) {
foreach( $user_subscriptions as $subscription ) {
$subscription_order_id = $subscription->get_parent_id();
$subscription_key = wcs_get_old_subscription_key( $subscription );
if( ! empty( $subscription_key ) ) {
$plan_parent_id = wp_get_post_parent_id( $subscription_id );
$subscription_url = WC_Subscriptions_Switcher::add_switch_query_arg_post_link( get_permalink( wc_get_page_id( 'subscriptions' ) ), $plan_parent_id );
// Failed Test, Goes to Product
// $subscription_url = WC_Subscriptions_Switcher::get_switch_url( $subscription_order_id, array( 'product_id' => $plan_parent_id ), $subscription );
}
}
}
}
if( $echo ) {
echo $subscription_url;
} else {
return $subscription_url;
}
}
Additional information: There is 1 product with subscriptions as variations. I'm passing the Variation ID to this function in hopes of generating the correct URL.
Here's what we got. We can add it to cart with specific URL arguments: Product, User Subscription ID, New Subscription ID, Subscription Order Line Number, and a nonce. Do not we did this on a single product with subscriptions as variations. This may need to be tweaked in other subscription cases but hopefully it's helpful to someone down the road:
/**
* Generate cart button based on subscription variation ID
*
* #param Array $args
*
* #return void
*/
function prefix_subscriptions_checkout_button( $args = array() ) {
$button_arr = wp_parse_args( $args, array(
'variation_id' => 0,
'btn_class' => array( 'button', 'button-primary' ),
'btn_text' => __( 'Sign Up' ),
'btn_atts' => array(),
) );
$button_arr['btn_url'] = do_shortcode( '[add_to_cart_url id="' . intval( $button_arr['variation_id'] ) . '"]' );
if( is_user_logged_in() && function_exists( 'wcs_get_users_subscriptions' ) ) {
// Grab an array of user subscriptions
$user_subscriptions = wcs_get_users_subscriptions();
if( ! empty( $user_subscriptions ) ) {
// Array( 'Subscription ID' => WC_Subscriptions Object );
foreach( $user_subscriptions as $user_subscription_id => $subscription ) {
// Loop through the users subscription order items to get the subscription order line item
foreach( $subscription->get_items() as $item_line_number => $item_arr ) {
if( $user_subscription_id == $item_arr['order_id'] ) {
if( $item_arr['variation_id'] == $button_arr['variation_id'] ) {
// Change button based on status
switch( $subscription->get_status() ) {
case 'on-hold':
$button_arr['btn_text'] = __( 'On Hold' );
$button_arr['btn_class'] = array( 'button', 'button-secondary' );
$button_arr['btn_url'] = 'javascript:void(0);';
break;
case 'active':
$button_arr['btn_text'] = __( 'Current' );
$button_arr['btn_class'] = array( 'button', 'button-secondary' );
$button_arr['btn_url'] = 'javascript:void(0);';
break;
default:
$button_arr['btn_url'] = add_query_arg( array(
'add-to-cart' => $item_arr['product_id'],
'switch-subscription' => $user_subscription_id,
'variation_id' => $button_arr['variation_id'],
'item' => $item_line_number,
'_wcsnonce' => wp_create_nonce( 'wcs_switch_request' )
),
wc_get_cart_url()
);
}
}
}
}
}
}
}
// Create button attributes
$button_atts = '';
if( ! empty( $button_arr['btn_atts'] ) && is_array( $button_arr['btn_atts'] ) ) {
foreach( $button_arr['btn_atts'] as $attribute => $value ) {
$button_atts .= sprintf( ' %1$s="%2$s"', esc_attr( $attribute ), esc_attr( $value ) );
}
}
// Create button Classes
if( ! empty( $button_arr['btn_class'] ) && is_array( $button_arr['btn_class'] ) ) {
array_walk( $button_arr['btn_class'], 'esc_attr' );
$button_arr['btn_class'] = implode( ' ', $button_arr['btn_class'] );
}
// Display Button
printf( '<a href="%1$s" class="%2$s"%3$s>%4$s</a>',
$button_arr['btn_url'],
esc_attr( $button_arr['btn_class'] ),
( ! empty( $button_atts ) ) ? $button_atts : '',
$button_arr['btn_text']
);
}
I searched and did not find this question has been posted before.
At the top of each post the meta data is displayed including author, entry date, updated date, and taxonomy. Each of these also include a url. I want to display the metas but remove the links. I have found the php file and succesfully modified it to achieve desired result. What I need help with is how to make these modifications within my child theme so the changes are not overridden after a theme update.
I have been trying to get some guidance from the theme publisher on their github account but so far no response.
Customizr Free version 4.0.11
Here are the details:
I was able to locate the php file: core/front/models/content/post-metas/class-model-post_metas.php
And I was able to locate and modify the portion of the function that inserts the url link into the author-meta element. NOTE, the example below only removes links from the author meta tag. Similar modifications are done for the other metas. This is a private function so I don't think I can call this from functions.php.
I made changes to the function named: czr_fn_get_meta_author()
private function czr_fn_get_meta_author() {
$author_id = null;
if ( is_single() )
if ( ! in_the_loop() ) {
global $post;
$author_id = $post->post_author;
}
return apply_filters(
'tc_author_meta',
sprintf( '<span class="author vcard author_name"><a class="url fn n" href="%1$s" title="%2$s" rel="author">%3$s</a></span>' ,
esc_url( get_author_posts_url( get_the_author_meta( 'ID', $author_id ) ) ),
esc_attr( sprintf( __( 'View all posts by %s' , 'customizr' ), get_the_author_meta( 'display_name', $author_id ) ) ),
get_the_author_meta( 'display_name', $author_id )
)
);//end filter
}
And here is the modified version:
private function czr_fn_get_meta_author() {
$author_id = null;
if ( is_single() )
if ( ! in_the_loop() ) {
global $post;
$author_id = $post->post_author;
}
return apply_filters(
'tc_author_meta',
sprintf( '<span class="author vcard author_name">%3$s</span>' ,
esc_url( get_author_posts_url( get_the_author_meta( 'ID', $author_id ) ) ),
esc_attr( sprintf( __( 'View all posts by %s' , 'customizr' ), get_the_author_meta( 'display_name', $author_id ) ) ),
get_the_author_meta( 'display_name', $author_id )
)
);//end filter
}
So I can figure out how to do the same for entry-meta and others. Now I just need to know how to make this work in my child theme so that it will not be erased by updates.
Please and thank you.
I have a potential solution to this issue. I was able to take a copy of the file I listed above 'class-model-post-metas.php' and place that in my child theme using the same directory structure. I then modified the file to check if the user level of the post 'author' is set to subscriber. If so, I strip out the href. Otherwise, normal behavior is performed.
The reason for this is that when adding a user forum plugin called CM Answers Pro, the users are able to login and register using social login (oAuth). I default all new registrations at subscriber level. So all my forum participants are held at subscriber level. Which is what created this issue in the first place. Every time a new post is added to the forum, the user gets tagged as the 'author' of the post. Even though they do not have Author level privileges.
When a single post from the Q&A forum is displayed, Customizr sets the post metas, including links, for the 'author' name and the entry date. These links create 404's because they are constructed making the assumption each post in the Q&A forum is a blog post.
The code below the modifications that correctly remove the links from the post metas when the user is set to subscriber level. The modifications were made to the following two functions: czr_fn_get_meta_date() and czr_fn_get_meta_author(). You can compare this to the original source code available on the Customizr GitHub repo. https://github.com/presscustomizr/customizr
<?php
class CZR_post_metas_model_class extends CZR_Model {
/* PUBLIC GETTERS */
public function czr_fn_get_cat_list( $limit = false, $sep = '' ) {
return 0 != esc_attr( czr_fn_opt( 'tc_show_post_metas_categories' ) ) ? $this -> czr_fn_get_meta( 'categories', $limit, $sep ) : '';
}
public function czr_fn_get_tag_list( $limit = false, $sep = '' ) {
return 0 != esc_attr( czr_fn_opt( 'tc_show_post_metas_tags' ) ) ? $this -> czr_fn_get_meta( 'tags', $limit, $sep ) : '';
}
public function czr_fn_get_author( $before = null ) {
return 0 != esc_attr( czr_fn_opt( 'tc_show_post_metas_author' ) ) ? $this -> czr_fn_get_meta( 'author', array( $before ) ) : '';
}
public function czr_fn_get_publication_date( $permalink = false, $before = null ) {
return 0 != esc_attr( czr_fn_opt( 'tc_show_post_metas_publication_date' ) ) ? $this -> czr_fn_get_meta( 'pub_date', array(
'',
$permalink,
$before = null ) ) : '';
}
public function czr_fn_get_update_date( $permalink = false, $before = null ) {
return 0 != esc_attr( czr_fn_opt( 'tc_show_post_metas_update_date' ) ) &&
false !== czr_fn_post_has_update() ?
$this -> czr_fn_get_meta( 'up_date', array( '', $permalink ) ) : '';
}
/* END PUBLIC GETTERS */
/* HELPERS */
protected function czr_fn_get_meta( $meta, $params = array(), $separator = '' ) {
$params = is_array( $params ) ? $params : array( $params );
return czr_fn_stringify_array( call_user_func_array( array( $this, "czr_fn_meta_generate_{$meta}" ), $params ), $separator );
}
private function czr_fn_meta_generate_categories( $limit = false ) {
return $this -> czr_fn_meta_generate_tax_list( $hierarchical = true, $limit );
}
private function czr_fn_meta_generate_tags( $limit = false ) {
return $this -> czr_fn_meta_generate_tax_list( $hierarchical = false, $limit );
}
private function czr_fn_meta_generate_author( $before ) {
$author = $this -> czr_fn_get_meta_author();
$before = is_null($before) ? __( 'by ', 'customizr-child' ) :'';
return '<span class="author-meta">' . $before . $author . '</span>';
}
private function czr_fn_meta_generate_pub_date( $format = '', $permalink = false, $before = null ) {
$date = $this -> czr_fn_get_meta_date( 'publication', $format, $permalink );
$before = is_null($before) ? __( 'Published ', 'customizr' ) :'';
return $before . $date;
}
private function czr_fn_meta_generate_up_date( $format = '', $permalink = false, $before = null ) {
$date = $this -> czr_fn_get_meta_date( 'update', $format, $permalink );
$before = is_null($before) ? __( 'Updated ', 'customizr' ) :'';
return $before . $date;
}
protected function czr_fn_get_term_css_class( $_is_hierarchical ) {
$_classes = array();
if ( $_is_hierarchical )
array_push( $_classes , 'tax__link' );
else
array_push( $_classes , 'tag__link btn btn-skin-dark-oh inverted' );
return $_classes;
}
/**
* Helper
* Return the date post metas
*
* #package Customizr
* #since Customizr 3.2.6
*/
protected function czr_fn_get_meta_date( $pub_or_update = 'publication', $_format = '', $permalink = false ) {
if ( 'short' == $_format )
$_format = 'j M, Y';
$_format = apply_filters( 'czr_meta_date_format' , $_format );
$_use_post_mod_date = apply_filters( 'czr_use_the_post_modified_date' , 'publication' != $pub_or_update );
// get user level to be used to turn meta links on or off
$subscriber_level = get_the_author_meta('user_level');
if ($subscriber_level == 0) {
// user is a subscriber
return apply_filters(
'tc_date_meta',
sprintf( '<span><time class="entry-date %3$s" datetime="%4$s">%5$s</time></span>' ,
$permalink ? esc_url( get_the_permalink() ) : esc_url( get_day_link( get_the_time( 'Y' ), get_the_time( 'm' ), get_the_time( 'd' ) ) ),
$permalink ? esc_attr( the_title_attribute( array( 'before' => __('Permalink to: ', 'customizr'), 'echo' => false ) ) ) : esc_attr( get_the_time() ),
'publication' == $pub_or_update ? 'published updated' : 'updated',
$_use_post_mod_date ? esc_attr( get_the_modified_date('c') ) : esc_attr( get_the_date( 'c' ) ),
$_use_post_mod_date ? esc_html( get_the_modified_date( $_format ) ) : esc_html( get_the_date( $_format ) )
),
$_use_post_mod_date,
$_format
);//end filter
} else {
// user is not a subscriber
return apply_filters(
'tc_date_meta',
sprintf( '<time class="entry-date %3$s" datetime="%4$s">%5$s</time>' ,
$permalink ? esc_url( get_the_permalink() ) : esc_url( get_day_link( get_the_time( 'Y' ), get_the_time( 'm' ), get_the_time( 'd' ) ) ),
$permalink ? esc_attr( the_title_attribute( array( 'before' => __('Permalink to: ', 'customizr'), 'echo' => false ) ) ) : esc_attr( get_the_time() ),
'publication' == $pub_or_update ? 'published updated' : 'updated',
$_use_post_mod_date ? esc_attr( get_the_modified_date('c') ) : esc_attr( get_the_date( 'c' ) ),
$_use_post_mod_date ? esc_html( get_the_modified_date( $_format ) ) : esc_html( get_the_date( $_format ) )
),
$_use_post_mod_date,
$_format
);//end filter
}
}
/**
* Helper
* Return the post author metas
*
* #package Customizr
* #since Customizr 3.2.6
*/
// LET'S SEE IF WE CAN UPDATE THIS FUNCTION TO CHECK IF 'AUTHOR' IS ACTUALLY AN AUTHOR
// BECUASE POSTS FROM THE CM ANSWERS PLUGIN ARE SUBSCRIBERS
private function czr_fn_get_meta_author() {
$author_id = null;
if ( is_single() )
$subscriber_level = 0;
if ( ! in_the_loop() ) {
global $post;
$author_id = $post->post_author;
}
$subscriber_level = get_the_author_meta('user_level');
// if ($subscriber_level == 0) {
// print_r("Subscriber ");
// } else {
// print_r("Not Subscriber ");
// }
if($subscriber_level == 0) {
// user role is subscriber
return apply_filters(
'tc_author_meta',
sprintf( '<span class="author vcard author_name">%3$s</span>' ,
esc_url( get_author_posts_url( get_the_author_meta( 'ID', $author_id ) ) ),
esc_attr( sprintf( __( 'View all posts by %s' , 'customizr' ), get_the_author_meta( 'display_name', $author_id ) ) ),
get_the_author_meta( 'display_name', $author_id )
)
);//end filter
} else {
// user role is higher than subscriber level
return apply_filters(
'tc_author_meta',
sprintf( '<span class="author vcard author_name"><a class="url fn n" href="%1$s" title="%2$s" rel="author">%3$s</a></span>' ,
esc_url( get_author_posts_url( get_the_author_meta( 'ID', $author_id ) ) ),
esc_attr( sprintf( __( 'View all posts by %s' , 'customizr' ), get_the_author_meta( 'display_name', $author_id ) ) ),
get_the_author_meta( 'display_name', $author_id )
)
);//end filter
}
}
/**
* Helper
* #return string of all the taxonomy terms (including the category list for posts)
* #param hierarchical tax boolean => true = categories like, false = tags like
*
* #package Customizr
* #since Customizr 3.0
*/
private function czr_fn_meta_generate_tax_list( $hierarchical, $limit = false ) {
$post_terms = $this -> czr_fn_get_term_of_tax_type( $hierarchical, $limit );
if ( ! $post_terms )
return;
$_terms_html_array = array_map( array( $this , 'czr_fn_meta_term_view' ), $post_terms );
return $_terms_html_array;
}
/**
* Helper
* #return string of the single term view
* #param $term object
*
* #package Customizr
* #since Customizr 3.3.2
*/
private function czr_fn_meta_term_view( $term ) {
$_is_hierarchical = is_taxonomy_hierarchical( $term -> taxonomy );
$_classes = czr_fn_stringify_array( apply_filters( 'czr_meta_tax_class', $this -> czr_fn_get_term_css_class( $_is_hierarchical ), $_is_hierarchical, $term ) );
// (Rocco's PR Comment) : following to this https://wordpress.org/support/topic/empty-articles-when-upgrading-to-customizr-version-332
// I found that at least wp 3.6.1 get_term_link($term->term_id, $term->taxonomy) returns a WP_Error
// Looking at the codex, looks like we can just use get_term_link($term), when $term is a term object.
// Just this change avoids the issue with 3.6.1, but I thought should be better make a check anyway on the return type of that function.
$_term_link = is_wp_error( get_term_link( $term ) ) ? '' : get_term_link( $term );
$_to_return = $_term_link ? '<a %1$s href="%2$s" title="%3$s"> <span>%4$s</span> </a>' : '<span %1$s> %4$s </span>';
$_to_return = $_is_hierarchical ? $_to_return : '<li>' . $_to_return . '</li>';
return apply_filters( 'czr_meta_term_view' , sprintf($_to_return,
$_classes ? 'class="'. $_classes .'"' : '',
$_term_link,
esc_attr( sprintf( __( "View all posts in %s", 'customizr' ), $term -> name ) ),
$term -> name
)
);
}
/**
* Helper to return the current post terms of specified taxonomy type : hierarchical or not
*
* #return boolean (false) or array
* #param boolean : hierarchical or not
* #package Customizr
* #since Customizr 3.1.20
*
*/
private function czr_fn_get_term_of_tax_type( $hierarchical = true, $limit = false ) {
//var declaration
$post_type = get_post_type( czr_fn_get_id() );
$tax_list = get_object_taxonomies( $post_type, 'object' );
$_tax_type_list = array();
$_tax_type_terms_list = array();
if ( empty($tax_list) )
return false;
//filter the post taxonomies
while ( $_tax_object = current($tax_list) ) {
// cast $_tax_object stdClass object in an array to access its property 'public'
// fix for PHP version < 5.3 (?)
$_tax_object = (array) $_tax_object;
//Is the object well defined ?
if ( ! isset($_tax_object['name']) ) {
next($tax_list);
continue;
}
$_tax_name = $_tax_object['name'];
//skip the post format taxinomy
if ( ! $this -> czr_fn_is_tax_authorized( $_tax_object, $post_type ) ) {
next($tax_list);
continue;
}
if ( (bool) $hierarchical === (bool) $_tax_object['hierarchical'] )
$_tax_type_list[$_tax_name] = $_tax_object;
next($tax_list);
}
if ( empty($_tax_type_list) )
return false;
$found = 0;
//fill the post terms array
foreach ($_tax_type_list as $tax_name => $data ) {
$_current_tax_terms = get_the_terms( czr_fn_get_id() , $tax_name );
//If current post support this tax but no terms has been assigned yet = continue
if ( ! $_current_tax_terms )
continue;
while( $term = current($_current_tax_terms) ) {
$_tax_type_terms_list[$term -> term_id] = $term;
if ( $limit > 0 && ++$found == $limit )
break 2;
next($_current_tax_terms);
}
}
/*if ( ! empty($_tax_type_terms_list) && $limit > 0 )
$_tax_type_terms_list = array_slice( $_tax_type_terms_list, 0, $limit );
*/
return empty($_tax_type_terms_list) ? false : apply_filters( "czr_tax_meta_list" , $_tax_type_terms_list , $hierarchical );
}
/**
* Helper : check if a given tax is allowed in the post metas or not
* A tax is authorized if :
* 1) not in the exclude list
* 2) AND not private
*
* #return boolean (false)
* #param $post_type, $_tax_object
* #package Customizr
* #since Customizr 3.3+
*
*/
private function czr_fn_is_tax_authorized( $_tax_object , $post_type ) {
$_in_exclude_list = in_array(
$_tax_object['name'],
apply_filters_ref_array ( 'czr_exclude_taxonomies_from_metas' , array( array('post_format') , $post_type , czr_fn_get_id() ) )
);
$_is_private = false === (bool) $_tax_object['public'] && apply_filters_ref_array( 'czr_exclude_private_taxonomies', array( true, $_tax_object['public'], czr_fn_get_id() ) );
return ! $_in_exclude_list && ! $_is_private;
}
/* Customizer: allow dynamic visibility in the preview */
function czr_fn_body_class( $_classes/*array*/ ) {
if ( ! czr_fn_is_customizing() )
return $_classes;
if ( 0 == esc_attr( czr_fn_opt( 'tc_show_post_metas' ) ) )
$_classes[] = 'hide-all-post-metas';
if (
( is_singular() && ! is_page() && ! czr_fn_is_real_home() && 0 == esc_attr( czr_fn_opt( 'tc_show_post_metas_single_post' ) ) ) ||
( ! is_singular() && ! czr_fn_is_real_home() && ! is_page() && 0 == esc_attr( czr_fn_opt( 'tc_show_post_metas_post_lists' ) ) ) ||
( czr_fn_is_real_home() ) && 0 == esc_attr( czr_fn_opt( 'tc_show_post_metas_home' ) )
)
$_classes[] = 'hide-post-metas';
return $_classes;
}
}//end of class