SEO Ultimate - Version 0.8

Version Description

Download this release

Release Info

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

Code changes from version 0.7 to 0.8

class.seo-ultimate.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * The main class. Provides plugin-level functionality.
4
  *
5
- * @version 1.3.2
6
  * @since 0.1
7
  */
8
  class SEO_Ultimate {
@@ -26,12 +26,12 @@ class SEO_Ultimate {
26
  var $disabled_modules = array();
27
 
28
  /**
29
- * Stores the status (disabled/hidden/silenced/enabled) of each module.
30
  *
31
- * @since 0.1
32
  * @var array
33
  */
34
- var $module_status = array();
35
 
36
  /**
37
  * The server path of this plugin file.
@@ -93,6 +93,8 @@ class SEO_Ultimate {
93
  * PHP5-style constructor.
94
  *
95
  * @since 0.1
 
 
96
  * @uses load_plugin_data()
97
  * @uses SU_VERSION
98
  * @uses install()
@@ -101,15 +103,27 @@ class SEO_Ultimate {
101
  * @uses activate() Registered with WordPress as the activation hook.
102
  * @uses init() Hooked into WordPress's "init" action.
103
  * @uses add_menus() Hooked into WordPress's "admin_menu" action.
104
- * @uses sanitize_menu_hook() Hooked into WordPress's "sanitize_title" filter.
105
  * @uses admin_includes() Hooked into WordPress's "admin_head" action.
106
  * @uses plugin_page_notices() Hooked into WordPress's "admin_head" action.
107
- * @uses admin_help() Hooked into WordPress's "contextual_help" action.
108
- * @uses log_redirect() Hooked into WordPress's "wp_redirect" action.
109
- * @uses log_hit() Hooked into WordPress's "status_header" action.
 
 
 
 
110
  */
111
  function __construct() {
112
 
 
 
 
 
 
 
 
 
 
113
  /********** CLASS CONSTRUCTION **********/
114
 
115
  //Load data about the plugin file itself into the class
@@ -118,21 +132,27 @@ class SEO_Ultimate {
118
 
119
  /********** VERSION CHECKING **********/
120
 
121
- //Get the current version, and the version when the plugin last ran
122
  $version = SU_VERSION;
123
- $oldversion = get_option('su_version', false);
124
 
125
- //If this is the first time the plugin is running, then install()
126
- if ($oldversion === false)
 
 
 
 
 
 
 
 
 
 
 
127
  $this->install();
128
-
129
- //If $oldversion is less than $version, then upgrade()
130
- elseif (version_compare($version, $oldversion) == 1)
131
- $this->upgrade($oldversion);
132
 
133
  //Store the current version in the database.
134
- //Rest assured, WordPress won't waste a database query if the value hasn't changed.
135
- update_option('su_version', $version);
136
 
137
 
138
  /********** INITIALIZATION **********/
@@ -174,7 +194,7 @@ class SEO_Ultimate {
174
  add_action('admin_menu', array($this, 'add_menus'), 10);
175
 
176
  //Hook to customize contextual help
177
- add_action('contextual_help', array($this, 'admin_help'), 10, 2);
178
 
179
  //Postmeta box hooks
180
  add_action('admin_menu', array($this, 'add_postmeta_box'));
@@ -214,9 +234,9 @@ class SEO_Ultimate {
214
  $this->db_setup();
215
 
216
  //Load settings file if present
217
- if (get_option('su_settings') === false && is_readable($settingsfile = $this->plugin_dir_path.'settings.txt')) {
218
  $import = base64_decode(file_get_contents($settingsfile));
219
- if (is_serialized($import)) update_option('su_settings', $import);
220
  }
221
  }
222
 
@@ -224,13 +244,31 @@ class SEO_Ultimate {
224
  * This will be called if the plugin's version has increased since the last run.
225
  *
226
  * @since 0.1
 
 
227
  */
228
- function upgrade() {
229
 
230
  //Upgrade database schemas if needed
231
  $this->db_setup();
232
  }
233
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  /**
235
  * WordPress will call this when the plugin is activated, as instructed by the register_activation_hook() call in {@link __construct()}.
236
  * Does activation tasks for the plugin itself, not modules.
@@ -256,10 +294,13 @@ class SEO_Ultimate {
256
  $this->remove_cron_jobs(true);
257
 
258
  //Delete module records, so that modules are re-activated if the plugin is.
259
- delete_option('su_modules');
260
 
261
  //Delete all cron job records, since the jobs no longer exist
262
- delete_option('su_cron');
 
 
 
263
  }
264
 
265
  /**
@@ -275,9 +316,12 @@ class SEO_Ultimate {
275
  //Let modules run uninstallation tasks
276
  do_action('su_uninstall');
277
 
278
- //Delete all other options that aren't deleted in deactivate()
279
- delete_option('su_version');
280
- delete_option('su_settings');
 
 
 
281
 
282
  //Delete the hits table
283
  mysql_query("DROP TABLE IF EXISTS ".$this->get_table_name('hits'));
@@ -324,20 +368,19 @@ class SEO_Ultimate {
324
  //The modules are in the "modules" subdirectory of the plugin folder.
325
  $dir = opendir($this->plugin_dir_path.'modules');
326
 
327
- //Get the modules list from last time the plugin was loaded.
328
- $oldmodules = maybe_unserialize(get_option('su_modules', false));
 
329
 
330
- //If no list is found, then create a new, empty list.
331
- if ($oldmodules === false) {
332
- $oldmodules = array();
333
- add_option('su_modules', serialize($oldmodules));
334
- }
335
 
336
  //This loop will be repeated as long as there are more files to inspect
337
  while ($file = readdir($dir)) {
338
 
339
  //Modules are non-directory files with the .php extension
340
- if ($file != '.' && $file != '..' && !is_dir($file) &&
 
341
  substr($file, -4) == '.php') {
342
 
343
  //Figure out the module's array key and class name
@@ -402,8 +445,7 @@ class SEO_Ultimate {
402
  }
403
 
404
  //Save the new modules list
405
- $this->module_status = $newmodules;
406
- update_option('su_modules', serialize($newmodules));
407
 
408
  //Remove the cron jobs of deleted modules
409
  $this->remove_cron_jobs();
@@ -475,6 +517,26 @@ class SEO_Ultimate {
475
  return '';
476
  }
477
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
478
  /**
479
  * A status_header WordPress filter that logs the current hit.
480
  *
@@ -575,7 +637,7 @@ class SEO_Ultimate {
575
  //If subitems have numeric bubbles, then add them up and show the total by the main menu item
576
  $count = 0;
577
  foreach ($this->modules as $key => $module) {
578
- if ($this->module_status[$key] > SU_MODULE_SILENCED && $module->get_menu_count() > 0 && $module->get_menu_parent() == 'seo')
579
  $count += $module->get_menu_count();
580
  }
581
  $count_code = $this->get_menu_count_code($count);
@@ -595,12 +657,12 @@ class SEO_Ultimate {
595
 
596
  //If the module is hidden, put the module under a non-existant menu parent
597
  //(this will let the module's admin page be loaded, but it won't show up on the menu)
598
- if ($this->module_status[$file] > SU_MODULE_HIDDEN)
599
  $parent = $module->get_menu_parent();
600
  else
601
  $parent = 'su-hidden-modules';
602
 
603
- if ($this->module_status[$file] > SU_MODULE_SILENCED)
604
  $count_code = $this->get_menu_count_code($module->get_menu_count());
605
  else
606
  $count_code = '';
@@ -884,10 +946,7 @@ class SEO_Ultimate {
884
  */
885
  function get_postmeta_fields($screen='post') {
886
 
887
- //Compile the fields array
888
- $fields = array();
889
- foreach ($this->modules as $module)
890
- $fields = $module->postmeta_fields($fields, $screen);
891
 
892
  if (count($fields) > 0) {
893
 
@@ -900,7 +959,23 @@ class SEO_Ultimate {
900
 
901
  return '';
902
  }
903
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
904
  /**
905
  * If we have post meta fields to display, then register our meta box with WordPress.
906
  *
@@ -966,57 +1041,45 @@ class SEO_Ultimate {
966
  * @since 0.1
967
  *
968
  * @param int $post_id The ID of the post being saved.
969
- * @return int The ID of the post being saved.
970
  */
971
  function save_postmeta_box($post_id, $post) {
972
 
973
  //Sanitize
974
  $post_id = (int)$post_id;
975
 
976
- //Don't save postmeta if this is a revision!
977
- if ($post->post_type == 'revision') return;
978
-
979
  //Run preliminary permissions checks
980
- if ( !check_admin_referer('su-update-postmeta', '_su_wpnonce') ) return;
981
  if ( 'page' == $_POST['post_type'] ) {
982
  if ( !current_user_can( 'edit_page', $post_id )) return;
983
  } elseif ( 'post' == $_POST['post_type'] ) {
984
  if ( !current_user_can( 'edit_post', $post_id )) return;
985
  } else return;
986
 
987
- //Get an array of all postmeta
988
- $allmeta = wp_cache_get($post_id, 'post_meta');
989
- if (!$allmeta) {
990
- update_postmeta_cache($post_id);
991
- $allmeta = wp_cache_get($post_id, 'post_meta');
992
- }
993
 
994
- //Update postmeta values
995
- foreach ($_POST as $key => $value) {
996
- if (substr($key, 0, 4) == '_su_') {
997
-
998
- //Turn checkboxes into integers
999
- if (strcmp($value, '1') == 0) $value = 1;
1000
-
1001
- //Set the postmeta
1002
- update_post_meta($post_id, $key, $value);
1003
-
1004
- //This value has been updated.
1005
- unset($allmeta[$key]);
1006
- }
1007
  }
1008
 
1009
- //Update values for unchecked checkboxes.
1010
- foreach ($allmeta as $key => $value) {
1011
- if (substr($key, 0, 4) == '_su_') {
1012
- $value = maybe_unserialize($value[0]);
1013
- if ($value == 1)
1014
- update_post_meta($post_id, $key, 0);
 
 
 
 
 
 
1015
  }
1016
  }
1017
-
1018
- //All done
1019
- return $post_id;
1020
  }
1021
 
1022
 
@@ -1030,7 +1093,7 @@ class SEO_Ultimate {
1030
  * @param bool $remove_all Whether to remove all cron jobs. Optional.
1031
  */
1032
  function remove_cron_jobs($remove_all = false) {
1033
- $crondata = maybe_unserialize(get_option('su_cron'));
1034
  if (is_array($crondata)) {
1035
  $newcrondata = $crondata;
1036
 
@@ -1041,7 +1104,7 @@ class SEO_Ultimate {
1041
  }
1042
  }
1043
 
1044
- update_option('su_cron', serialize($newcrondata));
1045
  }
1046
  }
1047
 
2
  /**
3
  * The main class. Provides plugin-level functionality.
4
  *
5
+ * @version 1.5
6
  * @since 0.1
7
  */
8
  class SEO_Ultimate {
26
  var $disabled_modules = array();
27
 
28
  /**
29
+ * Stores all database data.
30
  *
31
+ * @since 0.8
32
  * @var array
33
  */
34
+ var $dbdata = array();
35
 
36
  /**
37
  * The server path of this plugin file.
93
  * PHP5-style constructor.
94
  *
95
  * @since 0.1
96
+ * @uses $dbdata
97
+ * @uses save_dbdata()
98
  * @uses load_plugin_data()
99
  * @uses SU_VERSION
100
  * @uses install()
103
  * @uses activate() Registered with WordPress as the activation hook.
104
  * @uses init() Hooked into WordPress's "init" action.
105
  * @uses add_menus() Hooked into WordPress's "admin_menu" action.
 
106
  * @uses admin_includes() Hooked into WordPress's "admin_head" action.
107
  * @uses plugin_page_notices() Hooked into WordPress's "admin_head" action.
108
+ * @uses admin_help() Hooked into WordPress's "contextual_help" filter.
109
+ * @uses add_postmeta_box() Hooked into WordPress's "admin_menu" action.
110
+ * @uses save_postmeta_box() Hooked into WordPress's "save_post" action.
111
+ * @uses plugin_update_info() Hooked into the "in_plugin_update_message-seo-ultimate/seo-ultimate.php" action.
112
+ * @uses log_redirect_canonical() Hooked into WordPress's "redirect_canonical" filter.
113
+ * @uses log_redirect() Hooked into WordPress's "wp_redirect" filter.
114
+ * @uses log_hit() Hooked into WordPress's "status_header" filter.
115
  */
116
  function __construct() {
117
 
118
+ /********** LOAD/SAVE DATABASE DATA **********/
119
+
120
+ //Load
121
+ $this->dbdata = get_option('seo_ultimate', array());
122
+ $this->upgrade_to_08();
123
+
124
+ //Save
125
+ add_action('shutdown', array($this, 'save_dbdata'));
126
+
127
  /********** CLASS CONSTRUCTION **********/
128
 
129
  //Load data about the plugin file itself into the class
132
 
133
  /********** VERSION CHECKING **********/
134
 
135
+ //Get the current version
136
  $version = SU_VERSION;
 
137
 
138
+ //Get the version when the plugin last ran.
139
+ if (isset($this->dbdata['version']))
140
+ $oldversion = $this->dbdata['version'];
141
+ else
142
+ $oldversion = get_option('su_version', false);
143
+
144
+ //Or, if this is the first time the plugin is running, then install()
145
+ if ($oldversion) {
146
+
147
+ //If $oldversion is less than $version, then upgrade()
148
+ if (version_compare($version, $oldversion) == 1)
149
+ $this->upgrade($oldversion);
150
+ } else {
151
  $this->install();
152
+ }
 
 
 
153
 
154
  //Store the current version in the database.
155
+ $this->dbdata['version'] = $version;
 
156
 
157
 
158
  /********** INITIALIZATION **********/
194
  add_action('admin_menu', array($this, 'add_menus'), 10);
195
 
196
  //Hook to customize contextual help
197
+ add_filter('contextual_help', array($this, 'admin_help'), 10, 2);
198
 
199
  //Postmeta box hooks
200
  add_action('admin_menu', array($this, 'add_postmeta_box'));
234
  $this->db_setup();
235
 
236
  //Load settings file if present
237
+ if (!isset($this->dbdata['settings']) && is_readable($settingsfile = $this->plugin_dir_path.'settings.txt')) {
238
  $import = base64_decode(file_get_contents($settingsfile));
239
+ if (is_serialized($import)) $this->dbdata['settings'] = unserialize($import);
240
  }
241
  }
242
 
244
  * This will be called if the plugin's version has increased since the last run.
245
  *
246
  * @since 0.1
247
+ *
248
+ * @param string $oldversion The version that was last installed.
249
  */
250
+ function upgrade($oldversion) {
251
 
252
  //Upgrade database schemas if needed
253
  $this->db_setup();
254
  }
255
 
256
+ /**
257
+ * Upgrades SEO Ultimate to version 0.8.
258
+ *
259
+ * @since 0.8
260
+ * @uses $dbdata
261
+ */
262
+ function upgrade_to_08() {
263
+ $options = array('cron', 'modules', 'settings', 'version');
264
+ foreach ($options as $option) {
265
+ if (($value = get_option("su_$option", false)) !== false) {
266
+ $this->dbdata[$option] = maybe_unserialize($value);
267
+ delete_option("su_$option");
268
+ }
269
+ }
270
+ }
271
+
272
  /**
273
  * WordPress will call this when the plugin is activated, as instructed by the register_activation_hook() call in {@link __construct()}.
274
  * Does activation tasks for the plugin itself, not modules.
294
  $this->remove_cron_jobs(true);
295
 
296
  //Delete module records, so that modules are re-activated if the plugin is.
297
+ unset($this->dbdata['modules']);
298
 
299
  //Delete all cron job records, since the jobs no longer exist
300
+ unset($this->dbdata['cron']);
301
+
302
+ //Save to database
303
+ $this->save_dbdata();
304
  }
305
 
306
  /**
316
  //Let modules run uninstallation tasks
317
  do_action('su_uninstall');
318
 
319
+ //Delete all database data
320
+ $this->dbdata = array();
321
+ delete_option('seo_ultimate');
322
+
323
+ //Stop the database data from being re-saved
324
+ remove_action('shutdown', array($this, 'save_dbdata'));
325
 
326
  //Delete the hits table
327
  mysql_query("DROP TABLE IF EXISTS ".$this->get_table_name('hits'));
368
  //The modules are in the "modules" subdirectory of the plugin folder.
369
  $dir = opendir($this->plugin_dir_path.'modules');
370
 
371
+ //If no modules list is found, then create a new, empty list.
372
+ if (!isset($this->dbdata['modules']))
373
+ $this->dbdata['modules'] = array();
374
 
375
+ //Get the modules list from last time the plugin was loaded.
376
+ $oldmodules = $this->dbdata['modules'];
 
 
 
377
 
378
  //This loop will be repeated as long as there are more files to inspect
379
  while ($file = readdir($dir)) {
380
 
381
  //Modules are non-directory files with the .php extension
382
+ //We need to exclude index.php or else we'll get 403s galore
383
+ if ($file != '.' && $file != '..' && $file != 'index.php' && !is_dir($file) &&
384
  substr($file, -4) == '.php') {
385
 
386
  //Figure out the module's array key and class name
445
  }
446
 
447
  //Save the new modules list
448
+ $this->dbdata['modules'] = $newmodules;
 
449
 
450
  //Remove the cron jobs of deleted modules
451
  $this->remove_cron_jobs();
517
  return '';
518
  }
519
 
520
+ /**
521
+ * Saves data to the database.
522
+ *
523
+ * @since 0.8
524
+ * @uses $dbdata
525
+ */
526
+ function save_dbdata() {
527
+
528
+ //If we don't clear the cache, we sometimes end up with multiple seo_ultimate options entries
529
+ wp_cache_delete('seo_ultimate', 'options');
530
+ wp_cache_delete('notoptions', 'options');
531
+
532
+ if (empty($this->dbdata))
533
+ //If we don't have any data to save, then delete the option instead of saving an empty array
534
+ delete_option('seo_ultimate');
535
+ else
536
+ //Save our data to the database
537
+ update_option('seo_ultimate', $this->dbdata);
538
+ }
539
+
540
  /**
541
  * A status_header WordPress filter that logs the current hit.
542
  *
637
  //If subitems have numeric bubbles, then add them up and show the total by the main menu item
638
  $count = 0;
639
  foreach ($this->modules as $key => $module) {
640
+ if ($this->dbdata['modules'][$key] > SU_MODULE_SILENCED && $module->get_menu_count() > 0 && $module->get_menu_parent() == 'seo')
641
  $count += $module->get_menu_count();
642
  }
643
  $count_code = $this->get_menu_count_code($count);
657
 
658
  //If the module is hidden, put the module under a non-existant menu parent
659
  //(this will let the module's admin page be loaded, but it won't show up on the menu)
660
+ if ($this->dbdata['modules'][$file] > SU_MODULE_HIDDEN)
661
  $parent = $module->get_menu_parent();
662
  else
663
  $parent = 'su-hidden-modules';
664
 
665
+ if ($this->dbdata['modules'][$file] > SU_MODULE_SILENCED)
666
  $count_code = $this->get_menu_count_code($module->get_menu_count());
667
  else
668
  $count_code = '';
946
  */
947
  function get_postmeta_fields($screen='post') {
948
 
949
+ $fields = $this->get_postmeta_array($screen);
 
 
 
950
 
951
  if (count($fields) > 0) {
952
 
959
 
960
  return '';
961
  }
962
+
963
+ /**
964
+ * Compiles the post meta box field array based on data provided by the modules.
965
+ *
966
+ * @since 0.8
967
+ * @uses SU_Module::postmeta_fields()
968
+ *
969
+ * @param string $screen The admin screen currently being viewed (post, page). Defaults to post. Optional.
970
+ * @return array An array of post meta HTML.
971
+ */
972
+ function get_postmeta_array($screen='post') {
973
+ $fields = array();
974
+ foreach ($this->modules as $module)
975
+ $fields = $module->postmeta_fields($fields, $screen);
976
+ return $fields;
977
+ }
978
+
979
  /**
980
  * If we have post meta fields to display, then register our meta box with WordPress.
981
  *
1041
  * @since 0.1
1042
  *
1043
  * @param int $post_id The ID of the post being saved.
1044
+ * @param object $post The post being saved.
1045
  */
1046
  function save_postmeta_box($post_id, $post) {
1047
 
1048
  //Sanitize
1049
  $post_id = (int)$post_id;
1050
 
 
 
 
1051
  //Run preliminary permissions checks
1052
+ if ( !wp_verify_nonce($_REQUEST['_su_wpnonce'], 'su-update-postmeta') ) return;
1053
  if ( 'page' == $_POST['post_type'] ) {
1054
  if ( !current_user_can( 'edit_page', $post_id )) return;
1055
  } elseif ( 'post' == $_POST['post_type'] ) {
1056
  if ( !current_user_can( 'edit_post', $post_id )) return;
1057
  } else return;
1058
 
1059
+ //Get an array of the postmeta fields
1060
+ $keys = array_keys($this->get_postmeta_array($_POST['post_type']));
1061
+ $fields = array();
 
 
 
1062
 
1063
+ foreach ($keys as $key) {
1064
+ $newfields = explode('|', $key);
1065
+ array_shift($newfields);
1066
+ $fields = array_merge($fields, $newfields);
 
 
 
 
 
 
 
 
 
1067
  }
1068
 
1069
+ //Update postmeta values
1070
+ foreach ($fields as $field) {
1071
+
1072
+ $metakey = "_su_$field";
1073
+
1074
+ //Delete the old value
1075
+ delete_post_meta($post_id, $metakey);
1076
+
1077
+ //Add the new value, if there is one
1078
+ $value = $_POST[$metakey];
1079
+ if (!empty($value)) {
1080
+ add_post_meta($post_id, $metakey, $value);
1081
  }
1082
  }
 
 
 
1083
  }
1084
 
1085
 
1093
  * @param bool $remove_all Whether to remove all cron jobs. Optional.
1094
  */
1095
  function remove_cron_jobs($remove_all = false) {
1096
+ $crondata = $this->dbdata['cron'];
1097
  if (is_array($crondata)) {
1098
  $newcrondata = $crondata;
1099
 
1104
  }
1105
  }
1106
 
1107
+ $this->dbdata['cron'] = $newcrondata;
1108
  }
1109
  }
1110
 
class.su-hitset.php CHANGED
@@ -1,5 +1,9 @@
1
  <?php
2
-
 
 
 
 
3
  class SU_HitSet {
4
 
5
  var $result;
@@ -23,6 +27,10 @@ class SU_HitSet {
23
  return (is_array($this->result) && count($this->result) > 0);
24
  }
25
 
 
 
 
 
26
  function admin_table($actions_callback = false, $highlight_new = true) {
27
 
28
  if (!$this->result || !$this->where) return;
@@ -35,7 +43,7 @@ class SU_HitSet {
35
  $allfields = array(
36
  'time' => __("Date", 'seo-ultimate')
37
  , 'ip_address' => __("IP Address", 'seo-ultimate')
38
- , 'user_agent' => __("Browser", 'seo-ultimate')
39
  , 'url' => __("URL Requested", 'seo-ultimate')
40
  , 'redirect_url' => __("Redirected To", 'seo-ultimate')
41
  , 'status_code' => __("Status Code", 'seo-ultimate')
@@ -73,9 +81,9 @@ class SU_HitSet {
73
  $cell = sprintf(__('%1$s<br />%2$s', 'seo-ultimate'), $date, $time);
74
  break;
75
  case 'user_agent':
76
- $binfo = get_browser($cell, true);
77
  $ua = attribute_escape($cell);
78
- $cell = '<abbr title="'.$ua.'">'.$binfo['parent'].'</abbr>';
79
  break;
80
  case 'url':
81
  if (is_array($actions_callback)) {
1
  <?php
2
+ /**
3
+ * A class that stores the results of a query to to the hits table.
4
+ *
5
+ * @version 1.1
6
+ */
7
  class SU_HitSet {
8
 
9
  var $result;
27
  return (is_array($this->result) && count($this->result) > 0);
28
  }
29
 
30
+ function hits_count() {
31
+ return count($this->result);
32
+ }
33
+
34
  function admin_table($actions_callback = false, $highlight_new = true) {
35
 
36
  if (!$this->result || !$this->where) return;
43
  $allfields = array(
44
  'time' => __("Date", 'seo-ultimate')
45
  , 'ip_address' => __("IP Address", 'seo-ultimate')
46
+ , 'user_agent' => __("User Agent", 'seo-ultimate')
47
  , 'url' => __("URL Requested", 'seo-ultimate')
48
  , 'redirect_url' => __("Redirected To", 'seo-ultimate')
49
  , 'status_code' => __("Status Code", 'seo-ultimate')
81
  $cell = sprintf(__('%1$s<br />%2$s', 'seo-ultimate'), $date, $time);
82
  break;
83
  case 'user_agent':
84
+ $text = su_str_truncate($cell, 50);
85
  $ua = attribute_escape($cell);
86
+ $cell = "<abbr title='$ua'>$text</abbr>";
87
  break;
88
  case 'url':
89
  if (is_array($actions_callback)) {
class.su-importmodule.php CHANGED
@@ -3,7 +3,7 @@
3
  * Import Module
4
  *
5
  * @abstract
6
- * @version 1.0
7
  * @since 0.6
8
  */
9
 
@@ -13,10 +13,6 @@ class SU_ImportModule extends SU_Module {
13
 
14
  var $import_status_image;
15
 
16
- function __construct() {
17
-
18
- }
19
-
20
  function get_menu_parent() { return 'su-import-modules'; }
21
 
22
  function admin_page() {
@@ -67,17 +63,6 @@ class SU_ImportModule extends SU_Module {
67
  if ($this->get_setting('delete_import')) delete_option($option);
68
  }
69
  }
70
-
71
- function update_setting($key, $value, $module=null) {
72
- if (!$module) $module = $this->get_module_key();
73
-
74
- if (!apply_filters("su_custom_update_setting-$module-$key", false, $value)) {
75
- $settings = maybe_unserialize(get_option('su_settings'));
76
- if (!$settings) $settings = array();
77
- $settings[$module][$key] = $value;
78
- update_option('su_settings', serialize($settings));
79
- }
80
- }
81
  }
82
 
83
  }
3
  * Import Module
4
  *
5
  * @abstract
6
+ * @version 1.0.1
7
  * @since 0.6
8
  */
9
 
13
 
14
  var $import_status_image;
15
 
 
 
 
 
16
  function get_menu_parent() { return 'su-import-modules'; }
17
 
18
  function admin_page() {
63
  if ($this->get_setting('delete_import')) delete_option($option);
64
  }
65
  }
 
 
 
 
 
 
 
 
 
 
 
66
  }
67
 
68
  }
class.su-module.php CHANGED
@@ -3,7 +3,7 @@
3
  * The pseudo-abstract class upon which all modules are based.
4
  *
5
  * @abstract
6
- * @version 1.4
7
  * @since 0.1
8
  */
9
  class SU_Module {
@@ -243,13 +243,22 @@ class SU_Module {
243
  * Returns the absolute URL of the module's admin page.
244
  *
245
  * @since 0.7
 
 
 
 
 
 
246
  */
247
- function get_admin_url() {
248
- if ($key = $this->get_parent_module()) {
249
- $anchor = '#'.SEO_Ultimate::key_to_hook($this->get_module_key());
250
- } else {
251
- $key = $this->get_module_key();
252
- $anchor = '';
 
 
 
253
  }
254
 
255
  return admin_url('admin.php?page='.SEO_Ultimate::key_to_hook($key).$anchor);
@@ -271,9 +280,11 @@ class SU_Module {
271
  */
272
  function get_setting($key, $default=null, $module=null) {
273
  if (!$module) $module = $this->get_module_key();
274
- $settings = maybe_unserialize(get_option('su_settings'));
275
- if (isset($settings[$module][$key]))
276
- $setting = $settings[$module][$key];
 
 
277
  else
278
  $setting = $default;
279
 
@@ -294,10 +305,8 @@ class SU_Module {
294
  if (!$module) $module = $this->get_module_key();
295
 
296
  if (!apply_filters("su_custom_update_setting-$module-$key", false, $value)) {
297
- $settings = maybe_unserialize(get_option('su_settings'));
298
- if (!$settings) $settings = array();
299
- $settings[$module][$key] = $value;
300
- update_option('su_settings', serialize($settings));
301
  }
302
  }
303
 
@@ -478,6 +487,24 @@ class SU_Module {
478
  <?php
479
  }
480
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  /**
482
  * Adds plugin/module information to the admin footer.
483
  *
@@ -511,8 +538,7 @@ class SU_Module {
511
  * @uses get_module_key()
512
  * @uses admin_subheader()
513
  * @uses is_action()
514
- * @uses queue_message()
515
- * @uses print_messages()
516
  * @uses get_parent_module()
517
  *
518
  * @param mixed $header The text of the subheader that should go right before the form. Optional.
@@ -737,14 +763,18 @@ class SU_Module {
737
  * Determines if a particular nonce-secured admin action is being executed.
738
  *
739
  * @since 0.1
740
- * @uses nonce_validates()
 
 
741
  *
742
  * @param string $action The name of the action to check.
743
  * @return bool Whether or not the action is being executed.
744
  */
745
  function is_action($action) {
746
  if (!($object = $_GET['object'])) $object = false;
747
- return (($_GET['action'] == $action || $_POST['action'] == $action) && $this->nonce_validates($action, $object));
 
 
748
  }
749
 
750
  /**
@@ -1006,10 +1036,8 @@ class SU_Module {
1006
  wp_schedule_event($start, $recurrance, $hook);
1007
 
1008
  //Make a record of it
1009
- $data = maybe_unserialize(get_option('su_cron'));
1010
- if (!is_array($data)) $data = array();
1011
- $data[$mk][$function] = array($hook, $start, $recurrance);
1012
- update_option('su_cron', serialize($data));
1013
 
1014
  //Run the event now
1015
  call_user_func(array($this, $function));
3
  * The pseudo-abstract class upon which all modules are based.
4
  *
5
  * @abstract
6
+ * @version 1.5
7
  * @since 0.1
8
  */
9
  class SU_Module {
243
  * Returns the absolute URL of the module's admin page.
244
  *
245
  * @since 0.7
246
+ * @uses get_parent_module()
247
+ * @uses get_module_key()
248
+ * @uses SEO_Ultimate::key_to_hook()
249
+ *
250
+ * @param string|false $key The key of the module for which to generate the admin URL.
251
+ * @return string The absolute URL to the admin page.
252
  */
253
+ function get_admin_url($key = false) {
254
+
255
+ if ($key === false) {
256
+ if ($key = $this->get_parent_module()) {
257
+ $anchor = '#'.SEO_Ultimate::key_to_hook($this->get_module_key());
258
+ } else {
259
+ $key = $this->get_module_key();
260
+ $anchor = '';
261
+ }
262
  }
263
 
264
  return admin_url('admin.php?page='.SEO_Ultimate::key_to_hook($key).$anchor);
280
  */
281
  function get_setting($key, $default=null, $module=null) {
282
  if (!$module) $module = $this->get_module_key();
283
+
284
+ global $seo_ultimate;
285
+
286
+ if (isset($seo_ultimate->dbdata['settings'][$module][$key]))
287
+ $setting = $seo_ultimate->dbdata['settings'][$module][$key];
288
  else
289
  $setting = $default;
290
 
305
  if (!$module) $module = $this->get_module_key();
306
 
307
  if (!apply_filters("su_custom_update_setting-$module-$key", false, $value)) {
308
+ global $seo_ultimate;
309
+ $seo_ultimate->dbdata['settings'][$module][$key] = $value;
 
 
310
  }
311
  }
312
 
487
  <?php
488
  }
489
 
490
+ /**
491
+ * Adds the hook necessary to initialize the admin page tabs.
492
+ *
493
+ * @since 0.8
494
+ */
495
+ function admin_page_tabs_init() {
496
+ add_action('wp_print_scripts', array($this, 'admin_page_tabs_js'));
497
+ }
498
+
499
+ /**
500
+ * Enqueues the JavaScript needed for the admin page tabs.
501
+ *
502
+ * @since 0.8
503
+ */
504
+ function admin_page_tabs_js() {
505
+ wp_enqueue_script('jquery-ui-tabs');
506
+ }
507
+
508
  /**
509
  * Adds plugin/module information to the admin footer.
510
  *
538
  * @uses get_module_key()
539
  * @uses admin_subheader()
540
  * @uses is_action()
541
+ * @uses print_message()
 
542
  * @uses get_parent_module()
543
  *
544
  * @param mixed $header The text of the subheader that should go right before the form. Optional.
763
  * Determines if a particular nonce-secured admin action is being executed.
764
  *
765
  * @since 0.1
766
+ * @uses SEO_Ultimate::key_to_hook()
767
+ * @uses get_module_key()
768
+ * @uses nonce_validates()
769
  *
770
  * @param string $action The name of the action to check.
771
  * @return bool Whether or not the action is being executed.
772
  */
773
  function is_action($action) {
774
  if (!($object = $_GET['object'])) $object = false;
775
+ return (strcasecmp($_GET['page'], SEO_Ultimate::key_to_hook($this->get_module_key())) == 0 //Is $this module being shown?
776
+ && ($_GET['action'] == $action || $_POST['action'] == $action) //Is this $action being executed?
777
+ && $this->nonce_validates($action, $object)); //Is the nonce valid?
778
  }
779
 
780
  /**
1036
  wp_schedule_event($start, $recurrance, $hook);
1037
 
1038
  //Make a record of it
1039
+ global $seo_ultimate;
1040
+ $seo_ultimate->dbdata['cron'][$mk][$function] = array($hook, $start, $recurrance);
 
 
1041
 
1042
  //Run the event now
1043
  call_user_func(array($this, $function));
functions.php CHANGED
@@ -60,6 +60,35 @@ function su_str_startswith( $str, $sub ) {
60
  return ( substr( $str, 0, strlen( $sub ) ) === $sub );
61
  }
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
  /********** CLASS FUNCTION ALIASES **********/
65
 
60
  return ( substr( $str, 0, strlen( $sub ) ) === $sub );
61
  }
62
 
63
+ /**
64
+ * Truncates a string if it is longer than a given length.
65
+ *
66
+ * @since 0.8
67
+ *
68
+ * @param string $str The string to possibly truncate.
69
+ * @param int $maxlen The desired maximum length of the string.
70
+ * @param str $truncate The string that should be added to the end of a truncated string.
71
+ */
72
+ function su_str_truncate( $str, $maxlen, $truncate = '...' ) {
73
+ if ( strlen($str) > $maxlen )
74
+ return substr( $str, 0, $maxlen - strlen($truncate) ) . $truncate;
75
+
76
+ return $str;
77
+ }
78
+
79
+ /**
80
+ * Escapes an attribute value and removes unwanted characters.
81
+ *
82
+ * @since 0.8
83
+ *
84
+ * @param string $str The attribute value.
85
+ * @return string The filtered attribute value.
86
+ */
87
+ function su_esc_attr($str) {
88
+ $str = str_replace(array("\t", "\r\n", "\n"), ' ', $str);
89
+ $str = attribute_escape($str);
90
+ return $str;
91
+ }
92
 
93
  /********** CLASS FUNCTION ALIASES **********/
94
 
images/index.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ header('Status: 403 Forbidden');
3
+ header('HTTP/1.1 403 Forbidden');
4
+ ?>
index.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ header('Status: 403 Forbidden');
3
+ header('HTTP/1.1 403 Forbidden');
4
+ ?>
modules/404s.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * 404 Monitor Module
4
  *
5
- * @version 1.0.1
6
  * @since 0.4
7
  */
8
 
@@ -12,17 +12,12 @@ class SU_404s extends SU_Module {
12
 
13
  var $hitset;
14
 
15
- function init() {
16
- $this->hitset = new SU_HitSet($this->get_module_key(), "status_code=404 AND redirect_url=''");
17
  }
18
 
19
  function get_menu_title() { return __('404 Monitor', 'seo-ultimate'); }
20
-
21
- function get_menu_count() {
22
- global $wpdb;
23
- $table = SEO_Ultimate::get_table_name('hits');
24
- return $wpdb->query("SELECT id FROM $table WHERE status_code=404 AND is_new=1");
25
- }
26
 
27
  function admin_page_contents() {
28
 
@@ -48,7 +43,7 @@ class SU_404s extends SU_Module {
48
 
49
  if (!$this->hitset->have_hits())
50
  $this->queue_message('success', __("No 404 errors in the log.", 'seo-ultimate'));
51
-
52
  $this->print_messages();
53
 
54
  if ($this->hitset->have_hits()) {
@@ -91,6 +86,8 @@ STR;
91
  return __(<<<STR
92
  <p>The 404 Monitor keeps track of non-existant URLs that generated 404 errors. 404 errors are when a search engine or visitor comes to a URL on your site but nothing exists at that URL.
93
  The 404 Monitor helps you spot 404 errors; then you can take steps to correct them (e.g. finding the broken links responsible or creating redirects).</p>
 
 
94
  <p>Hover over a table row to access these options:</p>
95
  <ul>
96
  <li>The &#8220;View&#8221; link will open the URL in a new window. This is useful for testing whether or not a redirect is working.</li>
@@ -107,9 +104,6 @@ The 404 Monitor helps you spot 404 errors; then you can take steps to correct th
107
  STR
108
  , 'seo-ultimate');
109
 
110
- /*<p>A numeric bubble will appear next to the &#8220;404 Monitor&#8221; item on the menu if there are any newly-logged URLs that you haven&#8217;t seen yet.
111
- These new URLs will also be highlighted green in the table.</p>*/
112
-
113
  } else {
114
 
115
  return __(<<<STR
2
  /**
3
  * 404 Monitor Module
4
  *
5
+ * @version 1.0.2
6
  * @since 0.4
7
  */
8
 
12
 
13
  var $hitset;
14
 
15
+ function __construct() {
16
+ $this->hitset = new SU_HitSet('404s', "status_code=404 AND redirect_url='' AND url NOT LIKE '%/favicon.ico'");
17
  }
18
 
19
  function get_menu_title() { return __('404 Monitor', 'seo-ultimate'); }
20
+ function get_menu_count() { return $this->hitset->hits_count(); }
 
 
 
 
 
21
 
22
  function admin_page_contents() {
23
 
43
 
44
  if (!$this->hitset->have_hits())
45
  $this->queue_message('success', __("No 404 errors in the log.", 'seo-ultimate'));
46
+
47
  $this->print_messages();
48
 
49
  if ($this->hitset->have_hits()) {
86
  return __(<<<STR
87
  <p>The 404 Monitor keeps track of non-existant URLs that generated 404 errors. 404 errors are when a search engine or visitor comes to a URL on your site but nothing exists at that URL.
88
  The 404 Monitor helps you spot 404 errors; then you can take steps to correct them (e.g. finding the broken links responsible or creating redirects).</p>
89
+ <p>A numeric bubble will appear next to the &#8220;404 Monitor&#8221; item on the menu if there are any newly-logged URLs that you haven&#8217;t seen yet.
90
+ These new URLs will also be highlighted green in the table.</p>
91
  <p>Hover over a table row to access these options:</p>
92
  <ul>
93
  <li>The &#8220;View&#8221; link will open the URL in a new window. This is useful for testing whether or not a redirect is working.</li>
104
  STR
105
  , 'seo-ultimate');
106
 
 
 
 
107
  } else {
108
 
109
  return __(<<<STR
modules/files.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File Editor Module
4
+ *
5
+ * @version 1.0
6
+ * @since 2.0
7
+ */
8
+
9
+ if (class_exists('SU_Module')) {
10
+
11
+ class SU_Files extends SU_Module {
12
+
13
+ var $htaccess_recovery = null;
14
+
15
+ function get_menu_title() { return __('File Editor', 'seo-ultimate'); }
16
+
17
+ function init() {
18
+
19
+ if ($this->get_setting('enable_custom_robotstxt')) {
20
+ remove_action('do_robots', 'do_robots');
21
+ add_action('do_robots', array($this, 'do_robots'));
22
+ }
23
+
24
+ add_action('admin_notices', array($this, 'privacy_options_notice'));
25
+
26
+ add_filter('su_get_setting-files-htaccess', array($this, 'get_htaccess'));
27
+ add_filter('su_custom_update_setting-files-htaccess', array($this, 'update_htaccess'), 10, 2);
28
+ }
29
+
30
+ function admin_page_contents() {
31
+
32
+ global $is_apache;
33
+
34
+ if ($is_apache) {
35
+
36
+ $htaccess = get_home_path().'.htaccess';
37
+ $exists = file_exists($htaccess);
38
+ $writable = is_writable($htaccess);
39
+
40
+ if ($exists && !$writable) $this->queue_message('warning',
41
+ __('A .htaccess file exists, but it&#8217;s not writable. You can edit it here once the file permissions are corrected.', 'seo-ultimate'));
42
+ }
43
+
44
+ if (!strlen(get_option('permalink_structure'))) $this->queue_message('error',
45
+ __('WordPress won&#8217;t be able to display your robots.txt file because the default <a href="options-permalink.php" target="_blank">permalink structure</a> is in use.', 'seo-ultimate'));
46
+
47
+ $this->print_messages();
48
+
49
+ $this->admin_form_start();
50
+
51
+ $this->textarea('robotstxt', sprintf(__('robots.txt [<a href="%s" target="_blank">Open</a>]', 'seo-ultimate'), trailingslashit(get_bloginfo('url')).'robots.txt'));
52
+ $this->checkboxes(array(
53
+ 'enable_custom_robotstxt' => __('Enable this custom robots.txt file and disable the default file', 'seo-ultimate')
54
+ , 'enable_do_robotstxt_action' => __('Let other plugins add rules to my custom robots.txt file', 'seo-ultimate')
55
+ ), __('robots.txt Settings', 'seo-ultimate'));
56
+
57
+ $this->queue_message('warning',
58
+ __('Please realize that incorrectly editing your robots.txt file could block search engines from your site.', 'seo-ultimate'));
59
+
60
+ if ($is_apache && ($writable || !$exists)) {
61
+ $this->textarea('htaccess', __('.htaccess', 'seo-ultimate'));
62
+
63
+ $this->queue_message('warning',
64
+ __('Also, incorrectly editing your .htaccess file could disable your entire website. Edit with caution!', 'seo-ultimate'));
65
+ }
66
+
67
+ $this->admin_form_end();
68
+ $this->print_messages();
69
+ }
70
+
71
+ function do_robots() {
72
+ header( 'Content-Type: text/plain; charset=utf-8' );
73
+
74
+ if ($this->get_setting('enable_do_robotstxt_action'))
75
+ do_action('do_robotstxt');
76
+
77
+ echo $this->get_setting('robotstxt');
78
+ }
79
+
80
+ function get_htaccess() {
81
+ if ($this->htaccess_recovery) return $this->htaccess_recovery;
82
+
83
+ $htaccess = get_home_path().'.htaccess';
84
+ if (is_readable($htaccess))
85
+ return file_get_contents($htaccess);
86
+
87
+ return false;
88
+ }
89
+
90
+ function update_htaccess($unused, $value) {
91
+
92
+ $this->htaccess_recovery = $value;
93
+
94
+ $htaccess = get_home_path().'.htaccess';
95
+ $fp = fopen($htaccess, 'w');
96
+ fwrite($fp, $value);
97
+ fclose($fp);
98
+
99
+ return true;
100
+ }
101
+
102
+ function privacy_options_notice() {
103
+ global $pagenow;
104
+ if ($this->get_setting('enable_custom_robotstxt') && $pagenow == 'options-privacy.php') {
105
+ echo '<div class="su-module">';
106
+ $this->print_message('info', sprintf(
107
+ __('Please note that your privacy settings won&#8217;t have any effect on your robots.txt file, since you&#8217;re using <a href="%s">a custom one</a>.', 'seo-ultimate'),
108
+ admin_url('admin.php?page='.SEO_Ultimate::key_to_hook($this->get_module_key()))
109
+ ));
110
+ echo '</div>';
111
+ }
112
+ }
113
+
114
+ function admin_help() {
115
+ return __(<<<STR
116
+ <p>The File Editor module lets you edit system files that are of SEO value. Edit the files as desired, then click Save Changes. If you create a custom robots.txt file, be sure to enable it with the checkbox.</p>
117
+ STR
118
+ , 'seo-ultimate');
119
+ }
120
+ }
121
+
122
+ }
123
+ ?>
modules/index.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ header('Status: 403 Forbidden');
3
+ header('HTTP/1.1 403 Forbidden');
4
+ ?>
modules/meta.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Meta Editor Module
4
  *
5
- * @version 1.0.1
6
  * @since 0.3
7
  */
8
 
@@ -51,7 +51,7 @@ class SU_Meta extends SU_Module {
51
  $id = "_su_description";
52
  $value = attribute_escape($this->get_postmeta('description'));
53
 
54
- $fields['20-meta'] =
55
  "<tr class='textarea'>\n<th scope='row'><label for='$id'>".__("Description:", 'seo-ultimate')."</label></th>\n"
56
  . "<td><textarea name='$id' id='$id' type='text' class='regular-text' cols='60' rows='3'"
57
  . " onkeyup=\"javascript:textbox_char_count('_su_description', 'su_meta_description_charcount')\">$value</textarea>"
@@ -89,12 +89,12 @@ class SU_Meta extends SU_Module {
89
  }
90
 
91
  if ($desc) {
92
- $desc = attribute_escape($desc);
93
  echo "\t<meta name=\"description\" content=\"$desc\" />\n";
94
  }
95
 
96
  if ($kw) {
97
- $kw = attribute_escape($kw);
98
  echo "\t<meta name=\"keywords\" content=\"$kw\" />\n";
99
  }
100
 
@@ -106,7 +106,7 @@ class SU_Meta extends SU_Module {
106
 
107
  foreach ($verify as $site => $name) {
108
  if ($value = $this->get_setting($site.'_verify')) {
109
- $value = attribute_escape($value);
110
  echo "\t<meta name=\"$name\" content=\"$value\" />\n";
111
  }
112
  }
2
  /**
3
  * Meta Editor Module
4
  *
5
+ * @version 1.0.2
6
  * @since 0.3
7
  */
8
 
51
  $id = "_su_description";
52
  $value = attribute_escape($this->get_postmeta('description'));
53
 
54
+ $fields['20|description|keywords'] =
55
  "<tr class='textarea'>\n<th scope='row'><label for='$id'>".__("Description:", 'seo-ultimate')."</label></th>\n"
56
  . "<td><textarea name='$id' id='$id' type='text' class='regular-text' cols='60' rows='3'"
57
  . " onkeyup=\"javascript:textbox_char_count('_su_description', 'su_meta_description_charcount')\">$value</textarea>"
89
  }
90
 
91
  if ($desc) {
92
+ $desc = su_esc_attr($desc);
93
  echo "\t<meta name=\"description\" content=\"$desc\" />\n";
94
  }
95
 
96
  if ($kw) {
97
+ $kw = su_esc_attr($kw);
98
  echo "\t<meta name=\"keywords\" content=\"$kw\" />\n";
99
  }
100
 
106
 
107
  foreach ($verify as $site => $name) {
108
  if ($value = $this->get_setting($site.'_verify')) {
109
+ $value = su_esc_attr($value);
110
  echo "\t<meta name=\"$name\" content=\"$value\" />\n";
111
  }
112
  }
modules/modules.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Module Manager Module
4
  *
5
- * @version 1.0
6
  * @since 0.7
7
  */
8
 
@@ -10,27 +10,22 @@ if (class_exists('SU_Module')) {
10
 
11
  class SU_Modules extends SU_Module {
12
 
13
- function get_menu_title() { return __('Module Manager', 'seo-ultimate'); }
 
14
  function get_menu_pos() { return 10; }
15
 
16
  function init() {
17
  global $seo_ultimate;
18
 
19
- if ($_GET['page'] == SEO_Ultimate::key_to_hook($this->get_module_key()) && $this->is_action('update')) {
20
-
21
- $module_statuses = maybe_unserialize(get_option('su_modules', false));
22
 
23
  foreach ($_POST as $key => $value) {
24
  if (substr($key, 0, 3) == 'su-') {
25
  $key = str_replace(array('su-', '-module-status'), '', $key);
26
- $module_statuses[$key] = intval($value);
27
  }
28
  }
29
-
30
- $seo_ultimate->module_status = $module_statuses;
31
- update_option('su_modules', serialize($module_statuses));
32
  }
33
-
34
  }
35
 
36
  function admin_page_contents() {
@@ -65,16 +60,18 @@ STR;
65
 
66
  $modules = array();
67
 
68
- foreach ($seo_ultimate->modules as $key => $module)
69
- if (get_parent_class($module) == 'SU_Module' && !in_array($key, array('stats', 'modules')))
 
70
  $modules[$key] = $module->get_page_title();
 
71
 
72
  $modules = array_merge($modules, $seo_ultimate->disabled_modules);
73
  asort($modules);
74
 
75
  foreach ($modules as $key => $name) {
76
 
77
- $currentstatus = $seo_ultimate->module_status[$key];
78
 
79
  echo "\t\t<tr>\n\t\t\t<td class='module-status' id='$key-module-status'>\n";
80
  echo "\t\t\t\t<input type='hidden' name='su-$key-module-status' id='su-$key-module-status' value='$currentstatus' />\n";
@@ -86,8 +83,8 @@ STR;
86
  echo "<a href='javascript:void(0)' onclick=\"javascript:set_module_status('$key', $statuscode, this)\" class='$current'>$statuslabel</a></span>\n";
87
  }
88
 
89
- if ($seo_ultimate->module_status[$key] > SU_MODULE_DISABLED) {
90
- $cellcontent = "<a href='".$seo_ultimate->modules[$key]->get_admin_url()."'>$name</a>";
91
  } else
92
  $cellcontent = $name;
93
 
@@ -105,6 +102,19 @@ STR;
105
 
106
  $this->admin_form_end(false, false);
107
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  }
109
 
110
  } elseif ($_GET['css'] == 'admin') {
2
  /**
3
  * Module Manager Module
4
  *
5
+ * @version 1.1
6
  * @since 0.7
7
  */
8
 
10
 
11
  class SU_Modules extends SU_Module {
12
 
13
+ function get_menu_title() { return __('Modules', 'seo-ultimate'); }
14
+ function get_page_title() { return __('Module Manager', 'seo-ultimate'); }
15
  function get_menu_pos() { return 10; }
16
 
17
  function init() {
18
  global $seo_ultimate;
19
 
20
+ if ($this->is_action('update')) {
 
 
21
 
22
  foreach ($_POST as $key => $value) {
23
  if (substr($key, 0, 3) == 'su-') {
24
  $key = str_replace(array('su-', '-module-status'), '', $key);
25
+ $seo_ultimate->dbdata['modules'][$key] = intval($value);
26
  }
27
  }
 
 
 
28
  }
 
29
  }
30
 
31
  function admin_page_contents() {
60
 
61
  $modules = array();
62
 
63
+ foreach ($seo_ultimate->modules as $key => $module) {
64
+ //On some setups, get_parent_class() returns the class name in lowercase
65
+ if (strcasecmp(get_parent_class($module), 'SU_Module') == 0 && !in_array($key, array('stats', 'modules')))
66
  $modules[$key] = $module->get_page_title();
67
+ }
68
 
69
  $modules = array_merge($modules, $seo_ultimate->disabled_modules);
70
  asort($modules);
71
 
72
  foreach ($modules as $key => $name) {
73
 
74
+ $currentstatus = $seo_ultimate->dbdata['modules'][$key];
75
 
76
  echo "\t\t<tr>\n\t\t\t<td class='module-status' id='$key-module-status'>\n";
77
  echo "\t\t\t\t<input type='hidden' name='su-$key-module-status' id='su-$key-module-status' value='$currentstatus' />\n";
83
  echo "<a href='javascript:void(0)' onclick=\"javascript:set_module_status('$key', $statuscode, this)\" class='$current'>$statuslabel</a></span>\n";
84
  }
85
 
86
+ if ($currentstatus > SU_MODULE_DISABLED) {
87
+ $cellcontent = "<a href='".$this->get_admin_url($key)."'>$name</a>";
88
  } else
89
  $cellcontent = $name;
90
 
102
 
103
  $this->admin_form_end(false, false);
104
  }
105
+
106
+ function admin_help() {
107
+ return __(<<<STR
108
+ <p>The Module Manager lets you customize the visibility and accessibility of each module; here are the options available:</p>
109
+ <ul>
110
+ <li><strong>Enabled</strong> &mdash; The default option. The module will be fully enabled and accessible.</li>
111
+ <li><strong>Silenced</strong> &mdash; The module will be enabled and accessible, but it won&#8217;t be allowed to display numeric bubble alerts on the menu.</li>
112
+ <li><strong>Hidden</strong> &mdash; The module&#8217;s functionality will be enabled, but the module won&#8217;t be visible on the SEO menu. You will still be able to access the module&#8217;s admin page by clicking on its title in the Module Manager table.</li>
113
+ <li><strong>Disabled</strong> &mdash; The module will be completely disabled and inaccessible.</li>
114
+ </ul>
115
+ STR
116
+ , 'seo-ultimate');
117
+ }
118
  }
119
 
120
  } elseif ($_GET['css'] == 'admin') {
modules/settings.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Settings Module
4
  *
5
- * @version 2.1
6
  * @since 0.2
7
  */
8
 
@@ -29,6 +29,7 @@ class SU_Settings extends SU_Module {
29
  }
30
 
31
  function init() {
 
32
 
33
  if ($this->is_action('export')) {
34
  header('Content-Type: application/octet-stream');
@@ -37,7 +38,7 @@ class SU_Settings extends SU_Module {
37
  $options = $this->portable_options();
38
  $export = array();
39
  foreach ($options as $option) {
40
- $data = maybe_unserialize(get_option("su_$option"));
41
  $data = apply_filters("su_{$option}_export_array", $data);
42
  $export[$option] = $data;
43
  }
@@ -58,7 +59,7 @@ class SU_Settings extends SU_Module {
58
 
59
  $options = $this->portable_options();
60
  foreach ($options as $option) {
61
- update_option("su_$option", $import[$option]);
62
  }
63
 
64
  $this->queue_message('success', __("Settings successfully imported.", 'seo-ultimate'));
@@ -72,8 +73,8 @@ class SU_Settings extends SU_Module {
72
 
73
  } elseif ($this->is_action('reset')) {
74
 
75
- update_option('su_settings', serialize(array()));
76
- delete_option('su_modules');
77
  $this->load_default_settings();
78
 
79
  $this->queue_message('success', __("All settings have been erased and defaults have been restored.", 'seo-ultimate'));
@@ -129,7 +130,7 @@ class SU_Settings extends SU_Module {
129
  $hook = SEO_Ultimate::key_to_hook($this->get_module_key());
130
  echo "<form enctype='multipart/form-data' method='post' action='?page=$hook&amp;action=import'>\n";
131
  echo "\t<input name='settingsfile' type='file' /> ";
132
- $confirm = __("Are you sure you want to import this settings file? This will erase all current settings and cannot be undone.", 'seo-ultimate');
133
  echo "<input type='submit' class='button-secondary' value='".__("Import This Settings File", 'seo-ultimate')."' onclick=\"javascript:return confirm('$confirm')\" />\n";
134
  wp_nonce_field($this->get_nonce_handle('import'));
135
  echo "</form>\n";
2
  /**
3
  * Settings Module
4
  *
5
+ * @version 2.2
6
  * @since 0.2
7
  */
8
 
29
  }
30
 
31
  function init() {
32
+ global $seo_ultimate;
33
 
34
  if ($this->is_action('export')) {
35
  header('Content-Type: application/octet-stream');
38
  $options = $this->portable_options();
39
  $export = array();
40
  foreach ($options as $option) {
41
+ $data = $seo_ultimate->dbdata[$option];
42
  $data = apply_filters("su_{$option}_export_array", $data);
43
  $export[$option] = $data;
44
  }
59
 
60
  $options = $this->portable_options();
61
  foreach ($options as $option) {
62
+ $seo_ultimate->dbdata[$option] = array_merge($seo_ultimate->dbdata[$option], $import[$option]);
63
  }
64
 
65
  $this->queue_message('success', __("Settings successfully imported.", 'seo-ultimate'));
73
 
74
  } elseif ($this->is_action('reset')) {
75
 
76
+ $seo_ultimate->dbdata['settings'] = array();
77
+ unset($seo_ultimate->dbdata['modules']);
78
  $this->load_default_settings();
79
 
80
  $this->queue_message('success', __("All settings have been erased and defaults have been restored.", 'seo-ultimate'));
130
  $hook = SEO_Ultimate::key_to_hook($this->get_module_key());
131
  echo "<form enctype='multipart/form-data' method='post' action='?page=$hook&amp;action=import'>\n";
132
  echo "\t<input name='settingsfile' type='file' /> ";
133
+ $confirm = __("Are you sure you want to import this settings file? This will overwrite your current settings and cannot be undone.", 'seo-ultimate');
134
  echo "<input type='submit' class='button-secondary' value='".__("Import This Settings File", 'seo-ultimate')."' onclick=\"javascript:return confirm('$confirm')\" />\n";
135
  wp_nonce_field($this->get_nonce_handle('import'));
136
  echo "</form>\n";
modules/titles.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Title Rewriter Module
4
  *
5
- * @version 1.0.3
6
  * @since 0.1
7
  */
8
 
@@ -61,7 +61,7 @@ class SU_Titles extends SU_Module {
61
  }
62
 
63
  function postmeta_fields($fields) {
64
- $fields['10-title'] = $this->get_postmeta_textbox('title', __('Title Tag:', 'seo-ultimate'));
65
  return $fields;
66
  }
67
 
2
  /**
3
  * Title Rewriter Module
4
  *
5
+ * @version 1.0.4
6
  * @since 0.1
7
  */
8
 
61
  }
62
 
63
  function postmeta_fields($fields) {
64
+ $fields['10|title'] = $this->get_postmeta_textbox('title', __('Title Tag:', 'seo-ultimate'));
65
  return $fields;
66
  }
67
 
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === SEO Ultimate ===
2
  Contributors: SEO Design Solutions
3
- Tags: seo, title, meta, noindex, canonical, 404, google, yahoo, bing, search engines, admin, post, page, modules
4
  Requires at least: 2.7
5
- Tested up to: 2.8
6
- Stable tag: 0.7
7
 
8
  This all-in-one SEO plugin can handle titles, noindex, meta data, canonical tags, 404 error tracking, and more (with many more features coming soon).
9
 
@@ -23,6 +23,8 @@ SEO Ultimate is an all-in-one [SEO](http://www.seodesignsolutions.com/) plugin w
23
 
24
  * **Linkbox Inserter** - Encourages linkbuilding activity by inserting textboxes containing link HTML.
25
 
 
 
26
  SEO Ultimate was developed with WordPress plugin "best practices" in mind:
27
 
28
  * Integration with the contextual help system of WordPress 2.7+
@@ -32,9 +34,7 @@ SEO Ultimate was developed with WordPress plugin "best practices" in mind:
32
  * Integration with the new WordPress 2.7+ menu
33
  * Settings import/export/reset functionality
34
 
35
- **NOTE:** This plugin is in beta, which means it's very feature-incomplete. We have many more features that we're working on finetuning before release, including PageRank sculpting, robots.txt editing, 301 logging, and much more.
36
-
37
- If you install the plugin now, you can have these new features delivered to you on a regular basis via WordPress's automatic plugin upgrader.
38
 
39
 
40
  == Installation ==
@@ -64,27 +64,123 @@ To install the plugin manually:
64
 
65
  SEO Ultimate puts all its admin pages under a new "SEO" top-level menu. The only exception is the plugin settings page, which goes under `Settings > SEO Ultimate`.
66
 
67
- = Some of the features aren't working! =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
- Here are some troubleshooting ideas:
70
 
71
- 1. Try disabling other SEO plugins (they may be conflicting with SEO Ultimate).
72
- 2. Check to make sure your theme is [plugin-friendly](http://wordpress.jdwebdev.com/blog/theme-plugin-hooks/).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
  = How do I remove the attribution link? =
75
 
76
  Because of the tremendous effort put into this plugin, we ask that you please leave the link enabled. If you must disable it, you can do so under `Settings > SEO Ultimate`.
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  == Screenshots ==
80
 
81
  1. The Title Rewriter module
82
  2. The Noindex Manager module
83
  3. The Meta Editor module
84
-
 
 
85
 
86
  == Changelog ==
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  = Version 0.7 (July 16, 2009) =
89
  * Feature: Added the Module Manager
90
  * Feature: Modules can optionally display numeric notices in the menu
1
  === SEO Ultimate ===
2
  Contributors: SEO Design Solutions
3
+ Tags: seo, title, meta, noindex, canonical, 404, robots.txt, htaccess, google, yahoo, bing, search engines, admin, post, page, modules
4
  Requires at least: 2.7
5
+ Tested up to: 2.8.2
6
+ Stable tag: 0.8
7
 
8
  This all-in-one SEO plugin can handle titles, noindex, meta data, canonical tags, 404 error tracking, and more (with many more features coming soon).
9
 
23
 
24
  * **Linkbox Inserter** - Encourages linkbuilding activity by inserting textboxes containing link HTML.
25
 
26
+ * **File Editor** - Lets you edit two important SEO-related files: robots.txt and .htaccess
27
+
28
  SEO Ultimate was developed with WordPress plugin "best practices" in mind:
29
 
30
  * Integration with the contextual help system of WordPress 2.7+
34
  * Integration with the new WordPress 2.7+ menu
35
  * Settings import/export/reset functionality
36
 
37
+ **NOTE:** This plugin is in beta, which means it's very feature-incomplete. We have many more features that we're working on finetuning before release. If you install the plugin now, you can have these new features delivered to you on a regular basis via WordPress's automatic plugin upgrader.
 
 
38
 
39
 
40
  == Installation ==
64
 
65
  SEO Ultimate puts all its admin pages under a new "SEO" top-level menu. The only exception is the plugin settings page, which goes under `Settings > SEO Ultimate`.
66
 
67
+ = Where's the documentation? =
68
+
69
+ SEO Ultimate's documentation is built into the plugin itself. Whenever you're viewing an SEO Ultimate page in your WordPress admin, you can click the "Help" tab in the upper-right-hand corner to view documentation for the area you're viewing.
70
+
71
+ = What are modules? =
72
+
73
+ SEO Ultimate's features are divided into groups called "modules." SEO Ultimate's "Module Manager" lets you enable or disable each of these groups of features. This way, you can pick-and-choose which SEO Ultimate features you want.
74
+
75
+ = Can I access a module again after I've hidden it? =
76
+
77
+ Yes. Just go to the Module Manager and click the module's title to open its admin page. If you'd like to put the module back in the "SEO" menu, just re-enable the module in the Module Manager and click "Save Changes."
78
+
79
+ = How do I disable the number bubbles on the "SEO" menu? =
80
+
81
+ Just go to the Module Manager and select the "Silenced" option for any modules generating number bubbles. Then click "Save Changes."
82
+
83
+ = Why doesn't the settings exporter include all my data in an export? =
84
+
85
+ The settings export/import system is designed to facilitate moving settings between sites. It is NOT a replacement for keeping your database backed up. The settings exporter doesn't include data that is specific to your site. For example, logged 404 errors are not included because those 404 errors only apply to your site, not another site. Also, post/page titles/meta are not included because the site into which you import the file could have totally different posts/pages located under the same ID numbers.
86
+
87
+ If you're moving a site to a different server or restoring a crashed site, you should do so with database backup/restore.
88
+
89
+ = Why do I get a "500 Server Error" after using the File Editor? =
90
+
91
+ You may have inserted code into your .htaccess file that your web server can't understand. As the File Editor warns, incorrectly editing your .htaccess file can disable your entire website in this way. To restore your site, you'll need to use an FTP client (or your web host's File Manager) to edit or rename your .htaccess file. If you need help, please contact your web host.
92
+
93
+ = Will my robots.txt edits remain if I disable the File Editor? =
94
+
95
+ No. On a WordPress blog, the robots.txt file is dynamically generated just like your posts and Pages. If you disable the File Editor module or the entire SEO Ultimate plugin, the File Editor won't be able to insert your custom code into the robots.txt file anymore.
96
+
97
+ = Will my .htaccess edits remain if I disable the File Editor? =
98
+
99
+ Yes. The .htaccess file is static. Your edits will remain even if you disable SEO Ultimate or its File Editor module.
100
+
101
+ = Where did my .htaccess edits go? =
102
+
103
+ The .htaccess file is static, so SEO Ultimate doesn't have total control over it. It's possible that WordPress, another plugin, or other software may overwrite your .htaccess file. If you have a backup of your blog's files, you can try recovering your edits from there.
104
 
105
+ = What do I do if my site has multiple meta tags? =
106
 
107
+ First, try removing your theme's built-in meta tags if it has them. Go to `Appearance > Editor` and edit `header.php`. Delete or comment-out any `<meta>` tags.
108
+
109
+ If the problem persists, try disabling other SEO plugins that may be generating meta tags.
110
+
111
+ Troubleshooting tip: Go to `Settings > SEO Ultimate` and enable the "Insert comments around HTML code insertions" option. This will mark SEO Ultimate's meta tags with comments, allowing you to see which meta tags are generated by SEO Ultimate and which aren't.
112
+
113
+ = How do I edit the meta tags of my homepage? =
114
+
115
+ If you are using a "blog homepage" (the default option of showing your blog posts on your homepage), go to `SEO > Meta Editor` and use the Blog Homepage fields.
116
+
117
+ If you have configured your `Settings > Reading` section to use a "frontpage" (i.e. a Page as your homepage), just edit that Page under `Pages > Edit` and use the "Description" and "Keywords" fields in the "SEO Settings" box.
118
+
119
+ = Does the Title Rewriter edit my post/page titles? =
120
+
121
+ No. The Title Rewriter edits the `<title>` tags of your site, not your post/page titles.
122
+
123
+ = What's the difference between the "title" and the "title tag" of a post/page? =
124
+
125
+ The "title" is the title of your post or page, and is displayed on your site and in your RSS feed. The title is also used in your `<title>` tag by default; however, you can override the value of just the `<title>` tag by using the "Title Tag" field in the "SEO Settings" box.
126
 
127
  = How do I remove the attribution link? =
128
 
129
  Because of the tremendous effort put into this plugin, we ask that you please leave the link enabled. If you must disable it, you can do so under `Settings > SEO Ultimate`.
130
 
131
+ = Why isn't the Title Rewriter or the Meta Editor working? =
132
+
133
+ Try disabling other SEO plugins, as they may be conflicting with SEO Ultimate. Also, check to make sure your theme is [plugin-friendly](http://wordpress.jdwebdev.com/blog/theme-plugin-hooks/).
134
+
135
+ = How do I disable the "SEO Settings" box in the post/page editors? =
136
+
137
+ Open the editor, click the "Screen Options" tab in the upper-right-hand corner, and uncheck the "SEO Settings" checkbox.
138
+
139
+ = Why did some of the textboxes disappear from the "SEO Settings" box? =
140
+
141
+ The "SEO Settings" fields are added by your modules. The "Title Tag" field is added by the Title Rewriter module, the "Description" and "Keywords" fields are added by the Meta Editor module, etc. If you disable a module using the Module Manager, its fields in the "SEO Settings" box will be disabled too. You can re-enable the field in question by re-enabling the corresponding module.
142
+
143
+ = How do I uninstall SEO Ultimate? =
144
+
145
+ 1. Go to the `Plugins` admin page.
146
+ 2. Deactivate the plugin if it's activated.
147
+ 3. Click the plugin's "Delete" link.
148
+ 4. Click the "Yes, Delete these files" button. SEO Ultimate's files and database entries will be deleted.
149
+
150
+ = Will all my settings be deleted if I delete SEO Ultimate in the Plugins manager? =
151
+
152
+ Yes. WordPress plugins are supposed to delete their settings during the uninstallation process.
153
 
154
  == Screenshots ==
155
 
156
  1. The Title Rewriter module
157
  2. The Noindex Manager module
158
  3. The Meta Editor module
159
+ 4. The "SEO Settings" post/page meta box
160
+ 5. The Linkbox Inserter module
161
+ 6. The File Editor module
162
 
163
  == Changelog ==
164
 
165
+ = Version 0.8 (July 22, 2009) =
166
+ * Feature: Added robots.txt editor (new File Editor module)
167
+ * Feature: Added .htaccess editor (new File Editor module)
168
+ * Bugfix: 404 Monitor no longer uses the unreliable get_browser() function
169
+ * Bugfix: 404 Monitor now ignores favicon requests
170
+ * Bugfix: Fixed conflict with the WP Table Reloaded plugin
171
+ * Bugfix: Fixed bug that caused Module Manager to appear blank on certain configurations
172
+ * Bugfix: Fixed bug that caused multiple drafts to be saved per post
173
+ * Bugfix: Post meta box no longer leaves behind empty postmeta database rows
174
+ * Bugfix: Added missing Module Manager help
175
+ * Bugfix: Fixed settings double-serialization bug
176
+ * Bugfix: Fixed error that appeared when re-enabling disabled modules
177
+ * Bugfix: Newlines and tabs now removed from HTML attributes
178
+ * Improvement: SEO Ultimate now stores its wp_options data in 1 entry instead of 4
179
+ * Improvement: The settings read/write process has been streamlined
180
+ * Improvement: Drastically expanded the readme.txt FAQ section
181
+ * Improvement: Plugin's directories now return 403 codes
182
+ * Improvement: Settings importer now retains the settings of modules added after the export
183
+
184
  = Version 0.7 (July 16, 2009) =
185
  * Feature: Added the Module Manager
186
  * Feature: Modules can optionally display numeric notices in the menu
screenshot-4.png ADDED
Binary file
screenshot-5.png ADDED
Binary file
screenshot-6.png ADDED
Binary file
seo-ultimate.css CHANGED
@@ -72,6 +72,10 @@ div.su-module .su-message .su-info {
72
 
73
  /* ADMIN PAGES */
74
 
 
 
 
 
75
  div.su-module h3.su-subheader {
76
  margin-top: 3em;
77
  padding-top: 1em;
72
 
73
  /* ADMIN PAGES */
74
 
75
+ div.su-module {
76
+ padding-bottom: 1em;
77
+ }
78
+
79
  div.su-module h3.su-subheader {
80
  margin-top: 3em;
81
  padding-top: 1em;
seo-ultimate.php CHANGED
@@ -2,8 +2,8 @@
2
  /*
3
  Plugin Name: SEO Ultimate
4
  Plugin URI: http://www.seodesignsolutions.com/wordpress-seo/
5
- Description: This all-in-one SEO plugin can rewrite title tags, edit meta data, add noindex, insert canonical tags, and log 404 errors (with many more features coming soon).
6
- Version: 0.7
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 0.7
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
 
39
  define("SU_PLUGIN_NAME", "SEO Ultimate");
40
  define("SU_PLUGIN_URI", "http://www.seodesignsolutions.com/wordpress-seo/");
41
- define("SU_VERSION", "0.7");
42
  define("SU_AUTHOR", "SEO Design Solutions");
43
  define("SU_AUTHOR_URI", "http://www.seodesignsolutions.com/");
44
- define("SU_USER_AGENT", "SeoUltimate/0.7");
45
 
46
  define('SU_MODULE_ENABLED', 10);
47
  define('SU_MODULE_SILENCED', 5);
2
  /*
3
  Plugin Name: SEO Ultimate
4
  Plugin URI: http://www.seodesignsolutions.com/wordpress-seo/
5
+ Description: This all-in-one SEO plugin can rewrite title tags, set meta data, add noindex, insert canonical tags, log 404 errors, edit your robots.txt, and more.
6
+ Version: 0.8
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 0.8
16
  * @link http://www.seodesignsolutions.com/wordpress-seo/ SEO Ultimate Homepage
17
  */
18
 
38
 
39
  define("SU_PLUGIN_NAME", "SEO Ultimate");
40
  define("SU_PLUGIN_URI", "http://www.seodesignsolutions.com/wordpress-seo/");
41
+ define("SU_VERSION", "0.8");
42
  define("SU_AUTHOR", "SEO Design Solutions");
43
  define("SU_AUTHOR_URI", "http://www.seodesignsolutions.com/");
44
+ define("SU_USER_AGENT", "SeoUltimate/0.8");
45
 
46
  define('SU_MODULE_ENABLED', 10);
47
  define('SU_MODULE_SILENCED', 5);
seo-ultimate.pot CHANGED
@@ -8,7 +8,7 @@ msgid ""
8
  msgstr ""
9
  "Project-Id-Version: PACKAGE VERSION\n"
10
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/seo-ultimate\n"
11
- "POT-Creation-Date: 2009-07-17 03:13+0000\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,103 +18,103 @@ msgstr ""
18
 
19
  #. #-#-#-#-# plugin.pot (PACKAGE VERSION) #-#-#-#-#
20
  #. Plugin Name of an extension
21
- #: class.seo-ultimate.php:584 modules/settings.php:16
22
  msgid "SEO Ultimate"
23
  msgstr ""
24
 
25
- #: class.seo-ultimate.php:584
26
  msgid "SEO"
27
  msgstr ""
28
 
29
- #: class.seo-ultimate.php:770
30
  #, php-format
31
  msgid "%s Help"
32
  msgstr ""
33
 
34
- #: class.seo-ultimate.php:790
35
  msgid "SEO Settings Help"
36
  msgstr ""
37
 
38
- #: class.seo-ultimate.php:792
39
  msgid "The SEO Settings box lets you customize these settings:"
40
  msgstr ""
41
 
42
- #: class.seo-ultimate.php:794
43
  msgid "(The SEO Settings box is part of the SEO Ultimate plugin.)"
44
  msgstr ""
45
 
46
- #: class.seo-ultimate.php:849
47
  #, php-format
48
  msgid ""
49
  "SEO Ultimate includes the functionality of %1$s. You may want to deactivate %"
50
  "1$s to avoid plugin conflicts."
51
  msgstr ""
52
 
53
- #: class.seo-ultimate.php:917
54
  msgid "SEO Settings"
55
  msgstr ""
56
 
57
- #: class.su-hitset.php:36
58
  msgid "Date"
59
  msgstr ""
60
 
61
- #: class.su-hitset.php:37
62
  msgid "IP Address"
63
  msgstr ""
64
 
65
- #: class.su-hitset.php:38
66
- msgid "Browser"
67
  msgstr ""
68
 
69
- #: class.su-hitset.php:39
70
  msgid "URL Requested"
71
  msgstr ""
72
 
73
- #: class.su-hitset.php:40
74
  msgid "Redirected To"
75
  msgstr ""
76
 
77
- #: class.su-hitset.php:41
78
  msgid "Status Code"
79
  msgstr ""
80
 
81
- #: class.su-hitset.php:73
82
  #, php-format
83
  msgid "%1$s<br />%2$s"
84
  msgstr ""
85
 
86
- #: class.su-importmodule.php:41
87
  msgid "Import Now"
88
  msgstr ""
89
 
90
- #: class.su-importmodule.php:52
91
  msgid "Return to settings page"
92
  msgstr ""
93
 
94
- #: class.su-importmodule.php:55
95
  msgid "Return to SEO page"
96
  msgstr ""
97
 
98
- #: class.su-module.php:491
99
  #, php-format
100
  msgid "%1$s | %2$s %3$s by %4$s"
101
  msgstr ""
102
 
103
- #: class.su-module.php:526
104
  msgid "Settings updated."
105
  msgstr ""
106
 
107
- #: class.su-module.php:546
108
  msgid "Save Changes"
109
  msgstr ""
110
 
111
- #: class.su-module.php:642
112
  msgid ""
113
  "Are you sure you want to replace the textbox contents with this default "
114
  "value?"
115
  msgstr ""
116
 
117
- #: class.su-module.php:655
118
  msgid "Reset"
119
  msgstr ""
120
 
@@ -122,39 +122,39 @@ msgstr ""
122
  msgid "404 Monitor"
123
  msgstr ""
124
 
125
- #: modules/404s.php:35
126
  msgid "The log entry was successfully deleted."
127
  msgstr ""
128
 
129
- #: modules/404s.php:37
130
  msgid "This log entry has already been deleted."
131
  msgstr ""
132
 
133
- #: modules/404s.php:44
134
  msgid "The log was successfully cleared."
135
  msgstr ""
136
 
137
- #: modules/404s.php:50
138
  msgid "No 404 errors in the log."
139
  msgstr ""
140
 
141
- #: modules/404s.php:59
142
  msgid "Are you sure you want to delete all 404 log entries?"
143
  msgstr ""
144
 
145
- #: modules/404s.php:61
146
  msgid "Clear Log"
147
  msgstr ""
148
 
149
- #: modules/404s.php:73
150
  msgid "Open"
151
  msgstr ""
152
 
153
- #: modules/404s.php:74
154
  msgid "Google Cache"
155
  msgstr ""
156
 
157
- #: modules/404s.php:75
158
  msgid "Delete Log Entry"
159
  msgstr ""
160
 
@@ -166,6 +166,63 @@ msgstr ""
166
  msgid "Generate <code>&lt;link rel=&quot;canonical&quot; /&gt;</code> tags."
167
  msgstr ""
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  #: modules/linkbox.php:13
170
  msgid "Linkbox Inserter"
171
  msgstr ""
@@ -285,36 +342,40 @@ msgid ""
285
  msgstr ""
286
 
287
  #: modules/modules.php:13
 
 
 
 
288
  msgid "Module Manager"
289
  msgstr ""
290
 
291
- #: modules/modules.php:40
292
  msgid ""
293
  "Here you can disable or hide modules you don&#8217;t use. You can also "
294
  "silence modules from displaying bubble alerts on the menu."
295
  msgstr ""
296
 
297
- #: modules/modules.php:46
298
  msgid "Status"
299
  msgstr ""
300
 
301
- #: modules/modules.php:47
302
  msgid "Module"
303
  msgstr ""
304
 
305
- #: modules/modules.php:60
306
  msgid "Enabled"
307
  msgstr ""
308
 
309
- #: modules/modules.php:61
310
  msgid "Silenced"
311
  msgstr ""
312
 
313
- #: modules/modules.php:62
314
  msgid "Hidden"
315
  msgstr ""
316
 
317
- #: modules/modules.php:63
318
  msgid "Disabled"
319
  msgstr ""
320
 
@@ -392,99 +453,99 @@ msgstr ""
392
  msgid "SEO Ultimate Plugin Settings"
393
  msgstr ""
394
 
395
- #: modules/settings.php:64
396
  msgid "Settings successfully imported."
397
  msgstr ""
398
 
399
- #: modules/settings.php:66
400
  msgid ""
401
  "The uploaded file is not in the proper format. Settings could not be "
402
  "imported."
403
  msgstr ""
404
 
405
- #: modules/settings.php:68
406
  msgid "The settings file could not be uploaded successfully."
407
  msgstr ""
408
 
409
- #: modules/settings.php:71
410
  msgid ""
411
  "Settings could not be imported because no settings file was selected. Please "
412
  "click the &#8220;Browse&#8221; button and select a file to import."
413
  msgstr ""
414
 
415
- #: modules/settings.php:79
416
  msgid "All settings have been erased and defaults have been restored."
417
  msgstr ""
418
 
419
- #: modules/settings.php:93
420
  msgid "Plugin Settings"
421
  msgstr ""
422
 
423
- #: modules/settings.php:95
424
  msgid "Enable attribution link"
425
  msgstr ""
426
 
427
- #: modules/settings.php:96
428
  msgid "Enable attribution link CSS styling"
429
  msgstr ""
430
 
431
- #: modules/settings.php:97
432
  msgid "Notify me about unnecessary active plugins"
433
  msgstr ""
434
 
435
- #: modules/settings.php:99
436
  msgid "Insert comments around HTML code insertions"
437
  msgstr ""
438
 
439
- #: modules/settings.php:104
440
  msgid "Manage Settings Data"
441
  msgstr ""
442
 
443
- #: modules/settings.php:108
444
  msgid ""
445
  "This section allows you to export, import, and reset the settings of the "
446
  "plugin and all its modules."
447
  msgstr ""
448
 
449
- #: modules/settings.php:110
450
  msgid ""
451
  "A settings file includes the data of every checkbox and textbox of every "
452
  "installed module, as well as the &#8220;Plugin Settings&#8221; section "
453
  "above. "
454
  msgstr ""
455
 
456
- #: modules/settings.php:119
457
  msgid "Export:"
458
  msgstr ""
459
 
460
- #: modules/settings.php:122
461
  msgid "Download Settings File"
462
  msgstr ""
463
 
464
- #: modules/settings.php:127
465
  msgid "Import:"
466
  msgstr ""
467
 
468
- #: modules/settings.php:132
469
  msgid ""
470
- "Are you sure you want to import this settings file? This will erase all "
471
  "current settings and cannot be undone."
472
  msgstr ""
473
 
474
- #: modules/settings.php:133
475
  msgid "Import This Settings File"
476
  msgstr ""
477
 
478
- #: modules/settings.php:140
479
  msgid "Reset:"
480
  msgstr ""
481
 
482
- #: modules/settings.php:143
483
  msgid ""
484
  "Are you sure you want to erase all module settings? This cannot be undone."
485
  msgstr ""
486
 
487
- #: modules/settings.php:144
488
  msgid "Restore Default Settings"
489
  msgstr ""
490
 
@@ -605,9 +666,9 @@ msgstr ""
605
 
606
  #. Description of an extension
607
  msgid ""
608
- "This all-in-one SEO plugin can rewrite title tags, edit meta data, add "
609
- "noindex, insert canonical tags, and log 404 errors (with many more features "
610
- "coming soon)."
611
  msgstr ""
612
 
613
  #. Author of an extension
8
  msgstr ""
9
  "Project-Id-Version: PACKAGE VERSION\n"
10
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/seo-ultimate\n"
11
+ "POT-Creation-Date: 2009-07-23 22:19+0000\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
18
 
19
  #. #-#-#-#-# plugin.pot (PACKAGE VERSION) #-#-#-#-#
20
  #. Plugin Name of an extension
21
+ #: class.seo-ultimate.php:646 modules/settings.php:16
22
  msgid "SEO Ultimate"
23
  msgstr ""
24
 
25
+ #: class.seo-ultimate.php:646
26
  msgid "SEO"
27
  msgstr ""
28
 
29
+ #: class.seo-ultimate.php:832
30
  #, php-format
31
  msgid "%s Help"
32
  msgstr ""
33
 
34
+ #: class.seo-ultimate.php:852
35
  msgid "SEO Settings Help"
36
  msgstr ""
37
 
38
+ #: class.seo-ultimate.php:854
39
  msgid "The SEO Settings box lets you customize these settings:"
40
  msgstr ""
41
 
42
+ #: class.seo-ultimate.php:856
43
  msgid "(The SEO Settings box is part of the SEO Ultimate plugin.)"
44
  msgstr ""
45
 
46
+ #: class.seo-ultimate.php:911
47
  #, php-format
48
  msgid ""
49
  "SEO Ultimate includes the functionality of %1$s. You may want to deactivate %"
50
  "1$s to avoid plugin conflicts."
51
  msgstr ""
52
 
53
+ #: class.seo-ultimate.php:992
54
  msgid "SEO Settings"
55
  msgstr ""
56
 
57
+ #: class.su-hitset.php:44
58
  msgid "Date"
59
  msgstr ""
60
 
61
+ #: class.su-hitset.php:45
62
  msgid "IP Address"
63
  msgstr ""
64
 
65
+ #: class.su-hitset.php:46
66
+ msgid "User Agent"
67
  msgstr ""
68
 
69
+ #: class.su-hitset.php:47
70
  msgid "URL Requested"
71
  msgstr ""
72
 
73
+ #: class.su-hitset.php:48
74
  msgid "Redirected To"
75
  msgstr ""
76
 
77
+ #: class.su-hitset.php:49
78
  msgid "Status Code"
79
  msgstr ""
80
 
81
+ #: class.su-hitset.php:81
82
  #, php-format
83
  msgid "%1$s<br />%2$s"
84
  msgstr ""
85
 
86
+ #: class.su-importmodule.php:37
87
  msgid "Import Now"
88
  msgstr ""
89
 
90
+ #: class.su-importmodule.php:48
91
  msgid "Return to settings page"
92
  msgstr ""
93
 
94
+ #: class.su-importmodule.php:51
95
  msgid "Return to SEO page"
96
  msgstr ""
97
 
98
+ #: class.su-module.php:518
99
  #, php-format
100
  msgid "%1$s | %2$s %3$s by %4$s"
101
  msgstr ""
102
 
103
+ #: class.su-module.php:552
104
  msgid "Settings updated."
105
  msgstr ""
106
 
107
+ #: class.su-module.php:572
108
  msgid "Save Changes"
109
  msgstr ""
110
 
111
+ #: class.su-module.php:668
112
  msgid ""
113
  "Are you sure you want to replace the textbox contents with this default "
114
  "value?"
115
  msgstr ""
116
 
117
+ #: class.su-module.php:681
118
  msgid "Reset"
119
  msgstr ""
120
 
122
  msgid "404 Monitor"
123
  msgstr ""
124
 
125
+ #: modules/404s.php:30
126
  msgid "The log entry was successfully deleted."
127
  msgstr ""
128
 
129
+ #: modules/404s.php:32
130
  msgid "This log entry has already been deleted."
131
  msgstr ""
132
 
133
+ #: modules/404s.php:39
134
  msgid "The log was successfully cleared."
135
  msgstr ""
136
 
137
+ #: modules/404s.php:45
138
  msgid "No 404 errors in the log."
139
  msgstr ""
140
 
141
+ #: modules/404s.php:54
142
  msgid "Are you sure you want to delete all 404 log entries?"
143
  msgstr ""
144
 
145
+ #: modules/404s.php:56
146
  msgid "Clear Log"
147
  msgstr ""
148
 
149
+ #: modules/404s.php:68
150
  msgid "Open"
151
  msgstr ""
152
 
153
+ #: modules/404s.php:69
154
  msgid "Google Cache"
155
  msgstr ""
156
 
157
+ #: modules/404s.php:70
158
  msgid "Delete Log Entry"
159
  msgstr ""
160
 
166
  msgid "Generate <code>&lt;link rel=&quot;canonical&quot; /&gt;</code> tags."
167
  msgstr ""
168
 
169
+ #: modules/files.php:15
170
+ msgid "File Editor"
171
+ msgstr ""
172
+
173
+ #: modules/files.php:41
174
+ msgid ""
175
+ "A .htaccess file exists, but it&#8217;s not writable. You can edit it here "
176
+ "once the file permissions are corrected."
177
+ msgstr ""
178
+
179
+ #: modules/files.php:45
180
+ msgid ""
181
+ "WordPress won&#8217;t be able to display your robots.txt file because the "
182
+ "default <a href=\"options-permalink.php\" target=\"_blank\">permalink "
183
+ "structure</a> is in use."
184
+ msgstr ""
185
+
186
+ #: modules/files.php:51
187
+ #, php-format
188
+ msgid "robots.txt [<a href=\"%s\" target=\"_blank\">Open</a>]"
189
+ msgstr ""
190
+
191
+ #: modules/files.php:53
192
+ msgid "Enable this custom robots.txt file and disable the default file"
193
+ msgstr ""
194
+
195
+ #: modules/files.php:54
196
+ msgid "Let other plugins add rules to my custom robots.txt file"
197
+ msgstr ""
198
+
199
+ #: modules/files.php:55
200
+ msgid "robots.txt Settings"
201
+ msgstr ""
202
+
203
+ #: modules/files.php:58
204
+ msgid ""
205
+ "Please realize that incorrectly editing your robots.txt file could block "
206
+ "search engines from your site."
207
+ msgstr ""
208
+
209
+ #: modules/files.php:61
210
+ msgid ".htaccess"
211
+ msgstr ""
212
+
213
+ #: modules/files.php:64
214
+ msgid ""
215
+ "Also, incorrectly editing your .htaccess file could disable your entire "
216
+ "website. Edit with caution!"
217
+ msgstr ""
218
+
219
+ #: modules/files.php:107
220
+ #, php-format
221
+ msgid ""
222
+ "Please note that your privacy settings won&#8217;t have any effect on your "
223
+ "robots.txt file, since you&#8217;re using <a href=\"%s\">a custom one</a>."
224
+ msgstr ""
225
+
226
  #: modules/linkbox.php:13
227
  msgid "Linkbox Inserter"
228
  msgstr ""
342
  msgstr ""
343
 
344
  #: modules/modules.php:13
345
+ msgid "Modules"
346
+ msgstr ""
347
+
348
+ #: modules/modules.php:14
349
  msgid "Module Manager"
350
  msgstr ""
351
 
352
+ #: modules/modules.php:35
353
  msgid ""
354
  "Here you can disable or hide modules you don&#8217;t use. You can also "
355
  "silence modules from displaying bubble alerts on the menu."
356
  msgstr ""
357
 
358
+ #: modules/modules.php:41
359
  msgid "Status"
360
  msgstr ""
361
 
362
+ #: modules/modules.php:42
363
  msgid "Module"
364
  msgstr ""
365
 
366
+ #: modules/modules.php:55
367
  msgid "Enabled"
368
  msgstr ""
369
 
370
+ #: modules/modules.php:56
371
  msgid "Silenced"
372
  msgstr ""
373
 
374
+ #: modules/modules.php:57
375
  msgid "Hidden"
376
  msgstr ""
377
 
378
+ #: modules/modules.php:58
379
  msgid "Disabled"
380
  msgstr ""
381
 
453
  msgid "SEO Ultimate Plugin Settings"
454
  msgstr ""
455
 
456
+ #: modules/settings.php:65
457
  msgid "Settings successfully imported."
458
  msgstr ""
459
 
460
+ #: modules/settings.php:67
461
  msgid ""
462
  "The uploaded file is not in the proper format. Settings could not be "
463
  "imported."
464
  msgstr ""
465
 
466
+ #: modules/settings.php:69
467
  msgid "The settings file could not be uploaded successfully."
468
  msgstr ""
469
 
470
+ #: modules/settings.php:72
471
  msgid ""
472
  "Settings could not be imported because no settings file was selected. Please "
473
  "click the &#8220;Browse&#8221; button and select a file to import."
474
  msgstr ""
475
 
476
+ #: modules/settings.php:80
477
  msgid "All settings have been erased and defaults have been restored."
478
  msgstr ""
479
 
480
+ #: modules/settings.php:94
481
  msgid "Plugin Settings"
482
  msgstr ""
483
 
484
+ #: modules/settings.php:96
485
  msgid "Enable attribution link"
486
  msgstr ""
487
 
488
+ #: modules/settings.php:97
489
  msgid "Enable attribution link CSS styling"
490
  msgstr ""
491
 
492
+ #: modules/settings.php:98
493
  msgid "Notify me about unnecessary active plugins"
494
  msgstr ""
495
 
496
+ #: modules/settings.php:100
497
  msgid "Insert comments around HTML code insertions"
498
  msgstr ""
499
 
500
+ #: modules/settings.php:105
501
  msgid "Manage Settings Data"
502
  msgstr ""
503
 
504
+ #: modules/settings.php:109
505
  msgid ""
506
  "This section allows you to export, import, and reset the settings of the "
507
  "plugin and all its modules."
508
  msgstr ""
509
 
510
+ #: modules/settings.php:111
511
  msgid ""
512
  "A settings file includes the data of every checkbox and textbox of every "
513
  "installed module, as well as the &#8220;Plugin Settings&#8221; section "
514
  "above. "
515
  msgstr ""
516
 
517
+ #: modules/settings.php:120
518
  msgid "Export:"
519
  msgstr ""
520
 
521
+ #: modules/settings.php:123
522
  msgid "Download Settings File"
523
  msgstr ""
524
 
525
+ #: modules/settings.php:128
526
  msgid "Import:"
527
  msgstr ""
528
 
529
+ #: modules/settings.php:133
530
  msgid ""
531
+ "Are you sure you want to import this settings file? This will overwrite your "
532
  "current settings and cannot be undone."
533
  msgstr ""
534
 
535
+ #: modules/settings.php:134
536
  msgid "Import This Settings File"
537
  msgstr ""
538
 
539
+ #: modules/settings.php:141
540
  msgid "Reset:"
541
  msgstr ""
542
 
543
+ #: modules/settings.php:144
544
  msgid ""
545
  "Are you sure you want to erase all module settings? This cannot be undone."
546
  msgstr ""
547
 
548
+ #: modules/settings.php:145
549
  msgid "Restore Default Settings"
550
  msgstr ""
551
 
666
 
667
  #. Description of an extension
668
  msgid ""
669
+ "This all-in-one SEO plugin can rewrite title tags, set meta data, add "
670
+ "noindex, insert canonical tags, log 404 errors, edit your robots.txt, and "
671
+ "more."
672
  msgstr ""
673
 
674
  #. Author of an extension