I need to make something like wp_list_categories that shows categories that are empty but only if they have children categories that have posts in them. Anyone have any ideas?
Thanks
You can probably do this with a Walker, but I tried it the old-fashioned way.
$categories = get_categories();
// First index all categories by parent id, for easy lookup later
$cats_by_parent = array();
foreach ($categories as $cat) {
$parent_id = $cat->category_parent;
if (!array_key_exists($parent_id, $cats_by_parent)) {
$cats_by_parent[$parent_id] = array();
}
$cats_by_parent[$parent_id][] = $cat;
}
// Then build a hierarchical tree
$cat_tree = array();
function add_cats_to_bag(&$child_bag, &$children)
{
global $cats_by_parent;
foreach ($children as $child_cat) {
$child_id = $child_cat->cat_ID;
if (array_key_exists($child_id, $cats_by_parent)) {
$child_cat->children = array();
add_cats_to_bag($child_cat->children, $cats_by_parent[$child_id]);
}
$child_bag[$child_id] = $child_cat;
}
}
add_cats_to_bag($cat_tree, $cats_by_parent[0]);
// With this real tree, this recursive function can check for the cats you need
function has_children_with_posts(&$children)
{
$has_child_with_posts = false;
foreach ($children as $child_cat) {
$has_grandchildren_with_posts = false;
if (isset($child_cat->children)) {
// Here is our recursive call so we don't miss any subcats
if (has_children_with_posts($child_cat->children)) {
$has_grandchildren_with_posts = true;
}
}
if (0 < intval($child_cat->category_count)) {
$has_child_with_posts = true;
} else if ($has_grandchildren_with_posts) {
// This is a category that has no posts, but does have children that do
$child_cat->is_empty_with_children = true;
var_dump($child_cat->name);
}
}
return $has_child_with_posts;
}
has_children_with_posts($cat_tree);
Related
Hi I am importing a csv file, where one of the columns is representing the taxonomy term names separated with ; delimiter.
The code I have is the following:
public function save_post($post,$meta,$terms,$thumbnail,$is_update) {
// Separate the post tags from $post array
if (isset($post['post_tags']) && !empty($post['post_tags'])) {
$post_tags = $post['post_tags'];
unset($post['post_tags']);
}
// Special handling of attachments
if (!empty($thumbnail) && $post['post_type'] == 'attachment') {
$post['media_file'] = $thumbnail;
$thumbnail = null;
}
// Add or update the post
if ($is_update) {
$h = RSCSV_Import_Post_Helper::getByID($post['ID']);
$h->update($post);
} else {
$h = RSCSV_Import_Post_Helper::add($post);
}
// Set post tags
if (isset($post_tags)) {
$h->setPostTags($post_tags);
}
// Set meta data
$h->setMeta($meta);
// Set terms
foreach ($terms as $key => $value) {
$h->setObjectTerms($key, $value);
}
// Add thumbnail
if ($thumbnail) {
$h->addThumbnail($thumbnail);
}
return $h;
}
public function setObjectTerms($taxonomy, $terms)
{
$post = $this->getPost();
if ($post instanceof WP_Post) {
wp_set_object_terms($post->ID, $terms, $taxonomy);
} else {
$this->addError('post_is_not_set', __('WP_Post object is not set.', 'really-simple-csv-importer'));
}
}
The $key is the taxanomy ex: Col and the value is the actual name ex: Fiction Books
Any idea why the taxanomy terms are not ticked when the importation is complete?
I have a function that does 2 things.
Saves an existing or a new item/record
Query and re-order items
The code algorithm is like this
public function doSomething($id = 0)
{
$em = $this->getEntityManagerFromSomewhere();
$service = $this->getSomeServiceFromSomewhere();
$repo = $em->getRepository(Item::class);
$conn = $em->getConnection();
$conn->beginTransaction();
if ($id) {
$item = new Item();
} else {
$item = $repo->find($id);
}
$em->persist($item);
$em->flush();
$items = $repo->getAllItems();
// changes are saved to the database
$service->rearrangeItems($items);
$conn->commit();
}
Now the issue I'm having with this is that, if it is a new Item, when we try to get all items, that new item is not included for some odd reason.
I've tried stuff on my own and the one that works for me is to insert
$em->clear(); // after flush
I am not sure if this is the best way to approach this or if I'm misusing this functionality. It works though, when I tested it.
public function doSomething($id = 0)
There is $id is default 0, Actually, your are creating item every time.
if ($id) {
$item = new Item();
$em->persist($item);
} else {
$item = $repo->find($id);
}
also, you don't need to persist if you don't update or create new Item.
Or the way that I understood.
if($id)
{
$item = $em->getRepository(Item::class)->find($id)
}
else
{
$item = new Item();
$em->persist($item);
}
$em->flush();
I need to build a custom menu structure so the question as per title is: Is there a native wp function or something not from wp core to get the menu in a data structure as an object or an array ?
Thanks in advance.
add this on your function
function wp_get_menu_array($current_menu) {
$menu_name = $current_menu;
$locations = get_nav_menu_locations();
$menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
$array_menu = wp_get_nav_menu_items( $menu->term_id);
$menu = array();
foreach ($array_menu as $m) {
if (empty($m->menu_item_parent)) {
$menu[$m->ID] = array();
$menu[$m->ID]['ID'] = $m->ID;
$menu[$m->ID]['title'] = $m->title;
$menu[$m->ID]['url'] = $m->url;
$menu[$m->ID]['children'] = array();
}
}
$submenu = array();
foreach ($array_menu as $m) {
if ($m->menu_item_parent) {
$submenu[$m->ID] = array();
$submenu[$m->ID]['ID'] = $m->ID;
$submenu[$m->ID]['title'] = $m->title;
$submenu[$m->ID]['url'] = $m->url;
$menu[$m->menu_item_parent]['children'][$m->ID] = $submenu[$m->ID];
}
}
return $menu;
}
and retrieve the array on your view by
wp_get_menu_array('your_menu_name');
i have problem with managing advanced custom fields (i have 4 of them). I want to check if some of them are empty when i add new post. I tried something like empty($_POST['name_of_post_meta']) but it does not work.
How can i catch
function wpse120996_add_custom_field_automatically($post_id)
{
global $wpdb;
if (!wp_is_post_revision($post_id)) {
$category = get_the_category($post_id);
$category = $category[0]->name;
$link = get_permalink($post_id);
if (($_POST['post_status'] == 'publish') && ($_POST['original_post_status'] != 'publish')) { // new post
$lector = get_post_meta($post_id, 'lektor_pl', true);
$subs_pl = get_post_meta($post_id, 'napisy_pl', true);
$orginal = get_post_meta($post_id, 'wersja_eng', true);
$subs_eng = get_post_meta($post_id, 'subs_eng', true);
if (empty($_POST['lektor_pl'])) {
$lector = 0;
}
if (empty($_POST['napisy_pl'])) {
$subs_pl = 0;
}
if (empty($_POST['wersja_eng'])) {
$orginal = 0;
}
if (empty($_POST['subs_eng'])) {
$subs_eng = 0;
}
if (!empty($_POST['lektor_pl'])) {
$lector = 1;
}
if (!empty($_POST['napisy_pl'])) {
$subs_pl = 1;
}
if (!empty($_POST['wersja_eng'])) {
$orginal = 1;
}
if (!empty($_POST['subs_eng'])) {
$subs_eng = 1;
}
$sql = $wpdb->prepare("INSERT INTO `wp_cron_notification` (`id`, `post_id`, `subb_pl` , `lector`, `subb_eng`, `orginal`,`link`, `category`) values (NULL, %s, %s, %s, %s, %s, %s, %s)", $post_id, $subs_pl, $lector, $subs_eng, $orginal, $link, $category);
$wpdb->query($sql) or die("ERROR #3");
}
}
}
add_action('wp_insert_post', 'wpse120996_add_custom_field_automatically', 1);
Thanks in advance for any help.
You can make use here of the ACF save_post function (http://www.advancedcustomfields.com/resources/acfsave_post/) which fires just after a post is saved. See more here:
If you put the following in your functions.php file you should be able to access the newly saved post and carry out code above. For example:
add_action('acf/save_post', 'post_save_update_title', 20);
function post_save_update_title($post_id){
//Your code here
}
Maybe anyone can have a look:
I have a function and using batch to process bulk data to doctrine, but it not seems working, because nothing is inserted to database, but if i flush() every element, everything is working
any ideas why?
private function insertData($linesInFile, $output)
{
$google = $this->getContainer()->get('google.books');
$amazon = $this->getContainer()->get('amazon.books');
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
$number = 1;
$batchSize = 5;
foreach ($linesInFile as $string) {
$string = preg_split('/isbn_13/', $string);
$book = new Book();
$isbn = new Isbn();
if (isset($string[1])) {
$value = str_split($string[1], 23);
$isbnValue = preg_replace('/\D/', '', $value[0]);
$isbn->setIsbn($isbnValue);
$book = $google->getBookByIsbn($isbn);
if (null == $book->getIsbn()) {
$book = $amazon->getBookByIsbn($isbn);
}
$pages = $book->getPages();
$image = $book->getCover();
$about = $book->getAbout();
if ($about !== "") {
if ($image !=="") {
$em->persist($book);
if (($number % $batchSize) === 0) {
$em->flush();
$em->clear();
}
$output->writeln($isbnValue);
$number++;
}
}
}
}
$em->flush();
$em->clear();
return $number;
}
}
So, my code is good, it was some bug in google API and items were not persisted properly.