I have a custom post type 'Departments' in Wordpress. When I create a page in this CPT, it automatically creates 3 subpages. That works fine!
But now I want two grandchildren pages to be created automatically and their parent must be Subpage2.
Right now I have it working like this:
Department1
-Subpage1
-Subpage2
-Subpage3
Department2
-Subpage1
-Subpage2
-Subpage3
-Subpage4
And I need it to be like this:
Department1
-Subpage1
-Subpage2
--GrandchildrenPage1 <--
--GrandchildrenPage2 <--
-Subpage3
Department2
-Subpage1
-Subpage2
--GrandchildrenPage1 <--
--GrandchildrenPage2 <--
-Subpage3
I currently have this code that works fine to create the 3 subpages:
// Add 3 Children CPT
function add_children_custom_post_type( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
$post_template = esc_html( get_page_template_slug( $post->ID ) );
if ( !wp_is_post_revision( $post_id ) && 'department' == get_post_type( $post_id ) && 'publish' == get_post_status( $post_id ) && $post_template === '') {
$show = get_post( $post_id );
if( 0 == $show->post_parent && $show->post_excerpt == "" ) {
$children =& get_children(
array(
'post_parent' => $post_id,
'post_type' => 'department',
'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash')
)
);
if( empty( $children ) ){
$posts = "";
$posts = ['Subpage1' => 'template-subpage1.php', 'Subpage2' => 'template-subpage2.php', 'Subpage3' => 'template-subpage3.php'];
$order = 1;
foreach ($posts as $title => $template) {
$child = array(
'post_type' => 'department',
'post_title' => $title,
'post_status' => 'draft',
'post_parent' => $post_id,
'post_author' => get_post_field('post_author', $post_id),
'menu_order' => $order,
'page_template' => $template
);
wp_insert_post( $child );
$order++;
}
}
}
}
}
add_action( 'save_post', 'add_children_custom_post_type' );
Related
Using the answer from search multiple sku's on woocommerce admin side I adapted my code to replace $sku with the value of the custom field within my product, which is $winner.
When I search by separating product custom fields with a delimiter, it does not work. How can I edit my code so I can search products multiple by custom field?
function woo_multiple_title_search( $query_vars ) {
global $typenow;
global $wpdb;
global $pagenow;
if ( 'product' === $typenow && isset( $_GET['s'] ) && 'edit.php' === $pagenow ) {
$search_term = esc_sql( sanitize_text_field( $_GET['s'] ) );
if (strpos($search_term, '|') == false) return $query_vars;
$names = explode('|',$search_term);
$meta_query = array(
'relation' => 'OR'
);
if(is_array($winners) && $winners) {
foreach($winners as $winner) {
$meta_query[] = array(
'key' => '_winner',
'value' => $winner,
'compare' => '='
);
}
}
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'meta_query' => $meta_query
);
$posts = get_posts( $args );
if ( ! $posts ) return $query_vars;
foreach($posts as $post){
$query_vars['post__in'][] = $post->ID;
}
}
return $query_vars;
}
add_filter( 'request', 'woo_multiple_title_search', 20 );
I'm trying to add the "duplicate" post option to my custom post type admin menu called events. I have searched online, but there is very little documentation on how to add this function to the custom post types. Perhaps I am using the incorrect terminology when searching.
The code below adds the "duplicate" function, but when clicked it doesn't actually duplicate the post but returns a white screen instead. Are there any pointers or tips that you can give me?
function rd_duplicate_post_link( $actions, $post ) {
if (current_user_can('edit_posts') || $post->post_type=='events') {
$actions['duplicate'] = 'Duplicate';
}
return $actions;
}
add_filter('page_row_actions', 'rd_duplicate_post_link', 10, 2)
You need to call admin_action_rd_duplicate_post_as_draft hook
function rd_duplicate_post_link( $actions, $post ) {
//print_r($actions);
//if (current_user_can('edit_posts') || $post->post_type=='movies') {
$actions['duplicate'] = 'Duplicate';
// }
return $actions;
}
add_filter('page_row_actions', 'rd_duplicate_post_link', 10, 2);
add_action( 'admin_action_rd_duplicate_post_as_draft', 'dt_dpp_post_as_draft' );
function dt_dpp_post_as_draft()
{
global $wpdb;
/*sanitize_GET POST REQUEST*/
$post_copy = sanitize_text_field( $_POST["post"] );
$get_copy = sanitize_text_field( $_GET['post'] );
$request_copy = sanitize_text_field( $_REQUEST['action'] );
$opt = get_option('dpp_wpp_page_options');
$suffix = !empty($opt['dpp_post_suffix']) ? ' -- '.$opt['dpp_post_suffix'] : '';
$post_status = !empty($opt['dpp_post_status']) ? $opt['dpp_post_status'] : 'draft';
$redirectit = !empty($opt['dpp_post_redirect']) ? $opt['dpp_post_redirect'] : 'to_list';
if (! ( isset( $get_copy ) || isset( $post_copy ) || ( isset($request_copy) && 'dt_dpp_post_as_draft' == $request_copy ) ) ) {
wp_die('No post!');
}
$returnpage = '';
/* Get post id */
$post_id = (isset($get_copy) ? $get_copy : $post_copy );
$post = get_post( $post_id );
$current_user = wp_get_current_user();
$new_post_author = $current_user->ID;
/*Create the post Copy */
if (isset( $post ) && $post != null) {
/* Post data array */
$args = array('comment_status' => $post->comment_status,
'ping_status' => $post->ping_status,
'post_author' => $new_post_author,
'post_content' => $post->post_content,
'post_excerpt' => $post->post_excerpt,
'post_name' => $post->post_name,
'post_parent' => $post->post_parent,
'post_password' => $post->post_password,
'post_status' => $post_status,
'post_title' => $post->post_title.$suffix,
'post_type' => $post->post_type,
'to_ping' => $post->to_ping,
'menu_order' => $post->menu_order
);
$new_post_id = wp_insert_post( $args );
$taxonomies = get_object_taxonomies($post->post_type);
if(!empty($taxonomies) && is_array($taxonomies)):
foreach ($taxonomies as $taxonomy) {
$post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);}
endif;
$post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
if (count($post_meta_infos)!=0) {
$sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
foreach ($post_meta_infos as $meta_info) {
$meta_key = $meta_info->meta_key;
$meta_value = addslashes($meta_info->meta_value);
$sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";
}
$sql_query.= implode(" UNION ALL ", $sql_query_sel);
$wpdb->query($sql_query);
}
/*choice redirect */
if($post->post_type != 'post'):$returnpage = '?post_type='.$post->post_type; endif;
if(!empty($redirectit) && $redirectit == 'to_list'):wp_redirect( admin_url( 'edit.php'.$returnpage ) );
elseif(!empty($redirectit) && $redirectit == 'to_page'):wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
else:
wp_redirect( admin_url( 'edit.php'.$returnpage ) );
endif;
exit;
} else {
wp_die('Error! Post creation failed: ' . $post_id);
}
}
I have a category with products not visible to everyone.
I already have a script in place, that removes this category from the sidebar widget, when no items in the category are visible to the user.
I created a function that puts the exclude term_id in a global variable.
Now I need something that excludes them from view in the shop.
$GLOBALS['cat_exclude'] = NULL;
function getExcludedCats( ) {
//if( ! is_admin() && (is_product_category() || is_shop())){
$current_tax = get_query_var( 'product_cat' );
$term =get_term_by( 'slug', $current_tax, 'product_cat');
$parentid = $term->term_id;
$args = array(
'hide_empty' => true,
'parent' => $parentid
);
$product_categories = get_terms( 'product_cat', $args );
$exclude = array();
foreach ( $product_categories as $category ) {
$posts = get_posts( array( 'post_type' => 'product', 'posts_per_page' => -1, 'product_cat' => $category->slug, 'fields' => 'ids' ) );
$show_category = false;
foreach ( $posts as $post ) {
$product = new WC_Product( $post );
$visible_product = $product->is_visible();
if ( true === $visible_product ) {
$show_category = true;
break;
}
}
if ( false === $show_category ) {
$exclude[] = $category->term_id;
}
}
if ( ! empty( $exclude ) ) {
$GLOBALS['cat_exclude'] = implode( ',', $exclude );
}
//}
}
add_action('wp_head', 'getExcludedCats');
However, in the shop view itself, the category is still visible. How can I remove it there, when no items in this category are visible to the user.
I have tried:
https://gist.github.com/rynaldos/a9d357b1e3791afd9bea48833ff95994
But it removes the category ALWAYS, in both widget and shop.
Products are being displayed by group membership of the customer:
https://wordpress.org/plugins/groups/
I think I managed to create a script that made this possible:
https://gist.github.com/DarkAllMan/cffb114eb97c6f26882e54793e023587
<?php
/**
Plugin Name: WooCommerce - Hide categories where no products are visible to user
Plugin URI: https://www.randall.nl
Description: Excludes categories with no visible products from the WooCommerce category overview in shop
Version: 0.1
Author: Randall Kam
Author URI: https://www.randall.nl
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( !class_exists( 'ExcludeCats' ) ) :
class ExcludeCats {
public $version = '0.1',
$exclude = array();
protected static $_instance = null;
/**
* Main Plugin Instance
*
* Ensures only one instance of plugin is loaded or can be loaded.
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Constructor
*/
public function __construct() {
// CHECK CATEGORIES FOR VISIBLE PRODUCTS
add_action('wp_head', array( $this, 'get_excluded_cats' ), 10, 3 );
// ADD THE WIDGET SIDEBAR FILTER
add_filter( 'woocommerce_product_categories_widget_args', array( $this, 'kfg_exclude_categories_from_widget'), 10, 1 );
// ADD THE SHOP FILTER
add_filter( 'woocommerce_product_subcategories_args', array( $this, 'filter_woocommerce_product_subcategories_args'), 10, 1 );
}
// GET CATEGORIES WITH NO VISIBLE PRODUCTS AND PUT IN GLOBAL IF GLOBAL FALSE
public function get_excluded_cats( $terms, $taxonomies, $args ) {
$current_tax = get_query_var( 'product_cat' );
$term =get_term_by( 'slug', $current_tax, 'product_cat');
$term_id = $term->term_id;
$args = array(
'parent' => $term_id,
'hide_empty' => false,
'hierarchical' => false,
);
$product_categories = get_terms( 'product_cat', $args );
// if a product category and on the shop page
//if ( in_array( 'product_cat', $taxonomies ) && ! is_admin() && is_shop() ) {
if ( ! is_admin() && is_shop() ) {
foreach ( $product_categories as $key => $term ) {
unset($this->exclude);
if($term->taxonomy=='product_cat'){
$posts = get_posts( array( 'post_type' => 'product', 'posts_per_page' => -1, 'product_cat' => $term->slug, 'fields' => 'ids' ) );
$show_category = false;
foreach ( $posts as $post ) {
$product = new WC_Product( $post );
$visible_product = $product->is_visible();
if ( true === $visible_product ) {
$show_category = true;
break;
}
}
}
if ( false === $show_category ) {
$this->exclude[] = $term->term_id;
}
}
}
}
public function get_parent_cats ($cat_termid, $found = array()) {
array_push ($found, $cat_termid);
$term =get_term_by( 'term_id', $cat_termid, 'product_cat');
if($term->parent > 0){
return get_parent_cats($term->parent, $found);
}
return $found;
}
// ADD FILTERS FOR CATEGORIES AND EXCLUDE EMPTY
public function filter_woocommerce_product_subcategories_args( $temp_args = array() ) {
$current_tax = get_query_var( 'product_cat' );
$term =get_term_by( 'slug', $current_tax, 'product_cat');
$term_id = $term->term_id;
$temp_args = array(
'parent' => $term_id,
'menu_order' => 'ASC',
'hide_empty' => 1,
'hierarchical' => 1,
'taxonomy' => 'product_cat',
'pad_counts' => 1,
'include' => NULl,
'exclude' => $this->exclude,
);
return $temp_args;
}
public function kfg_exclude_categories_from_widget( $category_list_args ) {
$current_tax = get_query_var( 'product_cat' );
$term = get_term_by( 'slug', $current_tax, 'product_cat');
$term_id = $term->term_id;
$parents = $this->get_parent_cats($term_id);
$args = array(
'hide_empty' => false,
'hierarchical' => true,
);
$product_categories = get_terms( 'product_cat', $args );
$wexclude = array();
foreach ( $product_categories as $category ) {
$posts = get_posts( array( 'post_type' => 'product', 'posts_per_page' => -1, 'product_cat' => $category->slug, 'fields' => 'ids' ) );
$show_category = false;
foreach ( $posts as $post ) {
$product = new wC_Product( $post );
$visible_product = $product->is_visible();
if ( true === $visible_product ) {
$show_category = true;
break;
}
}
if ( false === $show_category || ( $category->parent > 0 && !in_array($category->parent,$parents) ) ) {
$wexclude[] = $category->term_id;
}
}
if ( ! empty( $wexclude ) ) {
$category_list_args['exclude'] = implode( ',', $wexclude );
unset( $category_list_args['include'] );
}
return $category_list_args;
}
} // class ExcludeCats
endif; // class_exists
/**
* Returns the main instance of the plugin class to prevent the need to use globals.
*
* #since 2.0
* #return WooCommerce_PostcodeAPInu
*/
function ExcludeCats() {
return ExcludeCats::instance();
}
ExcludeCats(); // load plugin
I want to create a stock level field in WooCommerce Products for every Store custom post type.
I've already created the Store custom post type and added 3 stores to it. I want to automatically add a "stock level at store" field every time someone adds a Store so that I could check the stocks at store level.
I'm trying to put the custom field at the Products->Inventory-> right under the Stock Quantity.
I've tried this:
$post_type = 'store';
$tax = 'show-topic';
$inv_arg_terms = get_terms(array('orderby' => 'id', 'order' => 'ASC'));
if ($inv_arg_terms) {
$args = array(
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => - 1,
'orderby' => 'title',
'order' => 'ASC'
); // END $args
$my_query = null;
$my_query = new WP_Query($args);
if ($my_query->have_posts()) {
while ($my_query->have_posts()) : $my_query->the_post();
add_action( 'woocommerce_product_options_inventory_product_data', 'wc_inventory_stock_product_field' );
function wc_inventory_stock_product_field() {
woocommerce_wp_text_input( array( 'id' => 'stock_level_' . the_title(), 'class' => 'short wc_input_stock', 'label' => __( 'Stock Level at ' . the_title(), 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')' ) );
}
add_action( 'save_post', 'wc_cost_save_product' );
function wc_cost_save_product( $product_id ) {
// stop the quick edit interferring as this will stop it saving properly, when a user uses quick edit feature
if (wp_verify_nonce($_POST['_inline_edit'], 'inlineeditnonce'))
return;
// If this is a auto save do nothing, we only save when update button is clicked
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( isset( $_POST['stock_level_' . the_title()] ) ) {
if ( is_numeric( $_POST['stock_level_' . the_title()] ) )
update_post_meta( $product_id, 'stock_level_' . the_title(), $_POST['cost_price'] );
} else delete_post_meta( $product_id, 'stock_level_' . the_title() );
}
endwhile;
} // END if have_posts loop
wp_reset_query();
} // END if $inv_arg_terms
and I got this:
Fatal error: Call to undefined function get_userdata() in
.../wp-includes/query.php on line 4758
Is what I'm thinking possible? How do I go about it?
Thanks, appreciate every help I could get.
Finally got it to work. Here's the code:
add_action( 'woocommerce_product_options_inventory_product_data', 'wc_stock_product_field' );
add_action( 'woocommerce_process_product_meta', 'wc_stock_save_product' );
function wc_stock_product_field() {
global $woocommerce, $post;
$post_type = 'store';
$args = array(
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => - 1,
'orderby' => 'id',
'order' => 'ASC',
'caller_get_posts' => 1
); // END $args
$store_query = null;
$store_query = new WP_Query($args);
if ($store_query->have_posts()) {
while ($store_query->have_posts()) : $store_query->the_post();
woocommerce_wp_text_input(
array(
'id' => get_the_id() ,
'class' => 'short wc_input_stock',
'label' => __( 'Stock Level # ' . get_the_title(), 'woocommerce' ) ) );
endwhile;
} // END if have_posts loop
wp_reset_query();
}
function wc_stock_save_product( $product_id ) {
// stop the quick edit interferring as this will stop it saving properly, when a user uses quick edit feature
if (wp_verify_nonce($_POST['_inline_edit'], 'inlineeditnonce'))
return;
// If this is a auto save do nothing, we only save when update button is clicked
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
$post_type = 'store';
$args = array(
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => - 1,
'orderby' => 'id',
'order' => 'ASC',
'caller_get_posts' => 1
); // END $args
$store_query = null;
$store_query = new WP_Query($args);
if ($store_query->have_posts()) {
while ($store_query->have_posts()) : $store_query->the_post();
if ( isset( $_POST[get_the_id()] ) ) {
if ( is_numeric( $_POST[get_the_id()] ) )
update_post_meta( $product_id, get_the_id(), $_POST[get_the_id()] );
} else delete_post_meta( $product_id, get_the_id() );
endwhile;
} // END if have_posts loop
wp_reset_query();
}
I'm using the function below to convert WP-comments to WP-posts. I want it to be fired when "approving" a comment. (now it is whenever the plug-in is activated in WP).
So really I'm wondering how to ad my function to this action from line 47 of the edit-comments.php:
foreach ( $comment_ids as $comment_id ) { // Check the permissions on each
if ( !current_user_can( 'edit_comment', $comment_id ) )
continue;
switch ( $doaction ) {
case 'approve' :
wp_set_comment_status( $comment_id, 'approve' );
$approved++;
break;
[...]
}
}
Plug-in function:
register_activation_hook( __FILE__, 'convert_to_posts' );
function convert_to_posts(){
$comments = get_comments();
foreach($comments as $comment)
{
$post = get_post($comment->comment_post_ID);
$title = get_comment_meta( $comment->comment_ID, 'title', true );
$content = $comment->comment_content;
$my_post = array(
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish',
'post_author' => 1
);
wp_insert_post( $my_post );
// wp_delete_comment( $comment->comment_ID );
}
}