AndyDeGroo on "Development of Polylang version 0.8"

February 27, 2012

I was moving code to production sandbox and tried to set default language for existing content in Polylang options screen.
Got this:

WordPress database error: [Duplicate entry '41-5' for key 1]
INSERT INTO wp_dev_term_relationships (object_id, term_taxonomy_id) VALUES (41, 5),(33, 5),(28, 5),(26, 5),(2, 5),(1, 5),(23, 5),(13, 5),(6, 5),(9, 5),(24, 5)

This is because get_terms('language', array('fields'=>'ids')) return an empty array every time. This in turn happens because, when you insert term relations manually, wp_term_taxonomy.count is not incremented.
The get_terms query returns only non-empty terms:
SELECT t.term_id, tt.parent, tt.count FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ('language') AND tt.count > 0 ORDER BY t.name ASC

Solution would be to add the hide_empty option to get_terms in Polylang_Admin::get_untranslated():

get_terms('language', array('fields'=>'ids','hide_empty'=>0));

and term count should also be updated after inserting relations to prevent further problems with get_terms:

$post_count = count($untranslated['posts']); //Note: get_untranslated returns array instead of false - read below
if($post_count && $lang->term_taxonomy_id){
	$values = array();
	foreach ($untranslated['posts'] as $post_id)
		$values[] = $wpdb->prepare("(%d, %d)", $post_id, $lang->term_taxonomy_id);

	$wpdb->query("INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id) VALUES " . implode(',', $values));
	$wpdb->update($wpdb->term_taxonomy, array('count'=>$post_count), array( 'term_taxonomy_id' => $lang->term_taxonomy_id ));
}

Probably there is a better way to update term counts.

Polylang_Admin::get_untranslated() should return an array of arrays instead of false:

return empty($posts) && empty($terms) ? false : array('posts' => $posts, 'terms' => $terms);

better cast them as arrays:

return array('posts'=>(array)$posts, 'terms'=>(array)$terms);

that way it can be passed directly to foreach without warnings like Invalid argument supplied for foreach() in ....

EDIT: I made this change and realized that there should be more advanced check in admin-form.php so maybe in this case it is easier to check return values in admin.php.

Leave a Comment

Previous post:

Next post: