/**
  * Outputs the contents of a meta editing table.
  * 
  * @since 2.9
  * 
  * @param string $genus The type of object being handled (either 'post' or 'term')
  * @param string $tab The ID of the current tab; used to generate a URL hash (e.g. #$tab)
  * @param string $type The type of post/taxonomy type being edited (examples: post, page, attachment, category, post_tag)
  * @param string $type_label The singular label for the post/taxonomy type (examples: Post, Page, Attachment, Category, Post Tag)
  * @param array $fields The array of meta fields that the user can edit with the tables. The data for each meta field are stored in an array with these elements: "type" (can be textbox, textarea, or checkbox), "name" (the meta field, e.g. title or description), "term_settings_key" (the key of the setting for cases when term meta data are stored in the settings array), and "label" (the internationalized label of the field, e.g. "Meta Description" or "Title Tag")
  */
 function meta_edit_table($genus, $tab, $type, $type_label, $fields)
 {
     //Pseudo-constant
     $per_page = 100;
     //Sanitize parameters
     if (!is_array($fields) || !count($fields)) {
         return false;
     }
     if (!isset($fields[0]) || !is_array($fields[0])) {
         $fields = array($fields);
     }
     //Get search query
     $type_s = $type . '_s';
     $search = isset($_REQUEST[$type_s]) ? $_REQUEST[$type_s] : '';
     //Save meta if applicable
     if ($is_update = $this->is_action('update') && !strlen(trim($search))) {
         foreach ($_POST as $key => $value) {
             $value = stripslashes($value);
             if (sustr::startswith($key, $genus . '_')) {
                 foreach ($fields as $field) {
                     if (preg_match("/{$genus}_([0-9]+)_{$field['name']}/", $key, $matches)) {
                         $id = (int) $matches[1];
                         switch ($genus) {
                             case 'post':
                                 update_post_meta($id, "_su_{$field['name']}", $value);
                                 break;
                             case 'term':
                                 $this->update_setting($field['term_settings_key'], $value, null, $id);
                                 break;
                         }
                         continue 2;
                         //Go to next $_POST item
                     }
                 }
             }
         }
     }
     $pagenum = isset($_GET[$type . '_paged']) ? absint($_GET[$type . '_paged']) : 0;
     if (empty($pagenum)) {
         $pagenum = 1;
     }
     //Load up the objects based on the genus
     switch ($genus) {
         case 'post':
             //Get the posts
             wp(array('post_type' => $type, 'posts_per_page' => $per_page, 'post_status' => 'any', 'paged' => $pagenum, 'order' => 'ASC', 'orderby' => 'title', 's' => $search));
             global $wp_query;
             $objects =& $wp_query->posts;
             $num_pages = $wp_query->max_num_pages;
             $total_objects = $wp_query->found_posts;
             break;
         case 'term':
             $objects = get_terms($type, array('search' => $search));
             $total_objects = count($objects);
             $num_pages = ceil($total_objects / $per_page);
             $objects = array_slice($objects, $per_page * ($pagenum - 1), $per_page);
             break;
         default:
             return false;
             break;
     }
     if ($total_objects < 1) {
         return false;
     }
     echo "\n<div class='su-meta-edit-table'>\n";
     $page_links = paginate_links(array('base' => add_query_arg($type . '_paged', '%#%') . '#' . $tab, 'format' => '', 'prev_text' => __('&laquo;'), 'next_text' => __('&raquo;'), 'total' => $num_pages, 'current' => $pagenum));
     if ($page_links) {
         $page_links_text = '<div class="tablenav"><div class="tablenav-pages">';
         $page_links_text .= sprintf('<span class="displaying-num">' . __('Displaying %s&#8211;%s of %s') . '</span>%s', number_format_i18n(($pagenum - 1) * $per_page + 1), number_format_i18n(min($pagenum * $per_page, $total_objects)), number_format_i18n($total_objects), $page_links);
         $page_links_text .= "</div></div>\n";
         echo $page_links_text;
     } else {
         $page_links_text = '';
     }
     //Get object identification headers
     $headers = array('actions' => __('Actions', 'seo-ultimate'), 'id' => __('ID', 'seo-ultimate'), 'name' => $type_label);
     //Get meta field headers
     foreach ($fields as $field) {
         $headers[$field['name']] = $field['label'];
     }
     //Output all headers
     $this->admin_wftable_start($headers);
     //Output rows
     foreach ($objects as $object) {
         switch ($genus) {
             case 'post':
                 $id = intval($object->ID);
                 $name = $object->post_title;
                 $view_url = get_permalink($id);
                 $edit_url = get_edit_post_link($id);
                 $status_obj = get_post_status_object($object->post_status);
                 switch ($object->post_status) {
                     case 'publish':
                         $status = '';
                         break;
                     case 'inherit':
                         $status = '';
                         break;
                     case 'auto-draft':
                         continue;
                         break;
                     default:
                         $status = $status_obj->label;
                         break;
                 }
                 if ($status) {
                     $name .= "<span class='su-meta-table-post-status'> &mdash; {$status}</span>";
                 }
                 break;
             case 'term':
                 $id = intval($object->term_id);
                 $name = $object->name;
                 $view_url = get_term_link($id, $type);
                 $edit_url = suwp::get_edit_term_link($id, $type);
                 break;
             default:
                 return false;
                 break;
         }
         $view_url = su_esc_attr($view_url);
         $edit_url = su_esc_attr($edit_url);
         $actions = array(sprintf('<a href="%s">%s</a>', $view_url, __('View', 'seo-ultimate')));
         if ($edit_url) {
             $actions[] = sprintf('<a href="%s">%s</a>', $edit_url, __('Edit', 'seo-ultimate'));
         }
         $actions = implode(' | ', $actions);
         $cells = compact('actions', 'id', 'name');
         //Get meta field cells
         foreach ($fields as $field) {
             $inputid = "{$genus}_{$id}_{$field['name']}";
             switch ($genus) {
                 case 'post':
                     $value = $this->get_postmeta($field['name'], $id);
                     break;
                 case 'term':
                     $value = $this->get_setting($field['term_settings_key'], array());
                     $value = isset($value[$id]) ? $value[$id] : null;
                     break;
             }
             if ($is_update && $field['type'] == 'checkbox' && $value == '1' && !isset($_POST[$inputid])) {
                 switch ($genus) {
                     case 'post':
                         delete_post_meta($id, "_su_{$field['name']}");
                         $value = 0;
                         break;
                     case 'term':
                         $this->update_setting($field['term_settings_key'], false, null, $id);
                         break;
                 }
             }
             $cells[$field['name']] = $this->get_input_element($field['type'], $inputid, $value, isset($field['options']) ? $field['options'] : false);
         }
         //Output all cells
         $this->table_row($cells, $id, $type);
     }
     //End table
     $this->admin_wftable_end();
     echo $page_links_text;
     echo "</div>\n";
     return true;
 }