SEO Ultimate - Version 2.9

Version Description

Download this release

Release Info

Developer SEO Design Solutions
Plugin Icon 128x128 SEO Ultimate
Version 2.9
Comparing to
See all releases

Code changes from version 2.8 to 2.9

includes/jlfunctions/html.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ JLFunctions HTML Class
4
+ Copyright (c)2010 John Lamansky
5
+ */
6
+
7
+ class suhtml {
8
+
9
+ /**
10
+ * Returns <option> tags.
11
+ */
12
+ function option_tags($options, $current = true) {
13
+ $html = '';
14
+ foreach ($options as $value => $label) {
15
+ $html .= "<option value='$value'";
16
+ if ($value == $current) $html .= " selected='selected'";
17
+ $html .= ">$label</option>";
18
+ }
19
+ return $html;
20
+ }
21
+ }
22
+
23
+ ?>
includes/jlfunctions/jlfunctions.php CHANGED
@@ -4,7 +4,7 @@ JLFunctions Library
4
  Copyright (c)2009-2010 John Lamansky
5
  */
6
 
7
- foreach (array('arr', 'io', 'md', 'str', 'url') as $jlfuncfile) {
8
  include dirname(__FILE__)."/$jlfuncfile.php";
9
  }
10
 
4
  Copyright (c)2009-2010 John Lamansky
5
  */
6
 
7
+ foreach (array('arr', 'html', 'io', 'md', 'str', 'url') as $jlfuncfile) {
8
  include dirname(__FILE__)."/$jlfuncfile.php";
9
  }
10
 
includes/jlwp/functions.php CHANGED
@@ -27,9 +27,23 @@ class suwp {
27
  }
28
 
29
  function get_post_type_names() {
30
- $types = get_post_types();
31
- suarr::remove_value($types, 'revision');
32
- return $types;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
34
 
35
  /**
@@ -88,15 +102,7 @@ class suwp {
88
  return 'http://codex.wordpress.org/Backing_Up_Your_Database';
89
  }
90
 
91
- function get_taxonomy_link($id, $taxonomy) {
92
- switch ($taxonomy) {
93
- case 'category': return get_category_link($id); break;
94
- case 'post_tag': return get_tag_link($id); break;
95
- default: return suwp::get_edit_taxonomy_link($id, $taxonomy); break;
96
- }
97
- }
98
-
99
- function get_edit_taxonomy_link($id, $taxonomy) {
100
  if ($taxonomy == 'category')
101
  return admin_url("categories.php?action=edit&amp;cat_ID=$id");
102
  else
27
  }
28
 
29
  function get_post_type_names() {
30
+ if (function_exists('get_post_types')) {
31
+ if ($types = get_post_types(array('public' => true), 'names'))
32
+ return $types;
33
+ else
34
+ return array('post', 'page', 'attachment');
35
+ }
36
+
37
+ return array();
38
+ }
39
+
40
+ function get_taxonomies() {
41
+ global $wp_taxonomies;
42
+ $taxonomies = array();
43
+ foreach ($wp_taxonomies as $key => $taxonomy)
44
+ if ($taxonomy->object_type == 'post')
45
+ $taxonomies[$key] = $taxonomy;
46
+ return $taxonomies;
47
  }
48
 
49
  /**
102
  return 'http://codex.wordpress.org/Backing_Up_Your_Database';
103
  }
104
 
105
+ function get_edit_term_link($id, $taxonomy) {
 
 
 
 
 
 
 
 
106
  if ($taxonomy == 'category')
107
  return admin_url("categories.php?action=edit&amp;cat_ID=$id");
108
  else
modules/404s/fofs-log.php CHANGED
@@ -74,17 +74,16 @@ class SU_FofsLog extends SU_Module {
74
 
75
  if ($hit['status_code'] == 404) {
76
 
77
- $exceptions = explode("\n", $this->get_setting('exceptions', ''));
78
  foreach ($exceptions as $exception) {
79
- $exception = trim($exception); //Remove any \r's
80
  $exception = str_replace('*', '.*', $exception);
81
  $regex = "@^$exception$@i";
82
  $regex = str_replace(array('@^.*', '.*$@i'), array('@', '@i'), $regex);
83
- if (preg_match($regex, $hit['url'])) return;
84
  }
85
 
86
  $l = $this->get_setting('log', array());
87
- while (count($l) >= $this->get_setting('max_log_size')) array_pop($l);
88
 
89
  $u = $hit['url'];
90
  if (!isset($l[$u])) {
@@ -108,6 +107,8 @@ class SU_FofsLog extends SU_Module {
108
 
109
  $this->update_setting('log', $l);
110
  }
 
 
111
  }
112
 
113
  function get_admin_table_columns() {
74
 
75
  if ($hit['status_code'] == 404) {
76
 
77
+ $exceptions = suarr::explode_lines($this->get_setting('exceptions', ''));
78
  foreach ($exceptions as $exception) {
 
79
  $exception = str_replace('*', '.*', $exception);
80
  $regex = "@^$exception$@i";
81
  $regex = str_replace(array('@^.*', '.*$@i'), array('@', '@i'), $regex);
82
+ if (preg_match($regex, $hit['url'])) return $hit;
83
  }
84
 
85
  $l = $this->get_setting('log', array());
86
+ while (count($l) >= $this->get_setting('max_log_size', 1000)) array_pop($l);
87
 
88
  $u = $hit['url'];
89
  if (!isset($l[$u])) {
107
 
108
  $this->update_setting('log', $l);
109
  }
110
+
111
+ return $hit;
112
  }
113
 
114
  function get_admin_table_columns() {
modules/class.su-module.php CHANGED
@@ -669,14 +669,18 @@ class SU_Module {
669
  * @param string $value The new value to assign to the setting.
670
  * @param string|null $module The module to which the setting belongs. Defaults to the current module's settings key. Optional.
671
  */
672
- function update_setting($key, $value, $module=null) {
673
  if (!$module) $module = $this->get_settings_key();
674
 
675
  $use_custom = apply_filters("su_custom_update_setting-$module-$key", false, $value, $key) ||
676
  apply_filters("su_custom_update_setting-$module", false, $value, $key);
677
 
678
- if (!$use_custom)
679
- $this->plugin->dbdata['settings'][$module][$key] = $value;
 
 
 
 
680
  }
681
 
682
  /**
@@ -731,14 +735,18 @@ class SU_Module {
731
  * @param string $key The name of the setting to delete.
732
  * @param string|null $module The module to which the setting belongs. Defaults to the current module's settings key. Optional.
733
  */
734
- function delete_setting($key, $module=null) {
735
  if (!$module) $module = $this->get_settings_key();
736
 
737
  if (isset($this->plugin->dbdata['settings']
738
  , $this->plugin->dbdata['settings'][$module]
739
- , $this->plugin->dbdata['settings'][$module][$key]))
740
  //Some PHP setups will actually throw an error if we try to unset an array element that doesn't exist...
741
- unset($this->plugin->dbdata['settings'][$module][$key]);
 
 
 
 
742
  }
743
 
744
  /**
@@ -871,7 +879,7 @@ class SU_Module {
871
  foreach ($tabs as $title => $function) {
872
 
873
  if ($c > 1) {
874
- $id = preg_replace('/[^a-z0-9]/', '', strtolower($title));
875
  echo "<fieldset id='su-$id'>\n<h3>$title</h3>\n<div class='su-tab-contents'>\n";
876
  }
877
 
@@ -984,6 +992,296 @@ class SU_Module {
984
  echo "<br />";
985
  }
986
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
987
 
988
  /********** ADMIN FORM FUNCTIONS **********/
989
 
@@ -1116,14 +1414,74 @@ class SU_Module {
1116
  echo "\t\t<td $class$style>".$cells[$column_name]."</td>\n";
1117
  }
1118
  } elseif (is_array($cells) && count($cells)) {
1119
- $mk = $this->get_module_key();
1120
  foreach ($cells as $class => $content) {
1121
- $class = is_numeric($class) ? '' : " class='su-$mk-$class'";
1122
  echo "\t\t<td$class>$content</td>\n";
1123
  }
1124
  }
1125
  }
1126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1127
  /**
1128
  * Ends a "widefat" WordPress table.
1129
  *
@@ -1175,8 +1533,11 @@ class SU_Module {
1175
  * @param string $hovertext The text that only displays upon row hover.
1176
  * @return string The HTML to put in a hover-supporting table row.
1177
  */
1178
- function hover_row($text, $hovertext) {
1179
- return "<div>$text</div>\n<div class='row-actions'>$hovertext</div>";
 
 
 
1180
  }
1181
 
1182
  /**
669
  * @param string $value The new value to assign to the setting.
670
  * @param string|null $module The module to which the setting belongs. Defaults to the current module's settings key. Optional.
671
  */
672
+ function update_setting($key, $value, $module=null, $array_key=null) {
673
  if (!$module) $module = $this->get_settings_key();
674
 
675
  $use_custom = apply_filters("su_custom_update_setting-$module-$key", false, $value, $key) ||
676
  apply_filters("su_custom_update_setting-$module", false, $value, $key);
677
 
678
+ if (!$use_custom) {
679
+ if ($array_key)
680
+ $this->plugin->dbdata['settings'][$module][$key][$array_key] = $value;
681
+ else
682
+ $this->plugin->dbdata['settings'][$module][$key] = $value;
683
+ }
684
  }
685
 
686
  /**
735
  * @param string $key The name of the setting to delete.
736
  * @param string|null $module The module to which the setting belongs. Defaults to the current module's settings key. Optional.
737
  */
738
+ function delete_setting($key, $module=null, $array_key = null) {
739
  if (!$module) $module = $this->get_settings_key();
740
 
741
  if (isset($this->plugin->dbdata['settings']
742
  , $this->plugin->dbdata['settings'][$module]
743
+ , $this->plugin->dbdata['settings'][$module][$key])) {
744
  //Some PHP setups will actually throw an error if we try to unset an array element that doesn't exist...
745
+ if ($array_key)
746
+ unset($this->plugin->dbdata['settings'][$module][$key][$array_key]);
747
+ else
748
+ unset($this->plugin->dbdata['settings'][$module][$key]);
749
+ }
750
  }
751
 
752
  /**
879
  foreach ($tabs as $title => $function) {
880
 
881
  if ($c > 1) {
882
+ $id = sustr::preg_filter('a-z0-9', strtolower($title));
883
  echo "<fieldset id='su-$id'>\n<h3>$title</h3>\n<div class='su-tab-contents'>\n";
884
  }
885
 
992
  echo "<br />";
993
  }
994
 
995
+ /**
996
+ * Returns tabs for post/taxonomy meta editing tables.
997
+ *
998
+ * @since 2.9
999
+ * @uses get_postmeta_edit_tabs()
1000
+ * @uses get_taxmeta_edit_tabs()
1001
+ *
1002
+ * @param array $fields The array of meta fields that the user can edit with the tables.
1003
+ */
1004
+ function get_meta_edit_tabs($fields) {
1005
+ return array_merge(
1006
+ $this->get_postmeta_edit_tabs($fields)
1007
+ ,$this->get_taxmeta_edit_tabs($fields)
1008
+ );
1009
+ }
1010
+
1011
+ /**
1012
+ * Returns tabs for post meta editing tables.
1013
+ *
1014
+ * @since 2.9
1015
+ *
1016
+ * @param array $fields The array of meta fields that the user can edit with the tables.
1017
+ */
1018
+ function get_postmeta_edit_tabs($fields) {
1019
+
1020
+ $types = array();
1021
+
1022
+ //Custom post type support - requires WordPress 3.0 or above (won't work with 2.9 custom post types)
1023
+ if (function_exists('get_post_types'))
1024
+ $types = get_post_types(array('public' => true), 'objects');
1025
+
1026
+ /*
1027
+ if (function_exists('get_post_types'))
1028
+ $types = suarr::flatten_values(get_post_types(array('public' => true), 'objects'), array('labels', 'name'));
1029
+ */
1030
+
1031
+ //Legacy support for WordPress 2.9 and below
1032
+ if (!count($types)) {
1033
+
1034
+ $_types = array(
1035
+ array('post', __('Posts'), __('Post'))
1036
+ , array('page', __('Pages'), __('Page'))
1037
+ , array('attachment', __('Attachments'), __('Attachment'))
1038
+ );
1039
+ $types = array();
1040
+ foreach ($_types as $_type) {
1041
+ $type = new stdClass();
1042
+ $type->name = $_type[0];
1043
+ $type->labels->name = $_type[1];
1044
+ $type->labels->singular_name = $_type[2];
1045
+ $types[] = $type;
1046
+ }
1047
+ }
1048
+
1049
+ //Turn the types array into a tabs array
1050
+ $tabs = array();
1051
+ foreach ($types as $type)
1052
+ $tabs[$type->labels->name] = array('meta_edit_tab', 'post', sustr::preg_filter('a-z0-9', strtolower($type->labels->name)), $type->name, $type->labels->singular_name, $fields);
1053
+ return $tabs;
1054
+ }
1055
+
1056
+ /**
1057
+ * Returns tabs for taxonomy meta editing tables.
1058
+ *
1059
+ * @since 2.9
1060
+ *
1061
+ * @param array $fields The array of meta fields that the user can edit with the tables.
1062
+ */
1063
+ function get_taxmeta_edit_tabs($fields) {
1064
+ $types = suwp::get_taxonomies();
1065
+
1066
+ //Turn the types array into a tabs array
1067
+ $tabs = array();
1068
+ foreach ($types as $name => $type)
1069
+ $tabs[$type->label] = array('meta_edit_tab', 'term', sustr::preg_filter('a-z0-9', strtolower($type->label)), $name, __('Name', 'seo-ultimate'), $fields);
1070
+ return $tabs;
1071
+ }
1072
+
1073
+ /**
1074
+ * Outputs the contents of a meta editing tab.
1075
+ *
1076
+ * @since 2.9
1077
+ */
1078
+ function meta_edit_tab($genus, $tab, $type, $type_label, $fields) {
1079
+ if (!$this->meta_edit_table($genus, $tab, $type, $type_label, $fields))
1080
+ $this->print_message('info', __('Your site currently doesn&#8217;t have any public items of this type.', 'seo-ultimate'));
1081
+ }
1082
+
1083
+ /**
1084
+ * Outputs the contents of a meta editing table.
1085
+ *
1086
+ * @since 2.9
1087
+ *
1088
+ * @param string $genus The type of object being handled (either 'post' or 'term')
1089
+ * @param string $tab The ID of the current tab; used to generate a URL hash (e.g. #su-$tab)
1090
+ * @param string $type The type of post/taxonomy type being edited (examples: post, page, attachment, category, post_tag)
1091
+ * @param string $type_label The singular label for the post/taxonomy type (examples: Post, Page, Attachment, Category, Post Tag)
1092
+ * @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), "setting" (the key of the setting for cases when meta data are stored in the settings array, namely, for taxonomies), and "label" (the internationalized label of the field, e.g. "Meta Description" or "Title Tag")
1093
+ */
1094
+ function meta_edit_table($genus, $tab, $type, $type_label, $fields) {
1095
+
1096
+ //Pseudo-constant
1097
+ $per_page = 100;
1098
+
1099
+ //Sanitize parameters
1100
+ if (!is_array($fields) || !count($fields)) return false;
1101
+ if (!is_array($fields[0])) $fields = array($fields);
1102
+
1103
+ //Get search query
1104
+ $search = $_REQUEST[$type . '_s'];
1105
+
1106
+ //Save meta if applicable
1107
+ if ($is_update = ($this->is_action('update') && !strlen(trim($search))))
1108
+ foreach ($_POST as $key => $value)
1109
+ if (sustr::startswith($key, $genus.'_'))
1110
+ foreach ($fields as $field)
1111
+ if (preg_match("/{$genus}_([0-9]+)_{$field['name']}/", $key, $matches)) {
1112
+ $id = (int)$matches[1];
1113
+ switch ($genus) {
1114
+ case 'post': update_post_meta($id, "_su_{$field['name']}", $_POST[$key]); break;
1115
+ case 'term': $this->update_setting($field['term_settings_key'], $_POST[$key], null, $id); break;
1116
+ }
1117
+ continue 2; //Go to next $_POST item
1118
+ }
1119
+
1120
+ $pagenum = isset( $_GET[$type . '_paged'] ) ? absint( $_GET[$type . '_paged'] ) : 0;
1121
+ if ( empty($pagenum) ) $pagenum = 1;
1122
+
1123
+ //Load up the objects based on the genus
1124
+ switch ($genus) {
1125
+ case 'post':
1126
+
1127
+ //Get the posts
1128
+ wp(array(
1129
+ 'post_type' => $type
1130
+ , 'posts_per_page' => $per_page
1131
+ , 'paged' => $pagenum
1132
+ , 'order' => 'ASC'
1133
+ , 'orderby' => 'title'
1134
+ , 's' => $search
1135
+ ));
1136
+ global $wp_query;
1137
+ $objects = &$wp_query->posts;
1138
+
1139
+ $num_pages = $wp_query->max_num_pages;
1140
+ $total_objects = $wp_query->found_posts;
1141
+
1142
+ break;
1143
+
1144
+ case 'term':
1145
+ $objects = get_terms($type, array('search' => $search));
1146
+ $total_objects = count($objects);
1147
+ $num_pages = ceil($total_objects / $per_page);
1148
+ $objects = array_slice($objects, $per_page * ($pagenum-1), $per_page);
1149
+ break;
1150
+ default:
1151
+ return false;
1152
+ break;
1153
+ }
1154
+
1155
+ if ($total_objects < 1) return false;
1156
+
1157
+ echo "\n<div class='su-meta-edit-table'>\n";
1158
+
1159
+ $page_links = paginate_links( array(
1160
+ 'base' => add_query_arg( $type . '_paged', '%#%' ) . '#su-' . $tab
1161
+ , 'format' => ''
1162
+ , 'prev_text' => __('&laquo;')
1163
+ , 'next_text' => __('&raquo;')
1164
+ , 'total' => $num_pages
1165
+ , 'current' => $pagenum
1166
+ ));
1167
+
1168
+ if ( $page_links ) {
1169
+ $page_links_text = '<div class="tablenav"><div class="tablenav-pages">';
1170
+ $page_links_text .= sprintf( '<span class="displaying-num">' . __( 'Displaying %s&#8211;%s of %s' ) . '</span>%s',
1171
+ number_format_i18n( ( $pagenum - 1 ) * $per_page + 1 ),
1172
+ number_format_i18n( min( $pagenum * $per_page, $total_objects ) ),
1173
+ number_format_i18n( $total_objects ),
1174
+ $page_links
1175
+ );
1176
+ $page_links_text .= "</div></div>\n";
1177
+
1178
+ echo $page_links_text;
1179
+ } else $page_links_text = '';
1180
+
1181
+ //Get object identification headers
1182
+ $headers = array(
1183
+ 'actions' => __('Actions', 'seo-ultimate')
1184
+ , 'id' => __('ID', 'seo-ultimate')
1185
+ , 'name' => $type_label
1186
+ );
1187
+
1188
+ //Get meta field headers
1189
+ foreach ($fields as $field) {
1190
+ $headers[$field['name']] = $field['label'];
1191
+ }
1192
+
1193
+ //Output all headers
1194
+ $this->admin_wftable_start($headers);
1195
+
1196
+ //Output rows
1197
+ foreach ($objects as $object) {
1198
+
1199
+ switch ($genus) {
1200
+ case 'post':
1201
+ $id = intval($object->ID);
1202
+ $name = $object->post_title;
1203
+ $view_url = get_permalink($id);
1204
+ $edit_url = get_edit_post_link($id);
1205
+ break;
1206
+ case 'term':
1207
+ $id = intval($object->term_id);
1208
+ $name = $object->name;
1209
+ $view_url = get_term_link($id, $type);
1210
+ $edit_url = suwp::get_edit_term_link($id, $type);
1211
+ break;
1212
+ default: return false; break;
1213
+ }
1214
+
1215
+ $view_url = su_esc_attr($view_url);
1216
+ $edit_url = su_esc_attr($edit_url);
1217
+ $actions = sprintf('<a href="%s">%s</a> | <a href="%s">%s</a>', $view_url, __('View', 'seo-ultimate'), $edit_url, __('Edit', 'seo-ultimate'));
1218
+ $cells = compact('actions', 'id', 'name');
1219
+
1220
+ //Get meta field cells
1221
+ foreach ($fields as $field) {
1222
+ $inputid = "{$genus}_{$id}_{$field['name']}";
1223
+
1224
+ switch ($genus) {
1225
+ case 'post': $value = $this->get_postmeta($field['name'], $id); break;
1226
+ case 'term': $value = $this->get_setting($field['term_settings_key'], array()); $value = $value[$id]; break;
1227
+ }
1228
+
1229
+ if ($is_update && $field['type'] == 'checkbox' && $value == '1' && !isset($_POST[$inputid]))
1230
+ switch ($genus) {
1231
+ case 'post': delete_post_meta($id, "_su_{$field['name']}"); $value = 0; break;
1232
+ case 'term': $this->update_setting($field['term_settings_key'], false, null, $id); break;
1233
+ }
1234
+
1235
+ $cells[$field['name']] = $this->get_input_element(
1236
+ $field['type'] //Type
1237
+ , $inputid
1238
+ , $value
1239
+ );
1240
+ }
1241
+
1242
+ //Output all cells
1243
+ $this->table_row($cells, $id, $type);
1244
+ }
1245
+
1246
+ //End table
1247
+ $this->admin_wftable_end();
1248
+
1249
+ echo $page_links_text;
1250
+
1251
+ echo "</div>\n";
1252
+
1253
+ return true;
1254
+ }
1255
+
1256
+ /**
1257
+ * Returns the HTML for a given type of input element, without any surrounding <td> elements etc.
1258
+ *
1259
+ * @since 2.9
1260
+ *
1261
+ * @param string $type The type of input element (can be textbox, textarea, or checkbox)
1262
+ * @param string $inputid The name/ID of the input element
1263
+ * @param string $value The current value of the field
1264
+ */
1265
+ function get_input_element($type, $inputid, $value) {
1266
+ //Get HTML element
1267
+ switch ($type) {
1268
+ case 'textbox':
1269
+ $value = su_esc_editable_html($value);
1270
+ return "<input name='$inputid' id='$inputid' type='text' value='$value' class='regular-text' />";
1271
+ break;
1272
+ case 'textarea':
1273
+ $value = su_esc_editable_html($value);
1274
+ return "<textarea name='$inputid' id='$inputid' type='text' rows='3' cols='50' class='regular-text'>$value</textarea>";
1275
+ break;
1276
+ case 'checkbox':
1277
+ $checked = $value ? " checked='checked'" : '';
1278
+ return "<input name='$inputid' id='$inputid' type='checkbox' value='1'$checked />";
1279
+ break;
1280
+ }
1281
+
1282
+ return '';
1283
+ }
1284
+
1285
 
1286
  /********** ADMIN FORM FUNCTIONS **********/
1287
 
1414
  echo "\t\t<td $class$style>".$cells[$column_name]."</td>\n";
1415
  }
1416
  } elseif (is_array($cells) && count($cells)) {
 
1417
  foreach ($cells as $class => $content) {
1418
+ $class = is_numeric($class) ? '' : " class='su-$class'";
1419
  echo "\t\t<td$class>$content</td>\n";
1420
  }
1421
  }
1422
  }
1423
 
1424
+ /**
1425
+ * Outputs a <tr> tag with <td> children.
1426
+ *
1427
+ * @since 2.9
1428
+ */
1429
+ function table_row($cells, $id, $class) {
1430
+ $mk = $this->get_module_key();
1431
+ echo "\t<tr id='su-$mk-$id' class='su-$mk-$class'>\n";
1432
+ $this->table_cells($cells);
1433
+ echo "\t</tr>\n";
1434
+ }
1435
+
1436
+ /**
1437
+ * Outputs a <tr> tag with <td> children, and consolidates adjacent, identical <td> elements with the rowspan attribute.
1438
+ *
1439
+ * @since 2.9
1440
+ */
1441
+ function table_rows_consolidated($rows, $cols_to_consolidate = 999) {
1442
+ $mk = $this->get_module_key();
1443
+
1444
+ $rowspans = array();
1445
+
1446
+ //Cycle through each row
1447
+ foreach ($rows as $rowid => $row) {
1448
+
1449
+ echo "<tr>";
1450
+
1451
+ //Cycle through the row's cells
1452
+ $cellid = 0;
1453
+ foreach ($row as $class => $cell) {
1454
+
1455
+ //If a rowspan is already in process for this cell...
1456
+ if ($rowspans[$cellid] > 1)
1457
+ $rowspans[$cellid]--;
1458
+ else {
1459
+
1460
+ //Find out if we should start a rowspan
1461
+ $rowspanhtml = '';
1462
+ if ($cellid < $cols_to_consolidate) {
1463
+ $rowspan = 1;
1464
+ for ($larowid = $rowid+1; $larowid < count($rows); $larowid++) {
1465
+ $lacell = $rows[$larowid][$class];
1466
+ if (strlen($lacell) && $cell == $lacell) $rowspan++; else break;
1467
+ }
1468
+
1469
+ if ($rowspan > 1) {
1470
+ $rowspans[$cellid] = $rowspan;
1471
+ $rowspanhtml = " rowspan='$rowspan'";
1472
+ }
1473
+ }
1474
+
1475
+ echo "<td class='su-$mk-$class'$rowspanhtml>$cell</td>";
1476
+ }
1477
+
1478
+ $cellid++;
1479
+ }
1480
+
1481
+ echo "</tr>";
1482
+ }
1483
+ }
1484
+
1485
  /**
1486
  * Ends a "widefat" WordPress table.
1487
  *
1533
  * @param string $hovertext The text that only displays upon row hover.
1534
  * @return string The HTML to put in a hover-supporting table row.
1535
  */
1536
+ function hover_row($text, $hovertext, $inline = false) {
1537
+ if ($inline)
1538
+ return "<span>$text</span>\n<span class='row-actions'> &mdash; $hovertext</span>";
1539
+ else
1540
+ return "<div>$text</div>\n<div class='row-actions'>$hovertext</div>";
1541
  }
1542
 
1543
  /**
modules/modules.css CHANGED
@@ -17,7 +17,7 @@ div.su-module h4.su-subheader {
17
 
18
  div.su-module table.widefat {
19
  width: auto;
20
- margin: 2em 0;
21
  }
22
 
23
  div.su-module table.fullwidth,
@@ -136,6 +136,13 @@ div.su-module .su-tabs .su-tab-contents {
136
  margin-top: 1em;
137
  }
138
 
 
 
 
 
 
 
 
139
  /* IMPORT MODULES */
140
 
141
  .su-module table#import-status {
17
 
18
  div.su-module table.widefat {
19
  width: auto;
20
+ /*margin: 2em 0;*/
21
  }
22
 
23
  div.su-module table.fullwidth,
136
  margin-top: 1em;
137
  }
138
 
139
+ div.su-module .su-meta-edit-table table.widefat,
140
+ div.su-module .su-meta-edit-table table.widefat .regular-text { width: 100%; }
141
+ div.su-module .su-meta-edit-table table.widefat td.su-actions { width: 6em; }
142
+ div.su-module .su-meta-edit-table table.widefat td.su-id { width: 2em; }
143
+ div.su-module .su-meta-edit-table table.widefat td.su-name { width: 20em; }
144
+ div.su-module .su-meta-edit-table table.widefat td { vertical-align: middle; }
145
+
146
  /* IMPORT MODULES */
147
 
148
  .su-module table#import-status {
modules/settings/install.php CHANGED
@@ -88,12 +88,20 @@ class SU_Install extends SU_Module {
88
 
89
  function get_version_radiobuttons($min, $max) {
90
 
 
 
91
  $this->update_setting('version', SU_VERSION);
92
 
93
- $trunk_readme = suwp::load_webpage('http://plugins.trac.wordpress.org/browser/seo-ultimate/trunk/readme.txt?format=txt', SU_USER_AGENT);
94
- if (!$trunk_readme) return false;
95
- $trunk_changelog = sumd::get_section($trunk_readme, 'Changelog');
96
- $versions = sumd::get_sections($trunk_changelog);
 
 
 
 
 
 
97
 
98
  if (count($versions)) {
99
 
@@ -106,7 +114,7 @@ class SU_Install extends SU_Module {
106
  if ($max && version_compare($version, $max, '>')) continue;
107
  if ($min && version_compare($version, $min, '<')) break;
108
 
109
- $changes = wptexturize(Markdown($changes));
110
  if ($version == SU_VERSION)
111
  $message = __('Current Version', 'seo-ultimate');
112
  elseif ($first)
88
 
89
  function get_version_radiobuttons($min, $max) {
90
 
91
+ include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
92
+
93
  $this->update_setting('version', SU_VERSION);
94
 
95
+ $plugin = plugins_api('plugin_information', array('slug' => 'seo-ultimate'));
96
+ if (is_wp_error($plugin)) return false;
97
+ $changelog = $plugin->sections['changelog'];
98
+
99
+ $entries = explode('<h4>', $changelog);
100
+ $versions = array();
101
+ foreach ($entries as $entry) {
102
+ $item = explode('</h4>', $entry, 2);
103
+ if (count($item) == 2) $versions[$item[0]] = $item[1];
104
+ }
105
 
106
  if (count($versions)) {
107
 
114
  if ($max && version_compare($version, $max, '>')) continue;
115
  if ($min && version_compare($version, $min, '<')) break;
116
 
117
+ $changes = wptexturize($changes);
118
  if ($version == SU_VERSION)
119
  $message = __('Current Version', 'seo-ultimate');
120
  elseif ($first)
modules/settings/uninstall.php CHANGED
@@ -28,7 +28,7 @@ class SU_Uninstall extends SU_Module {
28
  echo "</p>\n";
29
  $url = $this->get_nonce_url('su-uninstall');
30
  $confirm = __("Are you sure you want to uninstall SEO Ultimate? This will permanently erase your SEO Ultimate settings and cannot be undone.", 'seo-ultimate');
31
- echo "<a href='$url' class='button-primary' onclick=\"javascript:return confirm('$confirm')\">".__("Uninstall Now", 'seo-ultimate')."</a>";
32
  }
33
 
34
  function enable_post_uninstall_page() {
28
  echo "</p>\n";
29
  $url = $this->get_nonce_url('su-uninstall');
30
  $confirm = __("Are you sure you want to uninstall SEO Ultimate? This will permanently erase your SEO Ultimate settings and cannot be undone.", 'seo-ultimate');
31
+ echo "<p><a href='$url' class='button-primary' onclick=\"javascript:return confirm('$confirm')\">".__("Uninstall Now", 'seo-ultimate')."</a></p>";
32
  }
33
 
34
  function enable_post_uninstall_page() {
modules/slugs/slugs.php CHANGED
@@ -46,7 +46,7 @@ class SU_Slugs extends SU_Module {
46
  $words = strtolower(stripslashes($this->get_setting('words_to_remove')));
47
 
48
  //Remove the stopwords from the slug
49
- $newslug = implode("-", array_diff(explode(" ", $slug), explode("\n", $words)));
50
 
51
  //Make sure we haven't removed too much!
52
  if (empty($newslug))
46
  $words = strtolower(stripslashes($this->get_setting('words_to_remove')));
47
 
48
  //Remove the stopwords from the slug
49
+ $newslug = implode("-", array_diff(explode(" ", $slug), suarr::explode_lines($words)));
50
 
51
  //Make sure we haven't removed too much!
52
  if (empty($newslug))
modules/titles/titles-formats.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
- /**
3
- * Title Rewriter Formats Module
4
- *
5
- * @since 1.5
6
- */
7
-
8
- class SU_TitlesFormats extends SU_Module {
9
-
10
- function get_parent_module() { return 'titles'; }
11
- function get_child_order() { return 10; }
12
- function is_independent_module() { return false; }
13
-
14
- function get_module_title() { return __('Title Rewriter Formats', 'seo-ultimate'); }
15
- function get_module_subtitle() { return __('Default Formats', 'seo-ultimate'); }
16
-
17
- function admin_page_contents() {
18
- echo "<table class='form-table'>\n";
19
- $this->textboxes($this->parent_module->get_supported_settings(), $this->parent_module->get_default_settings());
20
- echo "</table>";
21
- }
22
- }
23
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/titles/titles-posts.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
- /**
3
- * Post Title Editor Module
4
- *
5
- * @since 1.5
6
- */
7
-
8
- if (class_exists('SU_Module')) {
9
-
10
- class SU_TitlesPosts extends SU_Module {
11
-
12
- function get_parent_module() { return 'titles'; }
13
- function get_child_order() { return 20; }
14
- function is_independent_module() { return false; }
15
-
16
- function get_module_title() { return __('Post Title Editor', 'seo-ultimate'); }
17
-
18
- function get_admin_page_tabs() {
19
-
20
- $types = array();
21
-
22
- //Custom post type support - requires WordPress 3.0 or above (won't work with 2.9 custom post types)
23
- if (function_exists('get_post_types'))
24
- $types = suarr::flatten_values(get_post_types(array('public' => true), 'objects'), array('labels', 'name'));
25
-
26
- //Legacy support for WordPress 2.9 and below
27
- if (!$types)
28
- $types = array(
29
- 'post' => __('Posts')
30
- , 'page' => __('Pages')
31
- , 'attachment' => __('Attachments')
32
- );
33
-
34
- return $this->parent_module->get_object_subtype_tabs('post', array_keys($types), array_values($types), array(&$this, 'admin_page_tab'));
35
- }
36
-
37
- function admin_page_tab($post_type) {
38
- $this->parent_module->title_editing_table($post_type, 'get_posts', 'post_type='.$post_type.'&numberposts=%1$d&offset=%2$d');
39
- }
40
-
41
- }
42
-
43
- }
44
-
45
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/titles/titles-taxonomies.php DELETED
@@ -1,39 +0,0 @@
1
- <?php
2
- /**
3
- * Taxonomy Title Editor Module
4
- *
5
- * @since 1.9
6
- */
7
-
8
- if (class_exists('SU_Module')) {
9
-
10
- class SU_TitlesTaxonomies extends SU_Module {
11
-
12
- function get_parent_module() { return 'titles'; }
13
- function get_child_order() { return 30; }
14
- function is_independent_module() { return false; }
15
-
16
- function get_module_title() { return __('Taxonomy Title Editor', 'seo-ultimate'); }
17
-
18
- function get_admin_page_tabs() {
19
-
20
- $type_keys = array('category', 'post_tag');
21
-
22
- $type_labels = array(
23
- 'category' => __('Categories')
24
- , 'post_tag' => __('Post Tags')
25
- );
26
-
27
- return $this->parent_module->get_object_subtype_tabs('taxonomy', $type_keys, $type_labels, array(&$this, 'admin_page_tab'));
28
- }
29
-
30
- function admin_page_tab($tax_type) {
31
- $this->parent_module->title_editing_table($tax_type, 'get_terms', array($tax_type, 'number=%1$d&offset=%2$d'), 'taxonomy',
32
- 'term_id', 'name', array('suwp', 'get_taxonomy_link'));
33
- }
34
-
35
- }
36
-
37
- }
38
-
39
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/titles/titles.css DELETED
@@ -1,7 +0,0 @@
1
- #su-titles table.widefat {
2
- width: auto;
3
- }
4
-
5
- #su-titles table.widefat td input.regular-text {
6
- width: 400px;
7
- }
 
 
 
 
 
 
 
modules/titles/titles.php CHANGED
@@ -17,6 +17,26 @@ class SU_Titles extends SU_Module {
17
  add_filter('su_postmeta_help', array(&$this, 'postmeta_help'), 10);
18
  }
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  function get_default_settings() {
21
 
22
  //We internationalize even non-text formats (like "{post} | {blog}") to allow RTL languages to switch the order of the variables
@@ -53,12 +73,6 @@ class SU_Titles extends SU_Module {
53
  );
54
  }
55
 
56
- function admin_page_formats_tab() {
57
- echo "<table class='form-table'>\n";
58
- $this->textboxes($this->get_supported_settings(), $this->get_default_settings());
59
- echo "</table>";
60
- }
61
-
62
  function get_title_format() {
63
  if ($key = $this->get_current_page_type())
64
  return $this->get_setting("title_$key");
@@ -118,8 +132,11 @@ class SU_Titles extends SU_Module {
118
  return htmlspecialchars($this->get_title_paged($post_title));
119
 
120
  //Custom taxonomy title?
121
- if ((is_category() || is_tag() || is_tax()) && $tax_title = $this->get_taxonomy_title('', $wp_query->get_queried_object_id()))
122
- return htmlspecialchars($tax_title);
 
 
 
123
 
124
  //Load post/page titles
125
  $post_id = 0;
@@ -264,162 +281,6 @@ class SU_Titles extends SU_Module {
264
  return $url;
265
  }
266
 
267
- function admin_page_posts_tab() {
268
- $this->title_editing_table('post', __('Post'), 'get_posts');
269
- }
270
-
271
- function admin_page_pages_tab() {
272
- $this->title_editing_table('page', __('Page'), 'get_pages');
273
- }
274
-
275
- function get_id_from_settings_key($key) {
276
- $matches = array();
277
- //Custom post/taxonomy types must have alphanumeric names, or else this won't work
278
- if (preg_match('/([a-z0-9]+)_([0-9]+)_([a-z]+)/', $key, $matches))
279
- return (int)$matches[2];
280
-
281
- return false;
282
- }
283
-
284
- function get_singular_title($value, $key) {
285
- if ($id = $this->get_id_from_settings_key($key))
286
- return $this->get_postmeta('title', $id);
287
-
288
- return $value;
289
- }
290
-
291
- function save_singular_title($unused, $value, $key) {
292
- if ($id = $this->get_id_from_settings_key($key)) {
293
- update_post_meta($id, '_su_title', $value);
294
- return true;
295
- }
296
-
297
- return false;
298
- }
299
-
300
- function get_taxonomy_title($value, $key) {
301
- return $this->get_title_from_settings('taxonomy', $value, $key);
302
- }
303
-
304
- function save_taxonomy_title($unused, $value, $key) {
305
- return $this->save_title_to_settings('taxonomy', $value, $key);
306
- }
307
-
308
- function get_title_from_settings($type, $value, $key) {
309
- if (is_int($key))
310
- $id = $key;
311
- else
312
- $id = $this->get_id_from_settings_key($key);
313
-
314
- if ($id) {
315
- $titles = $this->get_setting($type.'_titles', array());
316
- return $titles[$id];
317
- }
318
-
319
- return $value;
320
- }
321
-
322
- function save_title_to_settings($type, $value, $key) {
323
- if (is_int($key))
324
- $id = $key;
325
- else
326
- $id = $this->get_id_from_settings_key($key);
327
-
328
- if ($id) {
329
- $titles = $this->get_setting($type.'_titles', array());
330
- $titles[$id] = $value;
331
- $this->update_setting($type.'_titles', $titles);
332
- }
333
-
334
- return false;
335
- }
336
-
337
- function title_editing_table($object_type, $function, $args, $func_set = 'singular',
338
- $id_varname = 'ID', $title_varname = 'post_title', $edit_link_function = 'get_edit_post_link') {
339
-
340
- $mk = $this->get_module_key();
341
-
342
- add_filter("su_get_setting-$mk", array(&$this, "get_{$func_set}_title"), 10, 2);
343
- add_filter("su_custom_update_setting-$mk", array(&$this, "save_{$func_set}_title"), 10, 3);
344
-
345
- $headers = array( __('ID'), __('Name'), __('Title Tag', 'seo-ultimate') );
346
-
347
- /*if (strlen($num_varname) && strlen($offset_varname))
348
- $args = "$num_varname=20&$offset_varname=0";
349
- else
350
- $args = '';*/
351
- //$args = "$num_varname=1000";
352
- $args = (array)$args;
353
- foreach ($args as $arg_key => $arg) {
354
- if (is_string($arg))
355
- $args[$arg_key] = sprintf($arg, 1000, 0);
356
- }
357
-
358
- $objects = call_user_func_array($function, $args);
359
- //$pagination_total = ceil(count($function()) / 2);
360
-
361
- if (!count($objects)) {
362
- $this->print_message('info', __('Your site currently doesn&#8217;t have any public items of this type.', 'seo-ultimate'));
363
- return false;
364
- }
365
-
366
- echo <<<STR
367
- <table class="widefat fullwidth" cellspacing="0">
368
- <thead><tr>
369
- <!--<th scope="col" class="$object_type-id">{$headers[0]}</th>-->
370
- <th scope="col" class="$object_type-title">{$headers[1]}</th>
371
- <th scope="col" class="$object_type-title-tag">{$headers[2]}</th>
372
- </tr></thead>
373
- <tbody>
374
-
375
- STR;
376
-
377
- foreach ($objects as $object) {
378
- $id = $object->$id_varname;
379
- $editlink = call_user_func($edit_link_function, $id, $object_type);
380
- $title = $object->$title_varname;
381
-
382
- if ($editlink) $label = "<a href='$editlink' target='_blank'>$title</a>"; else $label = $title;
383
- $this->textbox("{$object_type}_{$id}_title", $label);
384
- }
385
-
386
- echo "\t</tbody>\n</table>\n";
387
-
388
- return true;
389
- }
390
-
391
- function get_object_subtype_tabs($type, $keys, $labels, $callback) {
392
-
393
- $labels = apply_filters("su_{$type}_tabs", $labels);
394
-
395
- $types = array();
396
- foreach ($keys as $key) {
397
-
398
- $label = $labels[$key];
399
-
400
- if (!$label) {
401
- //Rudimentary English pluralization; would turn "post" to "Posts"
402
- //Can be internationalized later on
403
- $label = ucwords($key);
404
- if (sustr::endswith($label, 's'))
405
- $label .= 'es';
406
- else
407
- $label .= 's';
408
-
409
- $label = __($label, 'seo-ultimate');
410
- }
411
-
412
- $types[$key] = $label;
413
- }
414
-
415
- $tabs = array();
416
- foreach ($types as $key => $label) {
417
- $tabs[$label] = array($callback, $key);
418
- }
419
-
420
- return $tabs;
421
- }
422
-
423
  function postmeta_fields($fields) {
424
  $fields['10|title'] = $this->get_postmeta_textbox('title', __('Title Tag:', 'seo-ultimate'));
425
  return $fields;
17
  add_filter('su_postmeta_help', array(&$this, 'postmeta_help'), 10);
18
  }
19
 
20
+ function get_admin_page_tabs() {
21
+ return array_merge(
22
+ array(
23
+ __('Default Formats') => 'formats_tab'
24
+ )
25
+ , $this->get_meta_edit_tabs(array(
26
+ 'type' => 'textbox'
27
+ , 'name' => 'title'
28
+ , 'term_settings_key' => 'taxonomy_titles'
29
+ , 'label' => __('Title Tag', 'seo-ultimate')
30
+ ))
31
+ );
32
+ }
33
+
34
+ function formats_tab() {
35
+ echo "<table class='form-table'>\n";
36
+ $this->textboxes($this->get_supported_settings(), $this->get_default_settings());
37
+ echo "</table>";
38
+ }
39
+
40
  function get_default_settings() {
41
 
42
  //We internationalize even non-text formats (like "{post} | {blog}") to allow RTL languages to switch the order of the variables
73
  );
74
  }
75
 
 
 
 
 
 
 
76
  function get_title_format() {
77
  if ($key = $this->get_current_page_type())
78
  return $this->get_setting("title_$key");
132
  return htmlspecialchars($this->get_title_paged($post_title));
133
 
134
  //Custom taxonomy title?
135
+ if (is_category() || is_tag() || is_tax()) {
136
+ $tax_titles = $this->get_setting('taxonomy_titles');
137
+ if ($tax_title = $tax_titles[$wp_query->get_queried_object_id()])
138
+ return htmlspecialchars($tax_title);
139
+ }
140
 
141
  //Load post/page titles
142
  $post_id = 0;
281
  return $url;
282
  }
283
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  function postmeta_fields($fields) {
285
  $fields['10|title'] = $this->get_postmeta_textbox('title', __('Title Tag:', 'seo-ultimate'));
286
  return $fields;
modules/user-code/user-code.php CHANGED
@@ -46,6 +46,7 @@ class SU_UserCode extends SU_Module {
46
  function get_usercode($field) {
47
 
48
  $code = $this->get_setting("global_$field", '');
 
49
 
50
  return $this->plugin->mark_code($code, __('Code Inserter module', 'seo-ultimate'), $field == 'wp_head');
51
  }
46
  function get_usercode($field) {
47
 
48
  $code = $this->get_setting("global_$field", '');
49
+ if (is_front_page()) $code .= $this->get_setting("frontpage_$field", '');
50
 
51
  return $this->plugin->mark_code($code, __('Code Inserter module', 'seo-ultimate'), $field == 'wp_head');
52
  }
plugin/class.seo-ultimate.php CHANGED
@@ -138,6 +138,7 @@ class SEO_Ultimate {
138
 
139
  //Load
140
  $this->dbdata = maybe_unserialize(get_option('seo_ultimate', array()));
 
141
  $this->upgrade_to_08();
142
 
143
  //Save
138
 
139
  //Load
140
  $this->dbdata = maybe_unserialize(get_option('seo_ultimate', array()));
141
+ if (!is_array($this->dbdata)) $this->dbdata = array();
142
  $this->upgrade_to_08();
143
 
144
  //Save
plugin/global.css CHANGED
@@ -105,10 +105,6 @@ div.su-help h6 {
105
 
106
  /* POSTMETA BOX */
107
 
108
- #su-postmeta-box table tr {
109
- vertical-align: middle;
110
- }
111
-
112
  #su-postmeta-box table th,
113
  #su-postmeta-box table td {
114
  padding: 0.5em 0;
@@ -120,14 +116,6 @@ div.su-help h6 {
120
  padding-right: 0.5em;
121
  }
122
 
123
- #su-postmeta-box table tr {
124
- vertical-align: top;
125
- }
126
-
127
- #su-postmeta-box table tr.textbox {
128
- vertical-align: middle;
129
- }
130
-
131
  #su-postmeta-box table tr.textarea th label {
132
  display: block;
133
  margin-top: 5px;
105
 
106
  /* POSTMETA BOX */
107
 
 
 
 
 
108
  #su-postmeta-box table th,
109
  #su-postmeta-box table td {
110
  padding: 0.5em 0;
116
  padding-right: 0.5em;
117
  }
118
 
 
 
 
 
 
 
 
 
119
  #su-postmeta-box table tr.textarea th label {
120
  display: block;
121
  margin-top: 5px;
plugin/global.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+
2
+ function su_toggle_select_children(select) {
3
+ var i=0;
4
+ for (i=0;i<select.options.length;i++) {
5
+ var option = select.options[i];
6
+ var c = ".su_" + select.name.replace("_su_", "") + "_" + option.value + "_subsection";
7
+ if (option.index == select.selectedIndex) jQuery(c).show(); else jQuery(c).hide();
8
+ }
9
+ }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: SEO Design Solutions
3
  Tags: seo, google, yahoo, bing, search engines, admin, post, page, custom post types, modules, title, meta, robots, noindex, nofollow, canonical, 404, robots.txt, htaccess, slugs, url, anchor, more, link, excerpt, permalink, links, autolinks, code, footer, categories, uninstallable, reinstallable, downgradable
4
  Requires at least: 2.8
5
  Tested up to: 3.0
6
- Stable tag: 2.8
7
 
8
  This all-in-one SEO plugin gives you control over titles, noindex/nofollow, meta tags, slugs, canonical tags, "more" links, 404 errors, and more.
9
 
@@ -11,17 +11,17 @@ This all-in-one SEO plugin gives you control over titles, noindex/nofollow, meta
11
 
12
  = Recent Releases =
13
 
14
- * Version 2.8 adds custom post type editor to Title Rewriter
 
15
  * Version 2.7 adds the Code Inserter module
16
  * Version 2.6 adds reinstallation support
17
  * Version 2.5 adds advanced plugin upgrade/downgrade functionality
18
- * Version 2.4 adds a nofollow option for Deeplink Juggernaut links
19
 
20
  = Features =
21
 
22
  SEO Ultimate is an all-in-one [SEO](http://www.seodesignsolutions.com/) plugin with these powerful features:
23
 
24
- * **Title Rewriter** -- UPDATED in Version 2.8
25
  * Out-of-the-box functionality puts your post titles at the beginning of the `<title>` tag for improved keyword SEO.
26
  * Easily override the entire `<title>` tag contents for any individual post, page, attachment, category, or post tag on your blog. Also supports custom post types.
27
  * Customize your homepage's `<title>` tag.
@@ -74,7 +74,7 @@ SEO Ultimate is an all-in-one [SEO](http://www.seodesignsolutions.com/) plugin w
74
  * Determine which of your webpages Google most strongly associates with the keywords you specify.
75
  * Use the information to determine ideal targets for incoming links or ideal sources of outgoing links.
76
 
77
- * **Deeplink Juggernaut** -- UPDATED in Version 2.4
78
  * Automatically link phrases in your posts/pages to given URLs.
79
  * Use the power of anchor text to boost your internal ranking SEO paradigm.
80
  * Control the maximum number of autolinks added to each post/page.
@@ -192,8 +192,13 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
192
 
193
  == Changelog ==
194
 
 
 
 
 
 
195
  = Version 2.8 (June 8, 2010) =
196
- * Feature: Title Rewriter now adds mass-editor tabs for custom post types
197
  * Feature: Title Rewriter can now edit the title tags of attachments
198
  * Improvement: Title Rewriter's mass-editors no longer display an empty table when no items of a particular type exist
199
 
@@ -212,14 +217,14 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
212
  * Bugfix: Fixed "string offset" fatal error that appeared on certain setups
213
 
214
  = Version 2.4 (May 28, 2010) =
215
- * SEO Feature: Added nofollow option for Deeplink Juggernaut links
216
 
217
  = Version 2.3 (May 26, 2010) =
218
- * SEO Feature: Meta robots tags (index/noindex and follow/nofollow) can now be set for each post or page via the "SEO Settings" box
219
  * Behavior Change: Since the Noindex Manager's advertised functionality is controlling the "noindex" attribute only, its behavior has been changed to output "noindex,follow" where it previously outputted "noindex,nofollow"
220
 
221
  = Version 2.2 (May 24, 2010) =
222
- * SEO Feature: Deeplink Juggernaut now has a links-per-post limiter option
223
  * Bugfix: The current tab is now maintained when submitting a tabbed form twice in a row
224
  * Bugfix: When a module page reloads after submitting a tabbed form, the screen no longer jumps part-way down the page
225
 
@@ -249,10 +254,10 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
249
  * Known Issue: If you had previously disabled 404 Monitor in version 2.0 or earlier, it will re-enable itself when upgrading to version 2.1 or later. The workaround is to re-disable 404 Monitor from the Module Manager after upgrading.
250
 
251
  = Version 2.0 (April 29, 2010) =
252
- * SEO Feature: Title Rewriter can now edit the title tags of post tag archives
253
 
254
  = Version 1.9 (April 3, 2010) =
255
- * SEO Feature: Title Rewriter can now edit the title tags of category archives
256
 
257
  = Version 1.8.3 (March 30, 2010) =
258
  * Bugfix: Fixed bug that caused disabled attribution link to display under certain circumstances
@@ -264,7 +269,7 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
264
  * Bugfix: Fixed back-end Deeplink Juggernaut error
265
 
266
  = Version 1.8 (March 27, 2010) =
267
- * SEO Feature: Added Deeplink Juggernaut beta module
268
 
269
  = Version 1.7.3 (March 11, 2010) =
270
  * Bugfix: Fixed variable name conflict introduced in 1.7.1 that disabled WordPress's plugin/theme editors
@@ -284,7 +289,7 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
284
  * Improvement: Added blank index.php files to additional plugin directories
285
 
286
  = Version 1.7 (February 20, 2010) =
287
- * SEO Feature: Displays admin notices if blog privacy settings are configured to block search engines
288
 
289
  = Version 1.6 (January 30, 2010) =
290
  * Feature: Added All in One SEO Pack importer module
@@ -315,17 +320,17 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
315
  * Compatibility: Meta Editor now supports the new Google Webmaster Tools verification code
316
 
317
  = Version 1.4 (December 16, 2009) =
318
- * SEO Feature: Added the Internal Relevance Researcher
319
  * Bugfix: Title Rewriter no longer rewrites XML `<title>` tags in feeds
320
  * Improvement: Copied all documentation to the readme.txt file
321
 
322
  = Version 1.3 (November 13, 2009) =
323
- * SEO Feature: Added the More Link Customizer module
324
  * Bugfix: Postmeta fields now handle HTML entities properly
325
  * Improvement: Made minor tweaks to the Competition Researcher
326
 
327
  = Version 1.2 (October 31, 2009) =
328
- * SEO Feature: Added the Competition Researcher module
329
 
330
  = Version 1.1.2 (October 9, 2009) =
331
  * Compatibility: Added PHP4 support
@@ -334,14 +339,14 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
334
  * Bugfix: Fixed tab rendering bug
335
 
336
  = Version 1.1 (October 7, 2009) =
337
- * SEO Feature: You can now mass-edit post/page titles from the Title Rewriter module
338
  * Bugfix: Fixed logo background color in the Whitepapers module
339
  * Improvement: Title Rewriter now supports 10 additional title format variables
340
  * Improvement: Added internationalization support for admin menu notice numbers
341
  * Improvement: Certain third-party plugin notices are now removed from SEO Ultimate's admin pages
342
 
343
  = Version 1.0 (September 21, 2009) =
344
- * SEO Feature: Canonicalizer can now redirect requests for nonexistent pagination
345
  * Feature: Visitor logging can now be disabled completely from the Plugin Settings page
346
  * Feature: Logged visitor information can now be automatically deleted after a certain number of days
347
  * Feature: Added icon support for the Ozh Admin Drop Down Menu plugin
@@ -359,8 +364,8 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
359
  * Bugfix: Fixed PHP parse errors
360
 
361
  = Version 0.9 (August 1, 2009) =
362
- * SEO Feature: Added the Slug Optimizer module
363
- * SEO Feature: Noindex Manager now supports noindexing comment subpages
364
  * Bugfix: 404 Monitor's numeric notice now only includes new 404s
365
  * Bugfix: Linkbox Inserter now respects the "more" tag
366
  * Bugfix: Missing strings added to the POT file
@@ -373,8 +378,8 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
373
  * Improvement: Many additional code comments added
374
 
375
  = Version 0.8 (July 22, 2009) =
376
- * SEO Feature: Added robots.txt editor (new File Editor module)
377
- * SEO Feature: Added .htaccess editor (new File Editor module)
378
  * Bugfix: 404 Monitor no longer uses the unreliable get_browser() function
379
  * Bugfix: 404 Monitor now ignores favicon requests
380
  * Bugfix: Fixed conflict with the WP Table Reloaded plugin
@@ -396,7 +401,7 @@ Frequently asked questions, settings help, and troubleshooting tips for SEO Ulti
396
  * Feature: Modules can optionally display numeric notices in the menu
397
 
398
  = Version 0.6 (July 2, 2009) =
399
- * SEO Feature: Added the Linkbox Inserter module
400
  * Bugfix: Fixed plugin notices bug
401
 
402
  = Version 0.5 (June 25, 2009) =
3
  Tags: seo, google, yahoo, bing, search engines, admin, post, page, custom post types, modules, title, meta, robots, noindex, nofollow, canonical, 404, robots.txt, htaccess, slugs, url, anchor, more, link, excerpt, permalink, links, autolinks, code, footer, categories, uninstallable, reinstallable, downgradable
4
  Requires at least: 2.8
5
  Tested up to: 3.0
6
+ Stable tag: 2.9
7
 
8
  This all-in-one SEO plugin gives you control over titles, noindex/nofollow, meta tags, slugs, canonical tags, "more" links, 404 errors, and more.
9
 
11
 
12
  = Recent Releases =
13
 
14
+ * Version 2.9 adds custom taxonomy support to Title Rewriter
15
+ * Version 2.8 adds custom post type support to Title Rewriter
16
  * Version 2.7 adds the Code Inserter module
17
  * Version 2.6 adds reinstallation support
18
  * Version 2.5 adds advanced plugin upgrade/downgrade functionality
 
19
 
20
  = Features =
21
 
22
  SEO Ultimate is an all-in-one [SEO](http://www.seodesignsolutions.com/) plugin with these powerful features:
23
 
24
+ * **Title Rewriter** -- UPDATED in Version 2.9
25
  * Out-of-the-box functionality puts your post titles at the beginning of the `<title>` tag for improved keyword SEO.
26
  * Easily override the entire `<title>` tag contents for any individual post, page, attachment, category, or post tag on your blog. Also supports custom post types.
27
  * Customize your homepage's `<title>` tag.
74
  * Determine which of your webpages Google most strongly associates with the keywords you specify.
75
  * Use the information to determine ideal targets for incoming links or ideal sources of outgoing links.
76
 
77
+ * **Deeplink Juggernaut**
78
  * Automatically link phrases in your posts/pages to given URLs.
79
  * Use the power of anchor text to boost your internal ranking SEO paradigm.
80
  * Control the maximum number of autolinks added to each post/page.
192
 
193
  == Changelog ==
194
 
195
+ = Version 2.9 (June 17, 2010) =
196
+ * Feature: Title Rewriter now has mass-editor tabs for custom taxonomies
197
+ * Feature: Title Rewriter mass-editors now support pagination
198
+ * Improvement: Upgrade/downgrade tabs now use official WordPress plugin API to obtain version info
199
+
200
  = Version 2.8 (June 8, 2010) =
201
+ * Feature: Title Rewriter now has mass-editor tabs for custom post types
202
  * Feature: Title Rewriter can now edit the title tags of attachments
203
  * Improvement: Title Rewriter's mass-editors no longer display an empty table when no items of a particular type exist
204
 
217
  * Bugfix: Fixed "string offset" fatal error that appeared on certain setups
218
 
219
  = Version 2.4 (May 28, 2010) =
220
+ * Feature: Added nofollow option for Deeplink Juggernaut links
221
 
222
  = Version 2.3 (May 26, 2010) =
223
+ * Feature: Meta robots tags (index/noindex and follow/nofollow) can now be set for each post or page via the "SEO Settings" box
224
  * Behavior Change: Since the Noindex Manager's advertised functionality is controlling the "noindex" attribute only, its behavior has been changed to output "noindex,follow" where it previously outputted "noindex,nofollow"
225
 
226
  = Version 2.2 (May 24, 2010) =
227
+ * Feature: Deeplink Juggernaut now has a links-per-post limiter option
228
  * Bugfix: The current tab is now maintained when submitting a tabbed form twice in a row
229
  * Bugfix: When a module page reloads after submitting a tabbed form, the screen no longer jumps part-way down the page
230
 
254
  * Known Issue: If you had previously disabled 404 Monitor in version 2.0 or earlier, it will re-enable itself when upgrading to version 2.1 or later. The workaround is to re-disable 404 Monitor from the Module Manager after upgrading.
255
 
256
  = Version 2.0 (April 29, 2010) =
257
+ * Feature: Title Rewriter can now edit the title tags of post tag archives
258
 
259
  = Version 1.9 (April 3, 2010) =
260
+ * Feature: Title Rewriter can now edit the title tags of category archives
261
 
262
  = Version 1.8.3 (March 30, 2010) =
263
  * Bugfix: Fixed bug that caused disabled attribution link to display under certain circumstances
269
  * Bugfix: Fixed back-end Deeplink Juggernaut error
270
 
271
  = Version 1.8 (March 27, 2010) =
272
+ * Feature: Added Deeplink Juggernaut beta module
273
 
274
  = Version 1.7.3 (March 11, 2010) =
275
  * Bugfix: Fixed variable name conflict introduced in 1.7.1 that disabled WordPress's plugin/theme editors
289
  * Improvement: Added blank index.php files to additional plugin directories
290
 
291
  = Version 1.7 (February 20, 2010) =
292
+ * Feature: Displays admin notices if blog privacy settings are configured to block search engines
293
 
294
  = Version 1.6 (January 30, 2010) =
295
  * Feature: Added All in One SEO Pack importer module
320
  * Compatibility: Meta Editor now supports the new Google Webmaster Tools verification code
321
 
322
  = Version 1.4 (December 16, 2009) =
323
+ * Feature: Added the Internal Relevance Researcher
324
  * Bugfix: Title Rewriter no longer rewrites XML `<title>` tags in feeds
325
  * Improvement: Copied all documentation to the readme.txt file
326
 
327
  = Version 1.3 (November 13, 2009) =
328
+ * Feature: Added the More Link Customizer module
329
  * Bugfix: Postmeta fields now handle HTML entities properly
330
  * Improvement: Made minor tweaks to the Competition Researcher
331
 
332
  = Version 1.2 (October 31, 2009) =
333
+ * Feature: Added the Competition Researcher module
334
 
335
  = Version 1.1.2 (October 9, 2009) =
336
  * Compatibility: Added PHP4 support
339
  * Bugfix: Fixed tab rendering bug
340
 
341
  = Version 1.1 (October 7, 2009) =
342
+ * Feature: You can now mass-edit post/page titles from the Title Rewriter module
343
  * Bugfix: Fixed logo background color in the Whitepapers module
344
  * Improvement: Title Rewriter now supports 10 additional title format variables
345
  * Improvement: Added internationalization support for admin menu notice numbers
346
  * Improvement: Certain third-party plugin notices are now removed from SEO Ultimate's admin pages
347
 
348
  = Version 1.0 (September 21, 2009) =
349
+ * Feature: Canonicalizer can now redirect requests for nonexistent pagination
350
  * Feature: Visitor logging can now be disabled completely from the Plugin Settings page
351
  * Feature: Logged visitor information can now be automatically deleted after a certain number of days
352
  * Feature: Added icon support for the Ozh Admin Drop Down Menu plugin
364
  * Bugfix: Fixed PHP parse errors
365
 
366
  = Version 0.9 (August 1, 2009) =
367
+ * Feature: Added the Slug Optimizer module
368
+ * Feature: Noindex Manager now supports noindexing comment subpages
369
  * Bugfix: 404 Monitor's numeric notice now only includes new 404s
370
  * Bugfix: Linkbox Inserter now respects the "more" tag
371
  * Bugfix: Missing strings added to the POT file
378
  * Improvement: Many additional code comments added
379
 
380
  = Version 0.8 (July 22, 2009) =
381
+ * Feature: Added robots.txt editor (new File Editor module)
382
+ * Feature: Added .htaccess editor (new File Editor module)
383
  * Bugfix: 404 Monitor no longer uses the unreliable get_browser() function
384
  * Bugfix: 404 Monitor now ignores favicon requests
385
  * Bugfix: Fixed conflict with the WP Table Reloaded plugin
401
  * Feature: Modules can optionally display numeric notices in the menu
402
 
403
  = Version 0.6 (July 2, 2009) =
404
+ * Feature: Added the Linkbox Inserter module
405
  * Bugfix: Fixed plugin notices bug
406
 
407
  = Version 0.5 (June 25, 2009) =
seo-ultimate.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: SEO Ultimate
4
  Plugin URI: http://www.seodesignsolutions.com/wordpress-seo/
5
  Description: This all-in-one SEO plugin gives you control over title tags, noindex/nofollow, meta tags, slugs, canonical tags, "more" links, 404 errors, and more.
6
- Version: 2.8
7
  Author: SEO Design Solutions
8
  Author URI: http://www.seodesignsolutions.com/
9
  Text Domain: seo-ultimate
@@ -12,7 +12,7 @@ Text Domain: seo-ultimate
12
  /**
13
  * The main SEO Ultimate plugin file.
14
  * @package SeoUltimate
15
- * @version 2.8
16
  * @link http://www.seodesignsolutions.com/wordpress-seo/ SEO Ultimate Homepage
17
  */
18
 
@@ -38,10 +38,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
38
  //Reading plugin info from constants is faster than trying to parse it from the header above.
39
  define("SU_PLUGIN_NAME", "SEO Ultimate");
40
  define("SU_PLUGIN_URI", "http://www.seodesignsolutions.com/wordpress-seo/");
41
- define("SU_VERSION", "2.8");
42
  define("SU_AUTHOR", "SEO Design Solutions");
43
  define("SU_AUTHOR_URI", "http://www.seodesignsolutions.com/");
44
- define("SU_USER_AGENT", "SeoUltimate/2.8");
45
 
46
  /********** INCLUDES **********/
47
 
3
  Plugin Name: SEO Ultimate
4
  Plugin URI: http://www.seodesignsolutions.com/wordpress-seo/
5
  Description: This all-in-one SEO plugin gives you control over title tags, noindex/nofollow, meta tags, slugs, canonical tags, "more" links, 404 errors, and more.
6
+ Version: 2.9
7
  Author: SEO Design Solutions
8
  Author URI: http://www.seodesignsolutions.com/
9
  Text Domain: seo-ultimate
12
  /**
13
  * The main SEO Ultimate plugin file.
14
  * @package SeoUltimate
15
+ * @version 2.9
16
  * @link http://www.seodesignsolutions.com/wordpress-seo/ SEO Ultimate Homepage
17
  */
18
 
38
  //Reading plugin info from constants is faster than trying to parse it from the header above.
39
  define("SU_PLUGIN_NAME", "SEO Ultimate");
40
  define("SU_PLUGIN_URI", "http://www.seodesignsolutions.com/wordpress-seo/");
41
+ define("SU_VERSION", "2.9");
42
  define("SU_AUTHOR", "SEO Design Solutions");
43
  define("SU_AUTHOR_URI", "http://www.seodesignsolutions.com/");
44
+ define("SU_USER_AGENT", "SeoUltimate/2.9");
45
 
46
  /********** INCLUDES **********/
47