WP-UserOnline - Version 2.83

Version Description

  • Show user agent when hovering over IP, instead of address lookup
  • Use local time for UserOnline Page
  • Fixed 'Strict Standards: Non-static method' warnings
  • Update scb Framework
Download this release

Release Info

Developer GamerZ
Plugin Icon WP-UserOnline
Version 2.83
Comparing to
See all releases

Code changes from version 2.82 to 2.83

admin.php CHANGED
@@ -60,10 +60,10 @@ class UserOnline_Options extends scbAdminPage {
60
  $this->option_name = 'useronline';
61
  }
62
 
63
- function validate( $options ) {
64
  $options['timeout'] = absint( $options['timeout'] );
65
  $options['url'] = trim( $options['url'] );
66
- $options['names'] = (bool) $options['names'];
67
 
68
  foreach ( $options['templates'] as $key => $template )
69
  if ( is_array( $template ) )
@@ -125,10 +125,11 @@ class UserOnline_Options extends scbAdminPage {
125
  ),
126
 
127
  array(
128
- 'title' => __( 'User Names', 'wp-useronline' ),
129
- 'type' => 'checkbox',
130
  'name' => 'names',
131
- 'desc' => __( 'Link user names to their author page', 'wp-useronline' ),
 
132
  ),
133
  );
134
 
60
  $this->option_name = 'useronline';
61
  }
62
 
63
+ function validate( $options, $old_data = array() ) {
64
  $options['timeout'] = absint( $options['timeout'] );
65
  $options['url'] = trim( $options['url'] );
66
+ $options['names'] = intval($options['names']);
67
 
68
  foreach ( $options['templates'] as $key => $template )
69
  if ( is_array( $template ) )
125
  ),
126
 
127
  array(
128
+ 'title' => __( 'Link user names?', 'wp-useronline' ),
129
+ 'type' => 'radio',
130
  'name' => 'names',
131
+ 'choices' => array( 1 => __( 'Yes', 'wp-useronline' ), 0 => __( 'No', 'wp-useronline' ) ),
132
+ 'desc' => '<br />' . __( 'Link user names to their author page', 'wp-useronline' )
133
  ),
134
  );
135
 
bots.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function useronline_get_bots() {
4
+ $bots = array(
5
+ 'Google Bot' => 'google',
6
+ 'MSN' => 'msnbot',
7
+ 'BingBot' => 'bingbot',
8
+ 'Alex' => 'ia_archiver',
9
+ 'Lycos' => 'lycos',
10
+ 'Ask Jeeves' => 'jeeves',
11
+ 'Altavista' => 'scooter',
12
+ 'AllTheWeb' => 'fast-webcrawler',
13
+ 'Inktomi' => 'slurp@inktomi',
14
+ 'Turnitin.com' => 'turnitinbot',
15
+ 'Technorati' => 'technorati',
16
+ 'Yahoo' => 'yahoo',
17
+ 'Findexa' => 'findexa',
18
+ 'NextLinks' => 'findlinks',
19
+ 'Gais' => 'gaisbo',
20
+ 'WiseNut' => 'zyborg',
21
+ 'WhoisSource' => 'surveybot',
22
+ 'Bloglines' => 'bloglines',
23
+ 'BlogSearch' => 'blogsearch',
24
+ 'PubSub' => 'pubsub',
25
+ 'Syndic8' => 'syndic8',
26
+ 'RadioUserland' => 'userland',
27
+ 'Gigabot' => 'gigabot',
28
+ 'Become.com' => 'become.com',
29
+ 'Baidu' => 'baidu',
30
+ 'Yandex' => 'yandex',
31
+ 'Amazon' => 'amazonaws.com',
32
+ 'Ahrefs' => 'AhrefsBot'
33
+ );
34
+
35
+ return apply_filters( 'useronline_bots', $bots );
36
+ }
37
+
core.php CHANGED
@@ -9,7 +9,7 @@ class UserOnline_Core {
9
 
10
  private static $useronline;
11
 
12
- function get_user_online_count() {
13
  global $wpdb;
14
 
15
  if ( is_null( self::$useronline ) )
@@ -18,7 +18,7 @@ class UserOnline_Core {
18
  return self::$useronline;
19
  }
20
 
21
- function init( $options, $most ) {
22
  self::$options = $options;
23
  self::$most = $most;
24
 
@@ -38,7 +38,7 @@ class UserOnline_Core {
38
  add_filter( 'useronline_display_user', array( __CLASS__, 'linked_names' ), 10, 2 );
39
  }
40
 
41
- function linked_names( $name, $user ) {
42
  if ( !$user->user_id )
43
  return $name;
44
 
@@ -60,7 +60,9 @@ class UserOnline_Core {
60
  scbUtil::do_scripts('wp-useronline');
61
  }
62
 
63
- function record( $page_url = '', $page_title = '' ) {
 
 
64
  global $wpdb;
65
 
66
  if ( empty( $page_url ) )
@@ -75,41 +77,16 @@ class UserOnline_Core {
75
  $referral = '';
76
 
77
  $user_ip = self::get_ip();
78
- $user_agent = $_SERVER['HTTP_USER_AGENT'];
 
 
 
 
 
79
  $current_user = wp_get_current_user();
80
 
81
  // Check For Bot
82
- $bots = array(
83
- 'Google Bot' => 'google',
84
- 'MSN' => 'msnbot',
85
- 'BingBot' => 'bingbot',
86
- 'Alex' => 'ia_archiver',
87
- 'Lycos' => 'lycos',
88
- 'Ask Jeeves' => 'jeeves',
89
- 'Altavista' => 'scooter',
90
- 'AllTheWeb' => 'fast-webcrawler',
91
- 'Inktomi' => 'slurp@inktomi',
92
- 'Turnitin.com' => 'turnitinbot',
93
- 'Technorati' => 'technorati',
94
- 'Yahoo' => 'yahoo',
95
- 'Findexa' => 'findexa',
96
- 'NextLinks' => 'findlinks',
97
- 'Gais' => 'gaisbo',
98
- 'WiseNut' => 'zyborg',
99
- 'WhoisSource' => 'surveybot',
100
- 'Bloglines' => 'bloglines',
101
- 'BlogSearch' => 'blogsearch',
102
- 'PubSub' => 'pubsub',
103
- 'Syndic8' => 'syndic8',
104
- 'RadioUserland' => 'userland',
105
- 'Gigabot' => 'gigabot',
106
- 'Become.com' => 'become.com',
107
- 'Baidu' => 'baidu',
108
- 'Yandex' => 'yandex',
109
- 'Amazon' => 'amazonaws.com'
110
- );
111
-
112
- $bots = apply_filters( 'useronline_bots', $bots );
113
 
114
  $bot_found = false;
115
  foreach ( $bots as $name => $lookfor ) {
@@ -145,15 +122,14 @@ class UserOnline_Core {
145
  }
146
  }
147
 
 
 
 
148
  // Purge table
149
- $wpdb->query( $wpdb->prepare( "
150
- DELETE FROM $wpdb->useronline
151
- WHERE user_ip = %s
152
- OR timestamp < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL %d SECOND)
153
- ", $user_ip, self::$options->timeout ) );
154
 
155
  // Insert Users
156
- $data = compact( 'user_type', 'user_id', 'user_name', 'user_ip', 'user_agent', 'page_title', 'page_url', 'referral' );
157
  $data = stripslashes_deep( $data );
158
  $wpdb->replace( $wpdb->useronline, $data );
159
 
@@ -175,9 +151,7 @@ class UserOnline_Core {
175
  $wpdb->query( "DELETE FROM $wpdb->useronline" );
176
  }
177
 
178
- function ajax() {
179
- global $wpdb;
180
-
181
  $mode = trim( $_POST['mode'] );
182
 
183
  $page_title = strip_tags( $_POST['page_title'] );
@@ -205,12 +179,12 @@ class UserOnline_Core {
205
  die;
206
  }
207
 
208
- function wp_stats_integration() {
209
  if ( function_exists( 'stats_page' ) )
210
  require_once dirname( __FILE__ ) . '/wp-stats.php';
211
  }
212
 
213
- private function get_title() {
214
  if ( is_admin() && function_exists( 'get_admin_page_title' ) ) {
215
  $page_title = ' &raquo; ' . __( 'Admin', 'wp-useronline' ) . ' &raquo; ' . get_admin_page_title();
216
  } else {
@@ -225,7 +199,7 @@ class UserOnline_Core {
225
  return $page_title;
226
  }
227
 
228
- private function get_ip() {
229
  if ( isset( $_SERVER["HTTP_X_FORWARDED_FOR"] ) )
230
  $ip_address = $_SERVER["HTTP_X_FORWARDED_FOR"];
231
  else
9
 
10
  private static $useronline;
11
 
12
+ static function get_user_online_count() {
13
  global $wpdb;
14
 
15
  if ( is_null( self::$useronline ) )
18
  return self::$useronline;
19
  }
20
 
21
+ static function init( $options, $most ) {
22
  self::$options = $options;
23
  self::$most = $most;
24
 
38
  add_filter( 'useronline_display_user', array( __CLASS__, 'linked_names' ), 10, 2 );
39
  }
40
 
41
+ static function linked_names( $name, $user ) {
42
  if ( !$user->user_id )
43
  return $name;
44
 
60
  scbUtil::do_scripts('wp-useronline');
61
  }
62
 
63
+ static function record( $page_url = '', $page_title = '' ) {
64
+ require_once dirname(__FILE__) . '/bots.php';
65
+
66
  global $wpdb;
67
 
68
  if ( empty( $page_url ) )
77
  $referral = '';
78
 
79
  $user_ip = self::get_ip();
80
+
81
+ if ( isset( $_SERVER['HTTP_USER_AGENT'] ) )
82
+ $user_agent = strip_tags( $_SERVER['HTTP_USER_AGENT'] );
83
+ else
84
+ $user_agent = '';
85
+
86
  $current_user = wp_get_current_user();
87
 
88
  // Check For Bot
89
+ $bots = useronline_get_bots();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  $bot_found = false;
92
  foreach ( $bots as $name => $lookfor ) {
122
  }
123
  }
124
 
125
+ // Current GMT Timestamp
126
+ $timestamp = current_time( 'mysql' );
127
+
128
  // Purge table
129
+ $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->useronline WHERE user_ip = %s OR timestamp < DATE_SUB(%s, INTERVAL %d SECOND)", $user_ip, $timestamp, self::$options->timeout ) );
 
 
 
 
130
 
131
  // Insert Users
132
+ $data = compact( 'timestamp', 'user_type', 'user_id', 'user_name', 'user_ip', 'user_agent', 'page_title', 'page_url', 'referral' );
133
  $data = stripslashes_deep( $data );
134
  $wpdb->replace( $wpdb->useronline, $data );
135
 
151
  $wpdb->query( "DELETE FROM $wpdb->useronline" );
152
  }
153
 
154
+ static function ajax() {
 
 
155
  $mode = trim( $_POST['mode'] );
156
 
157
  $page_title = strip_tags( $_POST['page_title'] );
179
  die;
180
  }
181
 
182
+ static function wp_stats_integration() {
183
  if ( function_exists( 'stats_page' ) )
184
  require_once dirname( __FILE__ ) . '/wp-stats.php';
185
  }
186
 
187
+ private static function get_title() {
188
  if ( is_admin() && function_exists( 'get_admin_page_title' ) ) {
189
  $page_title = ' &raquo; ' . __( 'Admin', 'wp-useronline' ) . ' &raquo; ' . get_admin_page_title();
190
  } else {
199
  return $page_title;
200
  }
201
 
202
+ private static function get_ip() {
203
  if ( isset( $_SERVER["HTTP_X_FORWARDED_FOR"] ) )
204
  $ip_address = $_SERVER["HTTP_X_FORWARDED_FOR"];
205
  else
lang/wp-useronline-hu_HU.mo CHANGED
Binary file
lang/wp-useronline-hu_HU.po CHANGED
@@ -1,11 +1,11 @@
1
  msgid ""
2
  msgstr ""
3
- "Project-Id-Version: WP-UserOnline 2.60 HU\n"
4
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-useronline\n"
5
- "POT-Creation-Date: 2010-02-12 01:21+0000\n"
6
  "PO-Revision-Date: \n"
7
- "Last-Translator: FYGureout <webmester@sakraft.hu>\n"
8
- "Language-Team: FYGureout <webmester@sakraft.hu>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
@@ -14,338 +14,307 @@ msgstr ""
14
  "X-Poedit-Country: HUNGARY\n"
15
  "X-Poedit-SourceCharset: utf-8\n"
16
 
17
- #: admin.php:8
18
- msgid "Users Online Now"
19
- msgstr "Jelenlegi látogató"
20
-
21
- #. #-#-#-#-# plugin.pot (WP-UserOnline 2.60rc) #-#-#-#-#
22
- #. Plugin Name of an extension
23
- #: admin.php:9
24
- #: wp-stats.php:21
25
- #: wp-stats.php:38
26
- msgid "WP-UserOnline"
27
- msgstr "WP-UserOnline"
28
-
29
- #: admin.php:22
30
- #, php-format
31
- msgid "There is <strong><a href=\"%s\">%s user</a></strong> online now."
32
- msgid_plural "There are a total of <strong><a href=\"%s\">%s users</a></strong> online now."
33
- msgstr[0] "Jelenleg <strong><a href=\"%s\">%s látogató</a></strong> online"
34
- msgstr[1] "Jelenleg <strong><a href=\"%s\">%s látogató</a></strong> online"
35
-
36
- #: admin.php:47
37
- msgid "UserOnline Options"
38
- msgstr "UserOnline lehetőségek"
39
 
40
- #: admin.php:48
41
- #: wp-useronline.php:518
42
- #: wp-useronline.php:575
43
  msgid "UserOnline"
44
- msgstr "UserOnline"
45
 
46
- #: admin.php:58
47
- #: wp-useronline.php:73
48
- msgid "Online"
49
- msgstr "online"
50
-
51
- #: admin.php:64
52
- #: wp-useronline.php:63
53
- msgid "1 User"
54
- msgstr "1 látogató"
55
 
56
- #: admin.php:65
57
- #: wp-useronline.php:64
58
- msgid "%USERONLINE_COUNT% Users"
59
- msgstr "%USERONLINE_COUNT% látogató"
60
 
61
- #: admin.php:66
62
- #: wp-useronline.php:65
63
- msgid "1 Member"
64
- msgstr "1 tag"
65
 
66
- #: admin.php:67
67
- #: wp-useronline.php:66
68
- msgid "%USERONLINE_COUNT% Members"
69
- msgstr "%USERONLINE_COUNT% tag"
70
 
71
- #: admin.php:68
72
- #: wp-useronline.php:67
73
- msgid "1 Guest"
74
- msgstr "1 vendég"
75
 
76
- #: admin.php:69
77
- #: wp-useronline.php:68
78
- msgid "%USERONLINE_COUNT% Guests"
79
- msgstr "%USERONLINE_COUNT% vendég"
80
 
81
- #: admin.php:70
82
- #: wp-useronline.php:69
83
- msgid "1 Bot"
84
- msgstr "1 robot"
85
 
86
- #: admin.php:71
87
- #: wp-useronline.php:70
88
- msgid "%USERONLINE_COUNT% Bots"
89
- msgstr "%USERONLINE_COUNT% robot"
90
-
91
- #: admin.php:74
92
- #: admin.php:75
93
- #: admin.php:76
94
- #: admin.php:80
95
- #: admin.php:81
96
- #: admin.php:82
97
- #: wp-useronline.php:76
98
- #: wp-useronline.php:77
99
- #: wp-useronline.php:78
100
- #: wp-useronline.php:83
101
- #: wp-useronline.php:84
102
- #: wp-useronline.php:85
103
- msgid ","
104
- msgstr ", "
105
 
106
- #: admin.php:77
107
- #: admin.php:83
108
- #: wp-useronline.php:79
109
- #: wp-useronline.php:86
110
- msgid "Users|Template Element"
111
- msgstr "Felhasználó|Sablon elem"
112
 
113
- #: admin.php:83
114
- #: wp-useronline.php:86
115
- msgid "Browsing This Page."
116
- msgstr "böngészi ezt az oldalt"
 
117
 
118
- #: admin.php:127
119
- msgid "Settings updated."
120
- msgstr "Beállítások frissítve"
121
 
122
- #: admin.php:140
123
  msgid "Time Out"
124
  msgstr "Időtúllépés"
125
 
126
- #: admin.php:142
127
- msgid "How long till it will remove the user from the database (In seconds)."
128
- msgstr "Mennyi idő múlva távolítja el a felhasználót az adatbázisból (másodpercben)"
129
 
130
- #: admin.php:146
131
  msgid "UserOnline URL"
132
  msgstr "UserOnline URL"
133
 
134
- #: admin.php:148
135
- msgid "URL To UserOnline Page (leave blank if you do not want to link it to the UserOnline Page)<br />Example: http://www.yoursite.com/blogs/useronline/<br />Example: http://www.yoursite.com/blogs/?page_id=2"
136
- msgstr "URL az UserOnline oldalhoz (üresen kell hagyni, ha nem akarjuk linkelni az UserOnline oldalhoz)<br />Például: http://www.teoldalad.hu/blogs/useronline/<br />Például: http://www.yoursite.com/blogs/?page_id=2"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
- #: admin.php:152
139
- msgid "Bots Name/User Agent"
140
- msgstr "Robot neve/Robotként bejelentkező"
141
 
142
- #: admin.php:154
143
- msgid "Here are a list of bots and their partial browser agents.<br />On the left column will be the <strong>Bot's Name</strong> and on the right column will be their <strong>Partial Browser Agent</strong>.<br />Start each entry on a new line."
144
- msgstr "Itt egy lista a robotokról, és az ő részleges kereső ügynökeiről.<br />A bal oldali oszlopban a <strong>Robot neve</strong>, és a jobb oldaliban az ő <strong>Részleges kereső ügynöke</strong><br />Mindegyiket új sorban kell kezdeni."
 
 
145
 
146
- #: admin.php:162
147
  msgid "Naming Conventions:"
148
  msgstr "Elnevezési szabályok:"
149
 
150
- #: admin.php:163
151
- #: admin.php:197
152
- #: admin.php:222
153
  msgid "Allowed Variables:"
154
  msgstr "Engedélyezett variációk:"
155
 
156
- #: admin.php:165
157
- #: admin.php:202
158
- #: admin.php:230
159
- msgid "Restore Default Template"
160
- msgstr "Alapsablon visszaállítása"
161
 
162
- #: admin.php:171
163
  msgid "Singular Form"
164
  msgstr "Egyes számú forma"
165
 
166
- #: admin.php:172
167
  msgid "Plural Form"
168
  msgstr "Többes számú forma"
169
 
170
- #: admin.php:192
171
- msgid "Useronline Templates"
172
- msgstr "UserOnline sablon"
173
-
174
- #: admin.php:196
175
  msgid "User(s) Online:"
176
  msgstr "Látogató(k) online:"
177
 
178
- #: admin.php:206
179
- msgid "User(s) Browsing Site:"
180
- msgstr "Látogató böngészi a lapot:"
181
-
182
- #: admin.php:207
183
- msgid "User(s) Browsing Page:"
184
- msgstr "Látogató böngészi az oldalt:"
185
-
186
- #: admin.php:210
187
- #: scb/AdminPage.php:119
188
- #: scb/AdminPage.php:130
189
- msgid "Save Changes"
190
- msgstr "Változások mentése"
191
 
192
- #: admin.php:236
193
  msgid "Member Names Separator"
194
  msgstr "Tagnév elválasztó"
195
 
196
- #: admin.php:237
197
  msgid "Guests Separator"
198
  msgstr "Vendég elválasztó"
199
 
200
- #: admin.php:238
201
  msgid "Bots Separator"
202
  msgstr "Robot elválasztó"
203
 
204
- #: scb/AdminPage.php:108
205
- msgid "Settings <strong>saved</strong>."
206
- msgstr "A beállítások <strong>elmentve</strong>!"
207
-
208
- #: scb/AdminPage.php:284
209
- msgid "Settings"
210
- msgstr "Beállítások"
211
-
212
- #: wp-stats.php:31
213
- #, php-format
214
  msgid "<strong>%s</strong> user online now."
215
  msgid_plural "<strong>%s</strong> users online now."
216
- msgstr[0] "Jelenleg <strong>%s</strong> látogató online."
217
- msgstr[1] "Jelenleg <strong>%s</strong> látogató online."
218
-
219
- #: wp-useronline.php:151
220
- msgid "guest"
221
- msgstr "vendég"
222
-
223
- #: wp-useronline.php:157
224
- #: wp-useronline.php:349
225
- msgid "Guest"
226
- msgstr "Vendég"
227
-
228
- #: wp-useronline.php:166
229
- msgid "Admin"
230
- msgstr "Admin"
231
-
232
- #: wp-useronline.php:172
233
- msgid "Archive"
234
- msgstr "Archívum"
235
-
236
- #: wp-useronline.php:347
237
- msgid "User"
238
- msgstr "látogató"
239
-
240
- #: wp-useronline.php:347
241
- msgid "Users"
242
- msgstr "látogató"
243
-
244
- #: wp-useronline.php:348
245
- msgid "Member"
246
- msgstr "tag"
247
-
248
- #: wp-useronline.php:348
249
- msgid "Members"
250
- msgstr "tag"
251
-
252
- #: wp-useronline.php:349
253
- msgid "Guests"
254
- msgstr "vendég"
255
-
256
- #: wp-useronline.php:350
257
- msgid "Bot"
258
- msgstr "robot"
259
-
260
- #: wp-useronline.php:350
261
- msgid "Bots"
262
- msgstr "robot"
263
 
264
- #: wp-useronline.php:358
265
- #, php-format
266
  msgid "There is <strong>%s</strong> online now: <strong>%s</strong>, <strong>%s</strong> and <strong>%s</strong>."
267
  msgid_plural "There are a total of <strong>%s</strong> online now: <strong>%s</strong>, <strong>%s</strong> and <strong>%s</strong>."
268
- msgstr[0] "Jelenleg <strong>%s</strong> látogató online: <strong>%s</strong>, <strong>%s</strong>, és <strong>%s</strong>."
269
- msgstr[1] "Jelenleg <strong>%s</strong> látogató online: <strong>%s</strong>, <strong>%s</strong>, és <strong>%s</strong>"
270
 
271
- #: wp-useronline.php:434
272
- msgid "No One Is Online Now"
273
- msgstr "Senki nincs most online"
274
 
275
- #: wp-useronline.php:436
276
  msgid "on"
277
  msgstr " - "
278
 
279
- #: wp-useronline.php:437
280
  msgid "url"
281
  msgstr "url"
282
 
283
- #: wp-useronline.php:438
284
  msgid "referral"
285
  msgstr "azonosítva"
286
 
287
- #: wp-useronline.php:449
288
  msgid "Online Now"
289
- msgstr "Jelenleg online"
290
 
291
- #: wp-useronline.php:480
292
- #, php-format
293
  msgid "%s @ %s"
294
  msgstr "%s - %s"
295
 
296
- #: wp-useronline.php:499
297
- #, php-format
298
  msgid "Most users ever online were <strong>%s</strong>, on <strong>%s</strong>"
299
- msgstr "A legtöbb látógató egyidőben <strong>%s</strong> volt, <strong>%s</strong>. napján."
300
 
301
- #: wp-useronline.php:517
302
- msgid "WP-UserOnline users online statistics"
303
- msgstr "WP-UserOnline látogató online statisztika"
304
 
305
- #: wp-useronline.php:582
306
- msgid "Title:"
307
- msgstr "Cím"
308
 
309
- #: wp-useronline.php:585
310
- msgid "Statistics Type:"
311
- msgstr "Statisztika típusa:"
312
 
313
- #: wp-useronline.php:587
314
- msgid "Users Online Count"
315
- msgstr "Látogató online szám"
316
 
317
- #: wp-useronline.php:588
318
- msgid "Users Browsing Current Page"
319
- msgstr "Látogató böngészi az aktuális oldalt"
320
 
321
- #: wp-useronline.php:589
322
- msgid "Users Browsing Site"
323
- msgstr "Látogató böngészi a lapot"
324
 
325
- #: wp-useronline.php:591
326
- msgid "Users Online Count & Users Browsing Current Page"
327
- msgstr "Látogató online & Látogató böngészi az aktuális oldalt"
328
 
329
- #: wp-useronline.php:592
330
- msgid "Users Online Count & Users Browsing Site"
331
- msgstr "Látogató online szám & Látogató böngészi a lapot"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
 
333
- #. Plugin URI of an extension
334
- msgid "http://lesterchan.net/portfolio/programming/php/"
335
- msgstr "http://lesterchan.net/portfolio/programming/php/"
 
 
336
 
337
- #. Description of an extension
338
- msgid "Enable you to display how many users are online on your Wordpress blog with detailed statistics of where they are and who there are(Members/Guests/Search Bots)."
339
- msgstr "Megjeleníti a WordPress-alapú honlapon éppen jelenlévő látogatók számát, részletes statisztikával, hogy honnan érkeztek és kik ők (tagok / vendégek /keresőrobotok)."
340
 
341
- #. Author of an extension
342
- msgid "Lester 'GaMerZ' Chan"
343
- msgstr "Lester 'GaMerZ' Chan"
344
 
345
- #. Author URI of an extension
346
- msgid "http://lesterchan.net"
347
- msgstr "http://lesterchan.net"
348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  #~ msgid "Useronline Timeout"
350
  #~ msgstr "Useronline időtúllépés"
351
  #~ msgid "Useronline Bots"
1
  msgid ""
2
  msgstr ""
3
+ "Project-Id-Version: WP-UserOnline 2.82- HU\n"
4
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/wpu\n"
5
+ "POT-Creation-Date: 2011-06-02 20:04:14+00:00\n"
6
  "PO-Revision-Date: \n"
7
+ "Last-Translator: FYGureout <webmester@wordpress2you.com>\n"
8
+ "Language-Team: FYGureout <webmester@wordpress2you.com>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
14
  "X-Poedit-Country: HUNGARY\n"
15
  "X-Poedit-SourceCharset: utf-8\n"
16
 
17
+ #: widget.php:5
18
+ msgid "WP-UserOnline users online statistics"
19
+ msgstr "WP-UserOnline látogató online statisztika"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ #: widget.php:6
22
+ #: widget.php:49
23
+ #: admin.php:56
24
  msgid "UserOnline"
25
+ msgstr "WP-User Online"
26
 
27
+ #: widget.php:56
28
+ msgid "Title:"
29
+ msgstr "Cím:"
 
 
 
 
 
 
30
 
31
+ #: widget.php:59
32
+ msgid "Statistics Type:"
33
+ msgstr "Statisztika típusa:"
 
34
 
35
+ #: widget.php:61
36
+ msgid "Users Online Count"
37
+ msgstr "Látogató online szám"
 
38
 
39
+ #: widget.php:62
40
+ msgid "Users Browsing Current Page"
41
+ msgstr "Látogató böngészi az aktuális oldalt"
 
42
 
43
+ #: widget.php:63
44
+ msgid "Users Browsing Site"
45
+ msgstr "Látogató böngészi a lapot"
 
46
 
47
+ #: widget.php:65
48
+ msgid "Users Online Count & Users Browsing Current Page"
49
+ msgstr "Látogató online & Látogató böngészi az aktuális oldalt"
 
50
 
51
+ #: widget.php:66
52
+ msgid "Users Online Count & Users Browsing Site"
53
+ msgstr "Látogató online szám & Látogató böngészi a lapot"
 
54
 
55
+ #: admin.php:9
56
+ msgid "Users Online Now"
57
+ msgstr "Jelenlegi látogató"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
+ #: admin.php:10
60
+ #: wp-stats.php:14
61
+ #: wp-stats.php:31
62
+ msgid "WP-UserOnline"
63
+ msgstr "WP-UserOnline"
 
64
 
65
+ #: admin.php:26
66
+ msgid "There is <strong><a href='%s'>%s user</a></strong> online now."
67
+ msgid_plural "There are a total of <strong><a href='%s'>%s users</a></strong> online now."
68
+ msgstr[0] "Jelenleg <strong><a href='%s'>%s látogató</a></strong> van a honlapon."
69
+ msgstr[1] "Jelenleg <strong><a href='%s'>%s látogató</a></strong> van a honlapon."
70
 
71
+ #: admin.php:55
72
+ msgid "UserOnline Options"
73
+ msgstr "UserOnline lehetőségek"
74
 
75
+ #: admin.php:114
76
  msgid "Time Out"
77
  msgstr "Időtúllépés"
78
 
79
+ #: admin.php:117
80
+ msgid "How long until it will remove the user from the database (in seconds)."
81
+ msgstr "Mennyi idő múlva távolítjuk el a felhasználót az adatbázisból (másodpercben)?"
82
 
83
+ #: admin.php:122
84
  msgid "UserOnline URL"
85
  msgstr "UserOnline URL"
86
 
87
+ #: admin.php:125
88
+ msgid "URL To UserOnline Page<br />Example: http://www.yoursite.com/useronline/<br />Example: http://www.yoursite.com/?page_id=2"
89
+ msgstr "URL az UserOnline oldalhoz<br />Például: http://www.teoldalad.hu/useronline/<br />Például: http://www.yoursite.com/?page_id=2"
90
+
91
+ #: admin.php:129
92
+ msgid "User Names"
93
+ msgstr "Látogató neve"
94
+
95
+ #: admin.php:132
96
+ msgid "Link user names to their author page"
97
+ msgstr "A felhasználó nevéhez link a honlapjához"
98
+
99
+ #: admin.php:151
100
+ msgid "Useronline Templates"
101
+ msgstr "UserOnline sablon"
102
+
103
+ #: admin.php:163
104
+ msgid "User(s) Browsing Site:"
105
+ msgstr "Látogató böngészi a lapot:"
106
 
107
+ #: admin.php:164
108
+ msgid "User(s) Browsing Page:"
109
+ msgstr "Látogató böngészi az oldalt:"
110
 
111
+ #: admin.php:177
112
+ #: scb/AdminPage.php:177
113
+ #: scb/AdminPage.php:187
114
+ msgid "Save Changes"
115
+ msgstr "Változások mentése"
116
 
117
+ #: admin.php:187
118
  msgid "Naming Conventions:"
119
  msgstr "Elnevezési szabályok:"
120
 
121
+ #: admin.php:188
122
+ #: admin.php:228
123
+ #: admin.php:250
124
  msgid "Allowed Variables:"
125
  msgstr "Engedélyezett variációk:"
126
 
127
+ #: admin.php:190
128
+ msgid "Restore Defaults"
129
+ msgstr "Alapállapot visszaállítása"
 
 
130
 
131
+ #: admin.php:196
132
  msgid "Singular Form"
133
  msgstr "Egyes számú forma"
134
 
135
+ #: admin.php:197
136
  msgid "Plural Form"
137
  msgstr "Többes számú forma"
138
 
139
+ #: admin.php:227
 
 
 
 
140
  msgid "User(s) Online:"
141
  msgstr "Látogató(k) online:"
142
 
143
+ #: admin.php:233
144
+ #: admin.php:258
145
+ msgid "Restore Default Template"
146
+ msgstr "Alapsablon visszaállítása"
 
 
 
 
 
 
 
 
 
147
 
148
+ #: admin.php:264
149
  msgid "Member Names Separator"
150
  msgstr "Tagnév elválasztó"
151
 
152
+ #: admin.php:265
153
  msgid "Guests Separator"
154
  msgstr "Vendég elválasztó"
155
 
156
+ #: admin.php:266
157
  msgid "Bots Separator"
158
  msgstr "Robot elválasztó"
159
 
160
+ #: wp-stats.php:23
 
 
 
 
 
 
 
 
 
161
  msgid "<strong>%s</strong> user online now."
162
  msgid_plural "<strong>%s</strong> users online now."
163
+ msgstr[0] "<strong>%s</strong> látogató online."
164
+ msgstr[1] "<strong>%s</strong> látogató online."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
+ #: template-tags.php:80
 
167
  msgid "There is <strong>%s</strong> online now: <strong>%s</strong>, <strong>%s</strong> and <strong>%s</strong>."
168
  msgid_plural "There are a total of <strong>%s</strong> online now: <strong>%s</strong>, <strong>%s</strong> and <strong>%s</strong>."
169
+ msgstr[0] "<strong>%s</strong> látogató online: <strong>%s</strong>, <strong>%s</strong>, és <strong>%s</strong>."
170
+ msgstr[1] "<strong>%s</strong> látogató online: <strong>%s</strong>, <strong>%s</strong>, és <strong>%s</strong>"
171
 
172
+ #: template-tags.php:190
173
+ msgid "No one is online now."
174
+ msgstr "Jelenleg nincs látogató a honlapon."
175
 
176
+ #: template-tags.php:192
177
  msgid "on"
178
  msgstr " - "
179
 
180
+ #: template-tags.php:193
181
  msgid "url"
182
  msgstr "url"
183
 
184
+ #: template-tags.php:194
185
  msgid "referral"
186
  msgstr "azonosítva"
187
 
188
+ #: template-tags.php:205
189
  msgid "Online Now"
190
+ msgstr "online"
191
 
192
+ #: template-tags.php:247
193
+ #: template-tags.php:249
194
  msgid "%s @ %s"
195
  msgstr "%s - %s"
196
 
197
+ #: template-tags.php:269
 
198
  msgid "Most users ever online were <strong>%s</strong>, on <strong>%s</strong>"
199
+ msgstr "A legtöbb látógató egyidőben <strong>%s</strong> volt, <strong>%s</strong>-kor."
200
 
201
+ #: core.php:137
202
+ msgid "Guest"
203
+ msgstr "Vendég"
204
 
205
+ #: core.php:208
206
+ msgid "Admin"
207
+ msgstr "Admin"
208
 
209
+ #: core.php:214
210
+ msgid "Archive"
211
+ msgstr "Archívum"
212
 
213
+ #: wp-useronline.php:61
214
+ msgid "1 User"
215
+ msgstr "1 látogató"
216
 
217
+ #: wp-useronline.php:62
218
+ msgid "%COUNT% Users"
219
+ msgstr "%COUNT% látogató"
220
 
221
+ #: wp-useronline.php:63
222
+ msgid "1 Member"
223
+ msgstr "1 tag"
224
 
225
+ #: wp-useronline.php:64
226
+ msgid "%COUNT% Members"
227
+ msgstr "%COUNT% tag"
228
 
229
+ #: wp-useronline.php:65
230
+ msgid "1 Guest"
231
+ msgstr "1 vendég"
232
+
233
+ #: wp-useronline.php:66
234
+ msgid "%COUNT% Guests"
235
+ msgstr "%COUNT% vendég"
236
+
237
+ #: wp-useronline.php:67
238
+ msgid "1 Bot"
239
+ msgstr "1 robot"
240
+
241
+ #: wp-useronline.php:68
242
+ msgid "%COUNT% Bots"
243
+ msgstr "%COUNT% robot"
244
+
245
+ #: wp-useronline.php:72
246
+ msgid "Online"
247
+ msgstr "online"
248
+
249
+ #: wp-useronline.php:76
250
+ #: wp-useronline.php:77
251
+ #: wp-useronline.php:78
252
+ #: wp-useronline.php:85
253
+ #: wp-useronline.php:86
254
+ #: wp-useronline.php:87
255
+ msgid ","
256
+ msgstr ","
257
 
258
+ #: wp-useronline.php:80
259
+ #: wp-useronline.php:89
260
+ msgctxt "Template Element"
261
+ msgid "Users"
262
+ msgstr "Látogató"
263
 
264
+ #: wp-useronline.php:89
265
+ msgid "Browsing This Page."
266
+ msgstr "böngészi ezt az oldalt"
267
 
268
+ #: scb/AdminPage.php:165
269
+ msgid "Settings <strong>saved</strong>."
270
+ msgstr "A beállítások <strong>elmentve</strong>!"
271
 
272
+ #: scb/AdminPage.php:369
273
+ msgid "Settings"
274
+ msgstr "Beállítások"
275
 
276
+ #~ msgid "http://wordpress.org/extend/plugins/wp-useronline/"
277
+ #~ msgstr "http://wordpress.org/extend/plugins/wp-useronline/"
278
+ #~ msgid ""
279
+ #~ "Enable you to display how many users are online on your Wordpress site"
280
+ #~ msgstr ""
281
+ #~ "Megjeleníti a WordPress-alapú honlapon éppen jelenlévő látogatók számát."
282
+ #~ msgid "Lester 'GaMerZ' Chan & scribu"
283
+ #~ msgstr "Lester 'GaMerZ' Chan & scribu"
284
+ #~ msgid "Users|Template Element"
285
+ #~ msgstr "Felhasználó|Sablon elem"
286
+ #~ msgid "Settings updated."
287
+ #~ msgstr "Beállítások frissítve"
288
+ #~ msgid "Bots Name/User Agent"
289
+ #~ msgstr "Robot neve/Robotként bejelentkező"
290
+ #~ msgid ""
291
+ #~ "Here are a list of bots and their partial browser agents.<br />On the "
292
+ #~ "left column will be the <strong>Bot's Name</strong> and on the right "
293
+ #~ "column will be their <strong>Partial Browser Agent</strong>.<br />Start "
294
+ #~ "each entry on a new line."
295
+ #~ msgstr ""
296
+ #~ "Itt egy lista a robotokról, és az ő részleges kereső ügynökeiről.<br />A "
297
+ #~ "bal oldali oszlopban a <strong>Robot neve</strong>, és a jobb oldaliban "
298
+ #~ "az ő <strong>Részleges kereső ügynöke</strong><br />Mindegyiket új sorban "
299
+ #~ "kell kezdeni."
300
+ #~ msgid "guest"
301
+ #~ msgstr "vendég"
302
+ #~ msgid "User"
303
+ #~ msgstr "látogató"
304
+ #~ msgid "Member"
305
+ #~ msgstr "tag"
306
+ #~ msgid "Members"
307
+ #~ msgstr "tag"
308
+ #~ msgid "Guests"
309
+ #~ msgstr "vendég"
310
+ #~ msgid "Bot"
311
+ #~ msgstr "robot"
312
+ #~ msgid "Bots"
313
+ #~ msgstr "robot"
314
+ #~ msgid "http://lesterchan.net"
315
+ #~ msgstr "http://lesterchan.net"
316
+ #~ msgid "http://lesterchan.net/portfolio/programming/php/"
317
+ #~ msgstr "http://lesterchan.net/portfolio/programming/php/"
318
  #~ msgid "Useronline Timeout"
319
  #~ msgstr "Useronline időtúllépés"
320
  #~ msgid "Useronline Bots"
readme.txt CHANGED
@@ -1,21 +1,20 @@
1
  === WP-UserOnline ===
2
- Contributors: GamerZ, scribu
3
- Tags: useronline, usersonline, wp-useronline, online, users, user, ajax, widget
4
- Requires at least: 3.1
5
- Tested up to: 3.5
6
- Stable tag: 2.82
7
- License: GPLv2 or later
8
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
  Enable you to display how many users are online on your Wordpress blog with detailed statistics.
11
 
12
  == Description ==
13
 
14
- **PHP 5 is required since version 2.60.**
15
-
16
  This plugin enables you to display how many users are online on your Wordpress site, with detailed statistics of where they are and who they are (Members/Guests/Search Bots).
17
 
18
- Links: [Plugin News](http://scribu.net/wordpress/wp-useronline) | [Translating](http://scribu.net/wordpress/translating-plugins.html)
 
19
 
20
  == Installation ==
21
 
@@ -24,18 +23,13 @@ You can either install it automatically from the WordPress admin, or do it manua
24
  1. Unzip the archive and put the `wp-useronline` folder into your plugins folder (/wp-content/plugins/).
25
  1. Activate the plugin from the Plugins menu.
26
 
27
- = Usage =
28
-
29
- **General Usage (With Widget)**
30
-
31
  1. Go to `WP-Admin -> Appearance -> Widgets`
32
  1. The widget name is <strong>UserOnline</strong>.
33
  1. Scroll down for instructions on how to create a *UserOnline Page*.
34
 
35
-
36
- **General Usage (Without Widget)**
37
-
38
- Open `wp-content/themes/<YOUR THEME NAME>/sidebar.php` and add Anywhere:
39
 
40
  `
41
  <?php if (function_exists('users_online')): ?>
@@ -43,60 +37,62 @@ Open `wp-content/themes/<YOUR THEME NAME>/sidebar.php` and add Anywhere:
43
  <?php endif; ?>
44
  `
45
 
46
- **UserOnline Page**
47
-
48
  1. Go to `WP-Admin -> Pages -> Add New`
49
  1. Type any title you like in the post's title area
50
- 1. If you **ARE** using nice permalinks, after typing the title, WordPress will generate the permalink to the page. You will see an 'Edit' link just beside the permalink.
51
  1. Click 'Edit' and type in `useronline` in the text field and click 'Save'.
52
  1. Type `[page_useronline]` in the post's content area
53
  1. Click 'Publish'
54
 
55
- If you **ARE NOT** using nice permalinks, you need to go to `WP-Admin -> Settings -> UserOnline` and under 'UserOnline URL', you need to fill in the URL to the UserOnline Page you created above.
56
 
57
- **UserOnline Stats (Outside WP Loop)**
 
 
 
 
58
 
59
- To Display *Most Number Of Users Online* use:
60
 
 
 
61
  `
62
  <?php if (function_exists('get_most_users_online')): ?>
63
  <p>Most Users Ever Online Is <?php echo get_most_users_online(); ?> On <?php echo get_most_users_online_date(); ?></p>
64
  <?php endif; ?>
65
  `
66
 
67
- To Display *Users Browsing Site* use:
68
-
69
  `
70
  <?php if (function_exists('get_users_browsing_site')): ?>
71
  <div id="useronline-browsing-site"><?php echo get_users_browsing_site(); ?></div>
72
  <?php endif; ?>
73
  `
74
 
75
- To Display *Users Browsing A Page* use:
76
-
77
  `
78
  <?php if (function_exists('get_users_browsing_page')): ?>
79
  <div id="useronline-browsing-page"><?php echo get_users_browsing_page(); ?></div>
80
  <?php endif; ?>
81
  `
82
 
83
- == Screenshots ==
84
-
85
- 1. Right Now text
86
- 2. Admin page
87
- 3. Settings page
88
-
89
- == Frequently Asked Questions ==
90
-
91
  = Error on activation: "Parse error: syntax error, unexpected..." =
92
 
93
  Make sure your host is running PHP 5. The only foolproof way to do this is to add this line to wp-config.php (after the opening `<?php` tag):
94
 
95
  `var_dump(PHP_VERSION);`
96
- <br>
97
 
98
  == Changelog ==
99
 
 
 
 
 
 
 
100
  = 2.82 =
101
  * show most recent visitors first
102
  * fix duplicate entry errors
@@ -244,4 +240,3 @@ Make sure your host is running PHP 5. The only foolproof way to do this is to ad
244
  * new: Page Title Added To wp-useronline.php
245
  * new: Added Extra Bots, Credit To Greg Perry (http://www.gregrperry.com/)
246
  * fixed: Cleaner Codes
247
-
1
  === WP-UserOnline ===
2
+ Contributors: GamerZ, scribu
3
+ Tags: useronline, usersonline, wp-useronline, online, users, user, ajax, widget
4
+ Requires at least: 3.1
5
+ Tested up to: 3.9
6
+ Stable tag: 2.83
7
+ License: GPLv2 or later
8
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
  Enable you to display how many users are online on your Wordpress blog with detailed statistics.
11
 
12
  == Description ==
13
 
 
 
14
  This plugin enables you to display how many users are online on your Wordpress site, with detailed statistics of where they are and who they are (Members/Guests/Search Bots).
15
 
16
+ = Development =
17
+ * [https://github.com/lesterchan/wp-useronline](https://github.com/lesterchan/wp-useronline "https://github.com/lesterchan/wp-useronline")
18
 
19
  == Installation ==
20
 
23
  1. Unzip the archive and put the `wp-useronline` folder into your plugins folder (/wp-content/plugins/).
24
  1. Activate the plugin from the Plugins menu.
25
 
26
+ = General Usage (With Widget) =
 
 
 
27
  1. Go to `WP-Admin -> Appearance -> Widgets`
28
  1. The widget name is <strong>UserOnline</strong>.
29
  1. Scroll down for instructions on how to create a *UserOnline Page*.
30
 
31
+ = General Usage (Without Widget) =
32
+ * Open `wp-content/themes/<YOUR THEME NAME>/sidebar.php` and add Anywhere:
 
 
33
 
34
  `
35
  <?php if (function_exists('users_online')): ?>
37
  <?php endif; ?>
38
  `
39
 
40
+ = Creating A UserOnline Page =
 
41
  1. Go to `WP-Admin -> Pages -> Add New`
42
  1. Type any title you like in the post's title area
43
+ 1. If you ARE using nice permalinks, after typing the title, WordPress will generate the permalink to the page. You will see an 'Edit' link just beside the permalink.
44
  1. Click 'Edit' and type in `useronline` in the text field and click 'Save'.
45
  1. Type `[page_useronline]` in the post's content area
46
  1. Click 'Publish'
47
 
48
+ If you ARE NOT using nice permalinks, you need to go to `WP-Admin -> Settings -> UserOnline` and under 'UserOnline URL', you need to fill in the URL to the UserOnline Page you created above.
49
 
50
+ == Screenshots ==
51
+
52
+ 1. Right Now text
53
+ 2. Admin page
54
+ 3. Settings page
55
 
56
+ == Frequently Asked Questions ==
57
 
58
+ = To Display Most Number Of Users Online =
59
+ * Use:
60
  `
61
  <?php if (function_exists('get_most_users_online')): ?>
62
  <p>Most Users Ever Online Is <?php echo get_most_users_online(); ?> On <?php echo get_most_users_online_date(); ?></p>
63
  <?php endif; ?>
64
  `
65
 
66
+ = To Display Users Browsing Site =
67
+ * Use:
68
  `
69
  <?php if (function_exists('get_users_browsing_site')): ?>
70
  <div id="useronline-browsing-site"><?php echo get_users_browsing_site(); ?></div>
71
  <?php endif; ?>
72
  `
73
 
74
+ = To Display Users Browsing A Page =
75
+ * Use:
76
  `
77
  <?php if (function_exists('get_users_browsing_page')): ?>
78
  <div id="useronline-browsing-page"><?php echo get_users_browsing_page(); ?></div>
79
  <?php endif; ?>
80
  `
81
 
 
 
 
 
 
 
 
 
82
  = Error on activation: "Parse error: syntax error, unexpected..." =
83
 
84
  Make sure your host is running PHP 5. The only foolproof way to do this is to add this line to wp-config.php (after the opening `<?php` tag):
85
 
86
  `var_dump(PHP_VERSION);`
 
87
 
88
  == Changelog ==
89
 
90
+ = 2.83 =
91
+ * Show user agent when hovering over IP, instead of address lookup
92
+ * Use local time for UserOnline Page
93
+ * Fixed 'Strict Standards: Non-static method' warnings
94
+ * Update scb Framework
95
+
96
  = 2.82 =
97
  * show most recent visitors first
98
  * fix duplicate entry errors
240
  * new: Page Title Added To wp-useronline.php
241
  * new: Added Extra Bots, Credit To Greg Perry (http://www.gregrperry.com/)
242
  * fixed: Cleaner Codes
 
scb/AdminPage.php CHANGED
@@ -1,13 +1,15 @@
1
  <?php
2
 
3
- // Administration page base class
4
-
 
5
  abstract class scbAdminPage {
6
  /** Page args
7
  * $page_title string (mandatory)
8
  * $parent (string) (default: options-general.php)
9
  * $capability (string) (default: 'manage_options')
10
  * $menu_title (string) (default: $page_title)
 
11
  * $page_slug (string) (default: sanitized $page_title)
12
  * $toplevel (string) If not empty, will create a new top level menu (for expected values see http://codex.wordpress.org/Administration_Menus#Using_add_submenu_page)
13
  * - $icon_url (string) URL to an icon for the top level menu
@@ -40,6 +42,13 @@ abstract class scbAdminPage {
40
 
41
  private static $registered = array();
42
 
 
 
 
 
 
 
 
43
  static function register( $class, $file, $options = null ) {
44
  if ( isset( self::$registered[$class] ) )
45
  return false;
@@ -51,6 +60,12 @@ abstract class scbAdminPage {
51
  return true;
52
  }
53
 
 
 
 
 
 
 
54
  static function replace( $old_class, $new_class ) {
55
  if ( ! isset( self::$registered[$old_class] ) )
56
  return false;
@@ -61,6 +76,11 @@ abstract class scbAdminPage {
61
  return true;
62
  }
63
 
 
 
 
 
 
64
  static function remove( $class ) {
65
  if ( ! isset( self::$registered[$class] ) )
66
  return false;
@@ -79,7 +99,12 @@ abstract class scbAdminPage {
79
  // ____________MAIN METHODS____________
80
 
81
 
82
- // Constructor
 
 
 
 
 
83
  function __construct( $file = false, $options = null ) {
84
  if ( is_a( $options, 'scbOptions' ) )
85
  $this->options = $options;
@@ -89,8 +114,7 @@ abstract class scbAdminPage {
89
 
90
  if ( isset( $this->option_name ) ) {
91
  add_action( 'admin_init', array( $this, 'option_init' ) );
92
- if ( function_exists( 'settings_errors' ) )
93
- add_action( 'admin_notices', 'settings_errors' );
94
  }
95
 
96
  add_action( 'admin_menu', array( $this, 'page_init' ), $this->args['admin_action_priority'] );
@@ -105,7 +129,9 @@ abstract class scbAdminPage {
105
  }
106
  }
107
 
108
- // This is where all the page args can be set
 
 
109
  function setup(){}
110
 
111
  /**
@@ -113,45 +139,68 @@ abstract class scbAdminPage {
113
  *
114
  * Useful for calling $screen->add_help_tab() etc.
115
  */
116
- function page_loaded() {}
 
 
117
 
118
- // This is where the css and js go
119
- // Both wp_enqueue_*() and inline code can be added
 
 
120
  function page_head(){}
121
 
122
- // This is where the contextual help goes
123
- // @return string
 
 
124
  function page_help(){}
125
 
126
- // A generic page header
 
 
127
  function page_header() {
128
  echo "<div class='wrap'>\n";
129
  screen_icon( $this->args['screen_icon'] );
130
- echo html( "h2", $this->args['page_title'] );
131
  }
132
 
133
- // This is where the page content goes
 
 
134
  abstract function page_content();
135
 
136
- // A generic page footer
 
 
137
  function page_footer() {
138
  echo "</div>\n";
139
  }
140
 
141
- // This is where the form data should be validated
 
 
 
 
 
 
 
142
  function validate( $new_data, $old_data ) {
143
  return $new_data;
144
  }
145
 
146
- // Manually handle option saving ( use Settings API instead )
 
 
 
 
147
  function form_handler() {
148
- if ( empty( $_POST['action'] ) )
149
  return false;
150
 
151
  check_admin_referer( $this->nonce );
152
 
153
  if ( !isset($this->options) ) {
154
- trigger_error('options handler not set', E_USER_WARNING);
155
  return false;
156
  }
157
 
@@ -163,11 +212,18 @@ abstract class scbAdminPage {
163
 
164
  $this->options->set( $new_data );
165
 
166
- $this->admin_msg();
 
 
167
  }
168
 
169
- // Manually generate a standard admin notice ( use Settings API instead )
170
- function admin_msg( $msg = '', $class = "updated" ) {
 
 
 
 
 
171
  if ( empty( $msg ) )
172
  $msg = __( 'Settings <strong>saved</strong>.', $this->textdomain );
173
 
@@ -178,52 +234,47 @@ abstract class scbAdminPage {
178
  // ____________UTILITIES____________
179
 
180
 
181
- // Generates a form submit button
182
- function submit_button( $value = '', $action = 'action', $class = "button" ) {
183
- if ( is_array( $value ) ) {
184
- extract( wp_parse_args( $value, array(
185
- 'value' => __( 'Save Changes', $this->textdomain ),
186
- 'action' => 'action',
187
- 'class' => 'button',
188
- 'ajax' => true
189
- ) ) );
190
-
191
- if ( ! $ajax )
192
- $class .= ' no-ajax';
193
- }
194
- else {
195
- if ( empty( $value ) )
196
- $value = __( 'Save Changes', $this->textdomain );
197
- }
198
-
199
- $input_args = array(
200
- 'type' => 'submit',
201
- 'name' => $action,
202
- 'value' => $value,
203
- 'extra' => '',
204
- 'desc' => false,
205
- 'wrap' => html( 'p class="submit"', scbForms::TOKEN )
206
- );
207
 
208
- if ( ! empty( $class ) )
209
- $input_args['extra'] = compact( 'class' );
 
 
 
 
210
 
211
- return scbForms::input( $input_args );
212
  }
213
 
214
- /*
215
- Mimics scbForms::form_wrap()
216
-
217
- $this->form_wrap( $content ); // generates a form with a default submit button
218
-
219
- $this->form_wrap( $content, false ); // generates a form with no submit button
220
-
221
- // the second argument is sent to submit_button()
222
- $this->form_wrap( $content, array( 'text' => 'Save changes',
223
- 'name' => 'action',
224
- 'ajax' => true,
225
- ) );
226
- */
 
 
 
 
 
 
 
227
  function form_wrap( $content, $submit_button = true ) {
228
  if ( is_array( $submit_button ) ) {
229
  $content .= $this->submit_button( $submit_button );
@@ -231,15 +282,24 @@ abstract class scbAdminPage {
231
  $content .= $this->submit_button();
232
  } elseif ( false !== strpos( $submit_button, '<input' ) ) {
233
  $content .= $submit_button;
 
 
234
  } elseif ( false !== $submit_button ) {
235
  $button_args = array_slice( func_get_args(), 1 );
236
- $content .= call_user_func_array( array( $this, 'submit_button' ), $button_args );
237
  }
238
 
239
  return scbForms::form_wrap( $content, $this->nonce );
240
  }
241
 
242
- // Generates a table wrapped in a form
 
 
 
 
 
 
 
243
  function form_table( $rows, $formdata = false ) {
244
  $output = '';
245
  foreach ( $rows as $row )
@@ -250,7 +310,13 @@ abstract class scbAdminPage {
250
  return $output;
251
  }
252
 
253
- // Wraps the given content in a <form><table>
 
 
 
 
 
 
254
  function form_table_wrap( $content ) {
255
  $output = $this->table_wrap( $content );
256
  $output = $this->form_wrap( $output );
@@ -258,7 +324,14 @@ abstract class scbAdminPage {
258
  return $output;
259
  }
260
 
261
- // Generates a form table
 
 
 
 
 
 
 
262
  function table( $rows, $formdata = false ) {
263
  $output = '';
264
  foreach ( $rows as $row )
@@ -269,12 +342,28 @@ abstract class scbAdminPage {
269
  return $output;
270
  }
271
 
272
- // Generates a table row
 
 
 
 
 
 
 
273
  function table_row( $args, $formdata = false ) {
274
  return $this->row_wrap( $args['title'], $this->input( $args, $formdata ) );
275
  }
276
 
277
- // Mimic scbForms inheritance
 
 
 
 
 
 
 
 
 
278
  function __call( $method, $args ) {
279
  if ( in_array( $method, array( 'input', 'form' ) ) ) {
280
  if ( empty( $args[1] ) && isset( $this->options ) )
@@ -287,12 +376,24 @@ abstract class scbAdminPage {
287
  return call_user_func_array( array( 'scbForms', $method ), $args );
288
  }
289
 
290
- // Wraps a string in a <script> tag
 
 
 
 
 
 
291
  function js_wrap( $string ) {
292
  return html( "script type='text/javascript'", $string );
293
  }
294
 
295
- // Wraps a string in a <style> tag
 
 
 
 
 
 
296
  function css_wrap( $string ) {
297
  return html( "style type='text/css'", $string );
298
  }
@@ -301,15 +402,40 @@ abstract class scbAdminPage {
301
  // ____________INTERNAL METHODS____________
302
 
303
 
304
- // Registers a page
 
 
305
  function page_init() {
306
- extract( $this->args );
307
 
308
- if ( ! $toplevel ) {
309
- $this->pagehook = add_submenu_page( $parent, $page_title, $menu_title, $capability, $page_slug, array( $this, '_page_content_hook' ) );
 
 
 
 
 
 
 
310
  } else {
311
- $func = 'add_' . $toplevel . '_page';
312
- $this->pagehook = $func( $page_title, $menu_title, $capability, $page_slug, array( $this, '_page_content_hook' ), $icon_url, $position );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  }
314
 
315
  if ( ! $this->pagehook )
@@ -317,11 +443,6 @@ abstract class scbAdminPage {
317
 
318
  add_action( 'load-' . $this->pagehook, array( $this, 'page_loaded' ) );
319
 
320
- if ( $ajax_submit ) {
321
- $this->ajax_response();
322
- add_action( 'admin_footer', array( $this, 'ajax_submit' ), 20 );
323
- }
324
-
325
  add_action( 'admin_print_styles-' . $this->pagehook, array( $this, 'page_head' ) );
326
  }
327
 
@@ -334,20 +455,22 @@ abstract class scbAdminPage {
334
  trigger_error( 'Page title cannot be empty', E_USER_WARNING );
335
 
336
  $this->args = wp_parse_args( $this->args, array(
337
- 'toplevel' => '',
338
- 'position' => null,
339
- 'icon_url' => '',
340
- 'screen_icon' => '',
341
- 'parent' => 'options-general.php',
342
- 'capability' => 'manage_options',
343
- 'menu_title' => $this->args['page_title'],
344
- 'page_slug' => '',
345
- 'nonce' => '',
346
- 'action_link' => __( 'Settings', $this->textdomain ),
347
- 'ajax_submit' => false,
348
  'admin_action_priority' => 10,
349
  ) );
350
 
 
 
 
351
  if ( empty( $this->args['page_slug'] ) )
352
  $this->args['page_slug'] = sanitize_title_with_dashes( $this->args['menu_title'] );
353
 
@@ -355,6 +478,12 @@ abstract class scbAdminPage {
355
  $this->nonce = $this->args['page_slug'];
356
  }
357
 
 
 
 
 
 
 
358
  function _contextual_help( $help, $screen ) {
359
  if ( is_object( $screen ) )
360
  $screen = $screen->id;
@@ -367,67 +496,17 @@ abstract class scbAdminPage {
367
  return $help;
368
  }
369
 
370
- function ajax_response() {
371
- if ( ! isset( $_POST['_ajax_submit'] ) || $_POST['_ajax_submit'] != $this->pagehook )
372
- return;
373
-
374
- $this->form_handler();
375
- die;
376
- }
377
-
378
- function ajax_submit() {
379
- global $page_hook;
380
-
381
- if ( $page_hook != $this->pagehook )
382
- return;
383
- ?>
384
- <script type="text/javascript">
385
- jQuery( document ).ready( function( $ ){
386
- var $spinner = $( new Image() ).attr( 'src', '<?php echo admin_url( "images/wpspin_light.gif" ); ?>' );
387
-
388
- $( ':submit' ).click( function( ev ){
389
- var $submit = $( this );
390
- var $form = $submit.parents( 'form' );
391
-
392
- if ( $submit.hasClass( 'no-ajax' ) || $form.attr( 'method' ).toLowerCase() != 'post' )
393
- return true;
394
-
395
- var $this_spinner = $spinner.clone();
396
-
397
- $submit.before( $this_spinner ).hide();
398
-
399
- var data = $form.serializeArray();
400
- data.push( {name: $submit.attr( 'name' ), value: $submit.val()} );
401
- data.push( {name: '_ajax_submit', value: '<?php echo $this->pagehook; ?>'} );
402
-
403
- $.post( location.href, data, function( response ){
404
- var $prev = $( '.wrap > .updated, .wrap > .error' );
405
- var $msg = $( response ).hide().insertAfter( $( '.wrap h2' ) );
406
- if ( $prev.length > 0 )
407
- $prev.fadeOut( 'slow', function(){ $msg.fadeIn( 'slow' ); } );
408
- else
409
- $msg.fadeIn( 'slow' );
410
-
411
- $this_spinner.hide();
412
- $submit.show();
413
- } );
414
-
415
- ev.stopPropagation();
416
- ev.preventDefault();
417
- } );
418
- } );
419
- </script>
420
- <?php
421
- }
422
-
423
  function _page_content_hook() {
424
- $this->form_handler();
425
-
426
  $this->page_header();
427
  $this->page_content();
428
  $this->page_footer();
429
  }
430
 
 
 
 
 
 
431
  function _action_link( $links ) {
432
  $url = add_query_arg( 'page', $this->args['page_slug'], admin_url( $this->args['parent'] ) );
433
 
1
  <?php
2
 
3
+ /**
4
+ * Administration page base class
5
+ */
6
  abstract class scbAdminPage {
7
  /** Page args
8
  * $page_title string (mandatory)
9
  * $parent (string) (default: options-general.php)
10
  * $capability (string) (default: 'manage_options')
11
  * $menu_title (string) (default: $page_title)
12
+ * $submenu_title (string) (default: $menu_title)
13
  * $page_slug (string) (default: sanitized $page_title)
14
  * $toplevel (string) If not empty, will create a new top level menu (for expected values see http://codex.wordpress.org/Administration_Menus#Using_add_submenu_page)
15
  * - $icon_url (string) URL to an icon for the top level menu
42
 
43
  private static $registered = array();
44
 
45
+ /**
46
+ * @param string $class
47
+ * @param string $file
48
+ * @param scbOptions $options
49
+ *
50
+ * @return bool
51
+ */
52
  static function register( $class, $file, $options = null ) {
53
  if ( isset( self::$registered[$class] ) )
54
  return false;
60
  return true;
61
  }
62
 
63
+ /**
64
+ * @param string $old_class
65
+ * @param string $new_class
66
+ *
67
+ * @return bool
68
+ */
69
  static function replace( $old_class, $new_class ) {
70
  if ( ! isset( self::$registered[$old_class] ) )
71
  return false;
76
  return true;
77
  }
78
 
79
+ /**
80
+ * @param string $class
81
+ *
82
+ * @return bool
83
+ */
84
  static function remove( $class ) {
85
  if ( ! isset( self::$registered[$class] ) )
86
  return false;
99
  // ____________MAIN METHODS____________
100
 
101
 
102
+ /**
103
+ * Constructor
104
+ *
105
+ * @param string|bool $file
106
+ * @param scbOptions $options
107
+ */
108
  function __construct( $file = false, $options = null ) {
109
  if ( is_a( $options, 'scbOptions' ) )
110
  $this->options = $options;
114
 
115
  if ( isset( $this->option_name ) ) {
116
  add_action( 'admin_init', array( $this, 'option_init' ) );
117
+ add_action( 'admin_notices', 'settings_errors' );
 
118
  }
119
 
120
  add_action( 'admin_menu', array( $this, 'page_init' ), $this->args['admin_action_priority'] );
129
  }
130
  }
131
 
132
+ /**
133
+ * This is where all the page args can be set
134
+ */
135
  function setup(){}
136
 
137
  /**
139
  *
140
  * Useful for calling $screen->add_help_tab() etc.
141
  */
142
+ function page_loaded() {
143
+ $this->form_handler();
144
+ }
145
 
146
+ /**
147
+ * This is where the css and js go
148
+ * Both wp_enqueue_*() and inline code can be added
149
+ */
150
  function page_head(){}
151
 
152
+ /**
153
+ * This is where the contextual help goes
154
+ * @return string
155
+ */
156
  function page_help(){}
157
 
158
+ /**
159
+ * A generic page header
160
+ */
161
  function page_header() {
162
  echo "<div class='wrap'>\n";
163
  screen_icon( $this->args['screen_icon'] );
164
+ echo html( 'h2', $this->args['page_title'] );
165
  }
166
 
167
+ /**
168
+ * This is where the page content goes
169
+ */
170
  abstract function page_content();
171
 
172
+ /**
173
+ * A generic page footer
174
+ */
175
  function page_footer() {
176
  echo "</div>\n";
177
  }
178
 
179
+ /**
180
+ * This is where the form data should be validated
181
+ *
182
+ * @param array $new_data
183
+ * @param array $old_data
184
+ *
185
+ * @return array
186
+ */
187
  function validate( $new_data, $old_data ) {
188
  return $new_data;
189
  }
190
 
191
+ /**
192
+ * Manually handle option saving ( use Settings API instead )
193
+ *
194
+ * @return bool
195
+ */
196
  function form_handler() {
197
+ if ( empty( $_POST['submit'] ) && empty( $_POST['action'] ) )
198
  return false;
199
 
200
  check_admin_referer( $this->nonce );
201
 
202
  if ( !isset($this->options) ) {
203
+ trigger_error( 'options handler not set', E_USER_WARNING );
204
  return false;
205
  }
206
 
212
 
213
  $this->options->set( $new_data );
214
 
215
+ add_action( 'admin_notices', array( $this, 'admin_msg' ) );
216
+
217
+ return true;
218
  }
219
 
220
+ /**
221
+ * Manually generate a standard admin notice ( use Settings API instead )
222
+ *
223
+ * @param string $msg
224
+ * @param string $class
225
+ */
226
+ function admin_msg( $msg = '', $class = 'updated' ) {
227
  if ( empty( $msg ) )
228
  $msg = __( 'Settings <strong>saved</strong>.', $this->textdomain );
229
 
234
  // ____________UTILITIES____________
235
 
236
 
237
+ /**
238
+ * Generates a form submit button
239
+ *
240
+ * @param string|array $value button text or array of arguments
241
+ * @param string $action
242
+ * @param string $class
243
+ *
244
+ * @return string
245
+ */
246
+ function submit_button( $value = '', $action = 'submit', $class = 'button' ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
 
248
+ $args = is_array( $value ) ? $value : compact( 'value', 'action', 'class' );
249
+ $args = wp_parse_args( $args, array(
250
+ 'value' => null,
251
+ 'action' => $action,
252
+ 'class' => $class,
253
+ ) );
254
 
255
+ return get_submit_button( $args['value'], $args['class'], $args['action'] );
256
  }
257
 
258
+ /**
259
+ * Mimics scbForms::form_wrap()
260
+ *
261
+ * $this->form_wrap( $content ); // generates a form with a default submit button
262
+ *
263
+ * $this->form_wrap( $content, false ); // generates a form with no submit button
264
+ *
265
+ * // the second argument is sent to submit_button()
266
+ * $this->form_wrap( $content, array(
267
+ * 'text' => 'Save changes',
268
+ * 'name' => 'action',
269
+ * ) );
270
+ *
271
+ * @see scbForms::form_wrap()
272
+ *
273
+ * @param string $content
274
+ * @param boolean|string|array $submit_button
275
+ *
276
+ * @return string
277
+ */
278
  function form_wrap( $content, $submit_button = true ) {
279
  if ( is_array( $submit_button ) ) {
280
  $content .= $this->submit_button( $submit_button );
282
  $content .= $this->submit_button();
283
  } elseif ( false !== strpos( $submit_button, '<input' ) ) {
284
  $content .= $submit_button;
285
+ } elseif ( false !== strpos( $submit_button, '<button' ) ) {
286
+ $content .= $submit_button;
287
  } elseif ( false !== $submit_button ) {
288
  $button_args = array_slice( func_get_args(), 1 );
289
+ $content .= call_user_func_array( array( $this, 'submit_button' ), $button_args );
290
  }
291
 
292
  return scbForms::form_wrap( $content, $this->nonce );
293
  }
294
 
295
+ /**
296
+ * Generates a table wrapped in a form
297
+ *
298
+ * @param array $rows
299
+ * @param array|boolean $formdata
300
+ *
301
+ * @return string
302
+ */
303
  function form_table( $rows, $formdata = false ) {
304
  $output = '';
305
  foreach ( $rows as $row )
310
  return $output;
311
  }
312
 
313
+ /**
314
+ * Wraps the given content in a <form><table>
315
+ *
316
+ * @param string $content
317
+ *
318
+ * @return string
319
+ */
320
  function form_table_wrap( $content ) {
321
  $output = $this->table_wrap( $content );
322
  $output = $this->form_wrap( $output );
324
  return $output;
325
  }
326
 
327
+ /**
328
+ * Generates a form table
329
+ *
330
+ * @param array $rows
331
+ * @param array|boolean $formdata
332
+ *
333
+ * @return string
334
+ */
335
  function table( $rows, $formdata = false ) {
336
  $output = '';
337
  foreach ( $rows as $row )
342
  return $output;
343
  }
344
 
345
+ /**
346
+ * Generates a table row
347
+ *
348
+ * @param array $args
349
+ * @param array|boolean $formdata
350
+ *
351
+ * @return string
352
+ */
353
  function table_row( $args, $formdata = false ) {
354
  return $this->row_wrap( $args['title'], $this->input( $args, $formdata ) );
355
  }
356
 
357
+ /**
358
+ * Mimic scbForms inheritance
359
+ *
360
+ * @see scbForms
361
+ *
362
+ * @param string $method
363
+ * @param array $args
364
+ *
365
+ * @return mixed
366
+ */
367
  function __call( $method, $args ) {
368
  if ( in_array( $method, array( 'input', 'form' ) ) ) {
369
  if ( empty( $args[1] ) && isset( $this->options ) )
376
  return call_user_func_array( array( 'scbForms', $method ), $args );
377
  }
378
 
379
+ /**
380
+ * Wraps a string in a <script> tag
381
+ *
382
+ * @param string $string
383
+ *
384
+ * @return string
385
+ */
386
  function js_wrap( $string ) {
387
  return html( "script type='text/javascript'", $string );
388
  }
389
 
390
+ /**
391
+ * Wraps a string in a <style> tag
392
+ *
393
+ * @param string $string
394
+ *
395
+ * @return string
396
+ */
397
  function css_wrap( $string ) {
398
  return html( "style type='text/css'", $string );
399
  }
402
  // ____________INTERNAL METHODS____________
403
 
404
 
405
+ /**
406
+ * Registers a page
407
+ */
408
  function page_init() {
 
409
 
410
+ if ( ! $this->args['toplevel'] ) {
411
+ $this->pagehook = add_submenu_page(
412
+ $this->args['parent'],
413
+ $this->args['page_title'],
414
+ $this->args['menu_title'],
415
+ $this->args['capability'],
416
+ $this->args['page_slug'],
417
+ array( $this, '_page_content_hook' )
418
+ );
419
  } else {
420
+ $func = 'add_' . $this->args['toplevel'] . '_page';
421
+ $this->pagehook = $func(
422
+ $this->args['page_title'],
423
+ $this->args['menu_title'],
424
+ $this->args['capability'],
425
+ $this->args['page_slug'],
426
+ null,
427
+ $this->args['icon_url'],
428
+ $this->args['position']
429
+ );
430
+
431
+ add_submenu_page(
432
+ $this->args['page_slug'],
433
+ $this->args['page_title'],
434
+ $this->args['submenu_title'],
435
+ $this->args['capability'],
436
+ $this->args['page_slug'],
437
+ array( $this, '_page_content_hook' )
438
+ );
439
  }
440
 
441
  if ( ! $this->pagehook )
443
 
444
  add_action( 'load-' . $this->pagehook, array( $this, 'page_loaded' ) );
445
 
 
 
 
 
 
446
  add_action( 'admin_print_styles-' . $this->pagehook, array( $this, 'page_head' ) );
447
  }
448
 
455
  trigger_error( 'Page title cannot be empty', E_USER_WARNING );
456
 
457
  $this->args = wp_parse_args( $this->args, array(
458
+ 'toplevel' => '',
459
+ 'position' => null,
460
+ 'icon_url' => '',
461
+ 'screen_icon' => '',
462
+ 'parent' => 'options-general.php',
463
+ 'capability' => 'manage_options',
464
+ 'menu_title' => $this->args['page_title'],
465
+ 'page_slug' => '',
466
+ 'nonce' => '',
467
+ 'action_link' => __( 'Settings', $this->textdomain ),
 
468
  'admin_action_priority' => 10,
469
  ) );
470
 
471
+ if ( empty( $this->args['submenu_title'] ) )
472
+ $this->args['submenu_title'] = $this->args['menu_title'];
473
+
474
  if ( empty( $this->args['page_slug'] ) )
475
  $this->args['page_slug'] = sanitize_title_with_dashes( $this->args['menu_title'] );
476
 
478
  $this->nonce = $this->args['page_slug'];
479
  }
480
 
481
+ /**
482
+ * @param string $help
483
+ * @param string|object $screen
484
+ *
485
+ * @return string
486
+ */
487
  function _contextual_help( $help, $screen ) {
488
  if ( is_object( $screen ) )
489
  $screen = $screen->id;
496
  return $help;
497
  }
498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
  function _page_content_hook() {
 
 
500
  $this->page_header();
501
  $this->page_content();
502
  $this->page_footer();
503
  }
504
 
505
+ /**
506
+ * @param array $links
507
+ *
508
+ * @return array
509
+ */
510
  function _action_link( $links ) {
511
  $url = add_query_arg( 'page', $this->args['page_slug'], admin_url( $this->args['parent'] ) );
512
 
scb/BoxesPage.php CHANGED
@@ -166,35 +166,55 @@ abstract class scbBoxesPage extends scbAdminPage {
166
  ) );
167
 
168
  $registered = array();
 
169
  foreach ( $this->boxes as $box_args ) {
170
- foreach ( array( 'name', 'title', 'context', 'priority', 'args' ) as $i => $arg ) {
171
- if ( isset( $box_args[$i] ) )
172
- $$arg = $box_args[$i];
173
- }
 
 
 
 
 
174
 
175
- if ( empty( $title ) )
176
- $title = ucfirst( $name );
177
- if ( empty( $context ) )
178
- $context = 'normal';
179
- if ( empty( $priority ) )
180
- $priority = 'default';
181
- if ( empty( $args ) )
182
- $args = array();
183
-
184
- if ( isset( $registered[$name] ) ) {
185
- if ( empty( $args ) )
186
  trigger_error( "Duplicate box name: $name", E_USER_NOTICE );
 
187
 
188
  $name = $this->_increment( $name );
189
  } else {
190
- $registered[$name] = true;
191
  }
192
 
193
- add_meta_box( $name, $title, array( $this, '_intermediate_callback' ), $this->pagehook, $context, $priority, $args );
 
 
 
 
 
 
 
 
194
  }
195
  }
196
 
197
- // Make it so that $args is actually what's passed to the callback
 
 
 
 
 
 
 
 
 
 
 
 
198
  function _intermediate_callback( $_, $box ) {
199
  list( $name ) = explode( '-', $box['id'] );
200
 
166
  ) );
167
 
168
  $registered = array();
169
+
170
  foreach ( $this->boxes as $box_args ) {
171
+ $box_args = self::numeric_to_assoc( $box_args, array( 'name', 'title', 'context', 'priority', 'args' ) );
172
+
173
+ $defaults = array(
174
+ 'title' => ucfirst( $box_args['name'] ),
175
+ 'context' => 'normal',
176
+ 'priority' => 'default',
177
+ 'args' => array()
178
+ );
179
+ $box_args = array_merge( $defaults, $box_args );
180
 
181
+ $name = $box_args['name'];
182
+
183
+ if ( isset( $registered[ $name ] ) ) {
184
+ if ( empty( $box_args['args'] ) ) {
 
 
 
 
 
 
 
185
  trigger_error( "Duplicate box name: $name", E_USER_NOTICE );
186
+ }
187
 
188
  $name = $this->_increment( $name );
189
  } else {
190
+ $registered[ $name ] = true;
191
  }
192
 
193
+ add_meta_box(
194
+ $name,
195
+ $box_args['title'],
196
+ array( $this, '_intermediate_callback' ),
197
+ $this->pagehook,
198
+ $box_args['context'],
199
+ $box_args['priority'],
200
+ $box_args['args']
201
+ );
202
  }
203
  }
204
 
205
+ private static function numeric_to_assoc( $argv, $keys ) {
206
+ $args = array();
207
+
208
+ foreach ( $keys as $i => $key ) {
209
+ if ( isset( $argv[ $i ] ) )
210
+ $args[ $key ] = $argv[ $i ];
211
+ }
212
+
213
+ return $args;
214
+ }
215
+
216
+ // Since we don't pass an object to do_meta_boxes(),
217
+ // pass $box['args'] directly to each method.
218
  function _intermediate_callback( $_, $box ) {
219
  list( $name ) = explode( '-', $box['id'] );
220
 
scb/Cron.php CHANGED
@@ -1,7 +1,8 @@
1
  <?php
2
 
3
- // wp-cron job container
4
-
 
5
  class scbCron {
6
  protected $schedule;
7
  protected $interval;
@@ -13,41 +14,40 @@ class scbCron {
13
  /**
14
  * Create a new cron job
15
  *
16
- * @param string Reference to main plugin file
17
- * @param array List of args:
18
- string $action OR callback $callback
19
- string $schedule OR number $interval
20
- array $callback_args (optional)
21
  */
22
  function __construct( $file = false, $args ) {
23
- extract( $args, EXTR_SKIP );
24
 
25
  // Set time & schedule
26
- if ( isset( $time ) )
27
- $this->time = $time;
28
-
29
- if ( isset( $interval ) ) {
30
- $this->schedule = $interval . 'secs';
31
- $this->interval = $interval;
32
- } elseif ( isset( $schedule ) ) {
33
- $this->schedule = $schedule;
34
  }
35
 
36
  // Set hook
37
- if ( isset( $action ) ) {
38
- $this->hook = $action;
39
- } elseif ( isset( $callback ) ) {
40
- $this->hook = self::_callback_to_string( $callback );
41
- add_action( $this->hook, $callback );
42
  } elseif ( method_exists( $this, 'callback' ) ) {
43
  $this->hook = self::_callback_to_string( array( $this, 'callback' ) );
44
- add_action( $this->hook, $callback );
45
  } else {
46
  trigger_error( '$action OR $callback not set', E_USER_WARNING );
47
  }
48
 
49
- if ( isset( $callback_args ) )
50
- $this->callback_args = (array) $callback_args;
51
 
52
  if ( $file && $this->schedule ) {
53
  scbUtil::add_activation_hook( $file, array( $this, 'reset' ) );
@@ -57,23 +57,23 @@ class scbCron {
57
  add_filter( 'cron_schedules', array( $this, '_add_timing' ) );
58
  }
59
 
60
- /* Change the interval of the cron job
 
61
  *
62
- * @param array List of args:
63
- string $schedule OR number $interval
64
- timestamp $time ( optional )
65
  */
66
  function reschedule( $args ) {
67
- extract( $args );
68
 
69
- if ( $schedule && $this->schedule != $schedule ) {
70
- $this->schedule = $schedule;
71
- } elseif ( $interval && $this->interval != $interval ) {
72
- $this->schedule = $interval . 'secs';
73
- $this->interval = $interval;
74
  }
75
 
76
- $this->time = $time;
77
 
78
  $this->reset();
79
  }
@@ -107,8 +107,8 @@ class scbCron {
107
 
108
  /**
109
  * Execute the job with a given delay
110
- * @param int $delay in seconds
111
- * @param array $args List of arguments to pass to the callback
112
  */
113
  function do_once( $delay = 0, $args = null ) {
114
  if ( is_null( $args ) )
@@ -121,13 +121,19 @@ class scbCron {
121
 
122
  //_____INTERNAL METHODS_____
123
 
124
-
 
 
 
 
125
  function _add_timing( $schedules ) {
126
  if ( isset( $schedules[$this->schedule] ) )
127
  return $schedules;
128
 
129
- $schedules[$this->schedule] = array( 'interval' => $this->interval,
130
- 'display' => $this->interval . ' seconds' );
 
 
131
 
132
  return $schedules;
133
  }
@@ -139,6 +145,9 @@ class scbCron {
139
  wp_schedule_event( $this->time, $this->schedule, $this->hook, $this->callback_args );
140
  }
141
 
 
 
 
142
  protected static function really_clear_scheduled_hook( $name ) {
143
  $crons = _get_cron_array();
144
 
@@ -147,13 +156,18 @@ class scbCron {
147
  if ( $hook == $name )
148
  unset( $crons[$timestamp][$hook] );
149
 
150
- if ( empty( $hooks ) )
151
  unset( $crons[$timestamp] );
152
  }
153
 
154
  _set_cron_array( $crons );
155
  }
156
 
 
 
 
 
 
157
  protected static function _callback_to_string( $callback ) {
158
  if ( ! is_array( $callback ) )
159
  $str = $callback;
1
  <?php
2
 
3
+ /**
4
+ * wp-cron job container
5
+ */
6
  class scbCron {
7
  protected $schedule;
8
  protected $interval;
14
  /**
15
  * Create a new cron job
16
  *
17
+ * @param string|bool $file Reference to main plugin file
18
+ * @param array $args List of args:
19
+ * string $action OR callback $callback
20
+ * string $schedule OR number $interval
21
+ * array $callback_args (optional)
22
  */
23
  function __construct( $file = false, $args ) {
 
24
 
25
  // Set time & schedule
26
+ if ( isset( $args['time'] ) )
27
+ $this->time = $args['time'];
28
+
29
+ if ( isset( $args['interval'] ) ) {
30
+ $this->schedule = $args['interval'] . 'secs';
31
+ $this->interval = $args['interval'];
32
+ } elseif ( isset( $args['schedule'] ) ) {
33
+ $this->schedule = $args['schedule'];
34
  }
35
 
36
  // Set hook
37
+ if ( isset( $args['action'] ) ) {
38
+ $this->hook = $args['action'];
39
+ } elseif ( isset( $args['callback'] ) ) {
40
+ $this->hook = self::_callback_to_string( $args['callback'] );
41
+ add_action( $this->hook, $args['callback'] );
42
  } elseif ( method_exists( $this, 'callback' ) ) {
43
  $this->hook = self::_callback_to_string( array( $this, 'callback' ) );
44
+ add_action( $this->hook, $args['callback'] );
45
  } else {
46
  trigger_error( '$action OR $callback not set', E_USER_WARNING );
47
  }
48
 
49
+ if ( isset( $args['callback_args'] ) )
50
+ $this->callback_args = (array) $args['callback_args'];
51
 
52
  if ( $file && $this->schedule ) {
53
  scbUtil::add_activation_hook( $file, array( $this, 'reset' ) );
57
  add_filter( 'cron_schedules', array( $this, '_add_timing' ) );
58
  }
59
 
60
+ /**
61
+ * Change the interval of the cron job
62
  *
63
+ * @param array $args List of args:
64
+ * string $schedule OR number $interval
65
+ * timestamp $time ( optional )
66
  */
67
  function reschedule( $args ) {
 
68
 
69
+ if ( $args['schedule'] && $this->schedule != $args['schedule'] ) {
70
+ $this->schedule = $args['schedule'];
71
+ } elseif ( $args['interval'] && $this->interval != $args['interval'] ) {
72
+ $this->schedule = $args['interval'] . 'secs';
73
+ $this->interval = $args['interval'];
74
  }
75
 
76
+ $this->time = $args['time'];
77
 
78
  $this->reset();
79
  }
107
 
108
  /**
109
  * Execute the job with a given delay
110
+ * @param int $delay in seconds
111
+ * @param array $args List of arguments to pass to the callback
112
  */
113
  function do_once( $delay = 0, $args = null ) {
114
  if ( is_null( $args ) )
121
 
122
  //_____INTERNAL METHODS_____
123
 
124
+ /**
125
+ * @param array $schedules
126
+ *
127
+ * @return array
128
+ */
129
  function _add_timing( $schedules ) {
130
  if ( isset( $schedules[$this->schedule] ) )
131
  return $schedules;
132
 
133
+ $schedules[$this->schedule] = array(
134
+ 'interval' => $this->interval,
135
+ 'display' => $this->interval . ' seconds',
136
+ );
137
 
138
  return $schedules;
139
  }
145
  wp_schedule_event( $this->time, $this->schedule, $this->hook, $this->callback_args );
146
  }
147
 
148
+ /**
149
+ * @param string $name
150
+ */
151
  protected static function really_clear_scheduled_hook( $name ) {
152
  $crons = _get_cron_array();
153
 
156
  if ( $hook == $name )
157
  unset( $crons[$timestamp][$hook] );
158
 
159
+ if ( empty( $crons[$timestamp] ) )
160
  unset( $crons[$timestamp] );
161
  }
162
 
163
  _set_cron_array( $crons );
164
  }
165
 
166
+ /**
167
+ * @param callback $callback
168
+ *
169
+ * @return string
170
+ */
171
  protected static function _callback_to_string( $callback ) {
172
  if ( ! is_array( $callback ) )
173
  $str = $callback;
scb/Forms.php CHANGED
@@ -1,24 +1,44 @@
1
  <?php
2
 
3
- // Data-aware form generator
4
-
 
5
  class scbForms {
6
 
7
  const TOKEN = '%input%';
8
 
 
 
 
 
 
 
9
  static function input_with_value( $args, $value ) {
10
  $field = scbFormField::create( $args );
11
 
12
  return $field->render( $value );
13
  }
14
 
 
 
 
 
 
 
15
  static function input( $args, $formdata = null ) {
16
  $field = scbFormField::create( $args );
17
 
18
  return $field->render( scbForms::get_value( $args['name'], $formdata ) );
19
  }
20
 
21
- // Generates a table wrapped in a form
 
 
 
 
 
 
 
22
  static function form_table( $rows, $formdata = null ) {
23
  $output = '';
24
  foreach ( $rows as $row )
@@ -29,7 +49,15 @@ class scbForms {
29
  return $output;
30
  }
31
 
32
- // Generates a form
 
 
 
 
 
 
 
 
33
  static function form( $inputs, $formdata = null, $nonce ) {
34
  $output = '';
35
  foreach ( $inputs as $input )
@@ -40,7 +68,14 @@ class scbForms {
40
  return $output;
41
  }
42
 
43
- // Generates a table
 
 
 
 
 
 
 
44
  static function table( $rows, $formdata = null ) {
45
  $output = '';
46
  foreach ( $rows as $row )
@@ -51,7 +86,14 @@ class scbForms {
51
  return $output;
52
  }
53
 
54
- // Generates a table row
 
 
 
 
 
 
 
55
  static function table_row( $args, $formdata = null ) {
56
  return self::row_wrap( $args['title'], self::input( $args, $formdata ) );
57
  }
@@ -59,11 +101,22 @@ class scbForms {
59
 
60
  // ____________WRAPPERS____________
61
 
62
-
 
 
 
 
 
63
  static function form_table_wrap( $content, $nonce = 'update_options' ) {
64
  return self::form_wrap( self::table_wrap( $content ), $nonce );
65
  }
66
 
 
 
 
 
 
 
67
  static function form_wrap( $content, $nonce = 'update_options' ) {
68
  return html( "form method='post' action=''",
69
  $content,
@@ -71,14 +124,25 @@ class scbForms {
71
  );
72
  }
73
 
 
 
 
 
 
74
  static function table_wrap( $content ) {
75
  return html( "table class='form-table'", $content );
76
  }
77
 
 
 
 
 
 
 
78
  static function row_wrap( $title, $content ) {
79
- return html( "tr",
80
  html( "th scope='row'", $title ),
81
- html( "td", $content )
82
  );
83
  }
84
 
@@ -111,9 +175,9 @@ class scbForms {
111
  /**
112
  * Traverses the formdata and retrieves the correct value.
113
  *
114
- * @param array|string $name The name of the value
115
- * @param array $value The data that will be traversed
116
- * @param mixed $fallback The value returned when the key is not found
117
  *
118
  * @return mixed
119
  */
@@ -131,8 +195,8 @@ class scbForms {
131
  /**
132
  * Given a list of fields, validate some data.
133
  *
134
- * @param array $fields List of args that would be sent to scbForms::input()
135
- * @param array $data The data to validate. Defaults to $_POST
136
  * @param array $to_update Existing data to populate. Necessary for nested values
137
  *
138
  * @return array
@@ -161,8 +225,8 @@ class scbForms {
161
  * For single-choice fields, we can't distinguish either, because of how self::update_meta() works.
162
  * Therefore, the 'default' parameter is always ignored.
163
  *
164
- * @param array $args Field arguments.
165
- * @param int $object_id The object ID the metadata is attached to
166
  * @param string $meta_type
167
  *
168
  * @return string
@@ -178,6 +242,12 @@ class scbForms {
178
  return self::input_with_value( $args, $value );
179
  }
180
 
 
 
 
 
 
 
181
  static function update_meta( $fields, $data, $object_id, $meta_type = 'post' ) {
182
  foreach ( $fields as $field_args ) {
183
  $key = $field_args['name'];
@@ -193,7 +263,7 @@ class scbForms {
193
  foreach ( array_diff( $old_values, $new_values ) as $value )
194
  delete_metadata( $meta_type, $object_id, $key, $value );
195
  } else {
196
- $value = $data[$key];
197
 
198
  if ( '' === $value )
199
  delete_metadata( $meta_type, $object_id, $key );
@@ -203,6 +273,11 @@ class scbForms {
203
  }
204
  }
205
 
 
 
 
 
 
206
  private static function set_value( &$arr, $name, $value ) {
207
  $name = (array) $name;
208
 
@@ -226,9 +301,13 @@ class scbForms {
226
  * A wrapper for scbForms, containing the formdata
227
  */
228
  class scbForm {
229
- protected $data = array();
230
  protected $prefix = array();
231
 
 
 
 
 
232
  function __construct( $data, $prefix = false ) {
233
  if ( is_array( $data ) )
234
  $this->data = $data;
@@ -237,6 +316,11 @@ class scbForm {
237
  $this->prefix = (array) $prefix;
238
  }
239
 
 
 
 
 
 
240
  function traverse_to( $path ) {
241
  $data = scbForms::get_value( $path, $this->data );
242
 
@@ -245,6 +329,11 @@ class scbForm {
245
  return new scbForm( $data, $prefix );
246
  }
247
 
 
 
 
 
 
248
  function input( $args ) {
249
  $value = scbForms::get_value( $args['name'], $this->data );
250
 
@@ -256,7 +345,9 @@ class scbForm {
256
  }
257
  }
258
 
259
-
 
 
260
  interface scbFormField_I {
261
 
262
  /**
@@ -278,11 +369,18 @@ interface scbFormField_I {
278
  function validate( $value );
279
  }
280
 
281
-
 
 
282
  abstract class scbFormField implements scbFormField_I {
283
 
284
  protected $args;
285
 
 
 
 
 
 
286
  public static function create( $args ) {
287
  if ( is_a( $args, 'scbFormField_I' ) )
288
  return $args;
@@ -305,9 +403,9 @@ abstract class scbFormField implements scbFormField_I {
305
  $args['extra'] = shortcode_parse_atts( $args['extra'] );
306
 
307
  $args = wp_parse_args( $args, array(
308
- 'desc' => '',
309
- 'desc_pos' => 'after',
310
- 'wrap' => scbForms::TOKEN,
311
  'wrap_each' => scbForms::TOKEN,
312
  ) );
313
 
@@ -332,18 +430,36 @@ abstract class scbFormField implements scbFormField_I {
332
  }
333
  }
334
 
 
 
 
335
  protected function __construct( $args ) {
336
  $this->args = $args;
337
  }
338
 
 
 
 
 
 
339
  public function __get( $key ) {
340
  return $this->args[ $key ];
341
  }
342
 
 
 
 
 
 
343
  public function __isset( $key ) {
344
  return isset( $this->args[ $key ] );
345
  }
346
 
 
 
 
 
 
347
  public function render( $value = null ) {
348
  if ( null === $value && isset( $this->default ) )
349
  $value = $this->default;
@@ -358,58 +474,89 @@ abstract class scbFormField implements scbFormField_I {
358
  return str_replace( scbForms::TOKEN, $this->_render( $args ), $this->wrap );
359
  }
360
 
361
- // Mutate the field arguments so that the value passed is rendered.
 
 
 
 
 
362
  abstract protected function _set_value( &$args, $value );
363
 
364
- // The actual rendering
 
 
 
 
365
  abstract protected function _render( $args );
366
 
367
- // Handle args for a single checkbox or radio input
 
 
 
 
 
 
368
  protected static function _checkbox( $args ) {
369
  $args = wp_parse_args( $args, array(
370
- 'value' => true,
371
- 'desc' => null,
372
  'checked' => false,
373
- 'extra' => array(),
374
  ) );
375
 
376
- foreach ( $args as $key => &$val )
377
- $$key = &$val;
378
- unset( $val );
379
 
380
- $extra['checked'] = $checked;
381
-
382
- if ( is_null( $desc ) && !is_bool( $value ) )
383
- $desc = str_replace( '[]', '', $value );
384
 
385
  return self::_input_gen( $args );
386
  }
387
 
388
- // Generate html with the final args
 
 
 
 
 
 
389
  protected static function _input_gen( $args ) {
390
- extract( wp_parse_args( $args, array(
391
  'value' => null,
392
- 'desc' => null,
393
- 'extra' => array()
394
- ) ) );
395
 
396
- $extra['name'] = $name;
397
 
398
- if ( 'textarea' == $type ) {
399
- $input = html( 'textarea', $extra, esc_textarea( $value ) );
400
  } else {
401
- $extra['value'] = $value;
402
- $extra['type'] = $type;
403
- $input = html( 'input', $extra );
404
  }
405
 
406
- return self::add_label( $input, $desc, $desc_pos );
407
  }
408
 
 
 
 
 
 
 
 
409
  protected static function add_label( $input, $desc, $desc_pos ) {
410
  return html( 'label', self::add_desc( $input, $desc, $desc_pos ) ) . "\n";
411
  }
412
 
 
 
 
 
 
 
 
413
  protected static function add_desc( $input, $desc, $desc_pos ) {
414
  if ( empty( $desc ) )
415
  return $input;
@@ -420,6 +567,9 @@ abstract class scbFormField implements scbFormField_I {
420
  return $input . ' ' . $desc;
421
  }
422
 
 
 
 
423
  private static function _expand_choices( &$args ) {
424
  $choices =& $args['choices'];
425
 
@@ -433,46 +583,70 @@ abstract class scbFormField implements scbFormField_I {
433
  }
434
  }
435
 
 
 
 
 
 
436
  private static function is_associative( $array ) {
437
  $keys = array_keys( $array );
438
  return array_keys( $keys ) !== $keys;
439
  }
440
  }
441
 
442
-
 
 
443
  class scbTextField extends scbFormField {
444
 
 
 
 
 
 
445
  public function validate( $value ) {
446
- $sanitize = isset( $this->sanitize ) ? $this->sanitize : 'wp_filter_kses';
447
 
448
  return call_user_func( $sanitize, $value, $this );
449
  }
450
 
 
 
 
 
 
451
  protected function _render( $args ) {
452
  $args = wp_parse_args( $args, array(
453
- 'value' => '',
454
  'desc_pos' => 'after',
455
- 'extra' => array( 'class' => 'regular-text' ),
456
  ) );
457
 
458
- foreach ( $args as $key => &$val )
459
- $$key = &$val;
460
- unset( $val );
461
-
462
- if ( !isset( $extra['id'] ) && !is_array( $name ) && false === strpos( $name, '[' ) )
463
- $extra['id'] = $name;
464
 
465
  return scbFormField::_input_gen( $args );
466
  }
467
 
 
 
 
 
468
  protected function _set_value( &$args, $value ) {
469
  $args['value'] = $value;
470
  }
471
  }
472
 
473
-
 
 
474
  abstract class scbSingleChoiceField extends scbFormField {
475
 
 
 
 
 
 
476
  public function validate( $value ) {
477
  if ( isset( $this->choices[ $value ] ) )
478
  return $value;
@@ -480,189 +654,274 @@ abstract class scbSingleChoiceField extends scbFormField {
480
  return null;
481
  }
482
 
 
 
 
 
 
483
  protected function _render( $args ) {
484
  $args = wp_parse_args( $args, array(
485
- 'numeric' => false, // use numeric array instead of associative
486
- 'selected' => array( 'foo' ), // hack to make default blank
487
  ) );
488
 
 
 
 
 
 
 
489
  return $this->_render_specific( $args );
490
  }
491
 
 
 
 
 
492
  protected function _set_value( &$args, $value ) {
493
  $args['selected'] = $value;
494
  }
495
 
 
 
 
 
 
496
  abstract protected function _render_specific( $args );
497
  }
498
 
499
-
 
 
500
  class scbSelectField extends scbSingleChoiceField {
501
 
 
 
 
 
 
502
  protected function _render_specific( $args ) {
503
- extract( wp_parse_args( $args, array(
504
- 'text' => false,
505
- 'extra' => array()
506
- ) ) );
507
 
508
  $options = array();
509
 
510
- if ( false !== $text ) {
511
  $options[] = array(
512
- 'value' => '',
513
- 'selected' => ( $selected == array( 'foo' ) ),
514
- 'title' => $text
515
  );
516
  }
517
 
518
- foreach ( $choices as $value => $title ) {
 
 
519
  $options[] = array(
520
- 'value' => $value,
521
- 'selected' => ( $value == $selected ),
522
- 'title' => $title
523
  );
524
  }
525
 
526
  $opts = '';
527
  foreach ( $options as $option ) {
528
- extract( $option );
529
-
530
- $opts .= html( 'option', compact( 'value', 'selected' ), $title );
531
  }
532
 
533
- $extra['name'] = $name;
534
 
535
- $input = html( 'select', $extra, $opts );
536
 
537
- return scbFormField::add_label( $input, $desc, $desc_pos );
538
  }
539
  }
540
 
541
-
 
 
542
  class scbRadiosField extends scbSelectField {
543
 
 
 
 
 
 
544
  protected function _render_specific( $args ) {
545
- extract( $args );
546
 
547
- if ( array( 'foo' ) == $selected ) {
548
  // radio buttons should always have one option selected
549
- $selected = key( $choices );
550
  }
551
 
552
  $opts = '';
553
- foreach ( $choices as $value => $title ) {
 
 
554
  $single_input = scbFormField::_checkbox( array(
555
- 'name' => $name,
556
- 'type' => 'radio',
557
- 'value' => $value,
558
- 'checked' => ( $value == $selected ),
559
- 'desc' => $title,
560
- 'desc_pos' => 'after'
561
  ) );
562
 
563
- $opts .= str_replace( scbForms::TOKEN, $single_input, $wrap_each );
564
  }
565
 
566
- return scbFormField::add_desc( $opts, $desc, $desc_pos );
567
  }
568
  }
569
 
570
-
 
 
571
  class scbMultipleChoiceField extends scbFormField {
572
 
 
 
 
 
 
573
  public function validate( $value ) {
574
  return array_intersect( array_keys( $this->choices ), (array) $value );
575
  }
576
 
 
 
 
 
 
577
  protected function _render( $args ) {
578
  $args = wp_parse_args( $args, array(
579
- 'numeric' => false, // use numeric array instead of associative
580
  'checked' => null,
581
  ) );
582
 
583
- extract( $args );
584
-
585
- if ( !is_array( $checked ) )
586
- $checked = array();
587
 
588
  $opts = '';
589
- foreach ( $choices as $value => $title ) {
590
  $single_input = scbFormField::_checkbox( array(
591
- 'name' => $name . '[]',
592
- 'type' => 'checkbox',
593
- 'value' => $value,
594
- 'checked' => in_array( $value, $checked ),
595
- 'desc' => $title,
596
- 'desc_pos' => 'after'
597
  ) );
598
 
599
- $opts .= str_replace( scbForms::TOKEN, $single_input, $wrap_each );
600
  }
601
 
602
- return scbFormField::add_desc( $opts, $desc, $desc_pos );
603
  }
604
 
 
 
 
 
605
  protected function _set_value( &$args, $value ) {
606
  $args['checked'] = (array) $value;
607
  }
608
  }
609
 
610
-
 
 
611
  class scbSingleCheckboxField extends scbFormField {
612
 
 
 
 
 
 
613
  public function validate( $value ) {
614
  return (bool) $value;
615
  }
616
 
 
 
 
 
 
617
  protected function _render( $args ) {
618
  $args = wp_parse_args( $args, array(
619
- 'value' => true,
620
- 'desc' => null,
621
  'checked' => false,
622
- 'extra' => array(),
623
  ) );
624
 
625
- foreach ( $args as $key => &$val )
626
- $$key = &$val;
627
- unset( $val );
628
 
629
- $extra['checked'] = $checked;
630
-
631
- if ( is_null( $desc ) && !is_bool( $value ) )
632
- $desc = str_replace( '[]', '', $value );
633
 
634
  return scbFormField::_input_gen( $args );
635
  }
636
 
 
 
 
 
637
  protected function _set_value( &$args, $value ) {
638
  $args['checked'] = ( $value || ( isset( $args['value'] ) && $value == $args['value'] ) );
639
  }
640
  }
641
 
642
-
 
 
643
  class scbCustomField implements scbFormField_I {
644
 
645
  protected $args;
646
 
 
 
 
647
  function __construct( $args ) {
648
  $this->args = wp_parse_args( $args, array(
649
- 'render' => 'var_dump',
650
  'sanitize' => 'wp_filter_kses',
651
  ) );
652
  }
653
 
 
 
 
 
 
654
  public function __get( $key ) {
655
  return $this->args[ $key ];
656
  }
657
 
 
 
 
 
 
658
  public function __isset( $key ) {
659
  return isset( $this->args[ $key ] );
660
  }
661
 
 
 
 
 
 
662
  public function render( $value = null ) {
663
  return call_user_func( $this->render, $value, $this );
664
  }
665
 
 
 
 
 
 
666
  public function validate( $value ) {
667
  return call_user_func( $this->sanitize, $value, $this );
668
  }
1
  <?php
2
 
3
+ /**
4
+ * Data-aware form generator
5
+ */
6
  class scbForms {
7
 
8
  const TOKEN = '%input%';
9
 
10
+ /**
11
+ * @param array|scbFormField_I $args
12
+ * @param mixed $value
13
+ *
14
+ * @return string
15
+ */
16
  static function input_with_value( $args, $value ) {
17
  $field = scbFormField::create( $args );
18
 
19
  return $field->render( $value );
20
  }
21
 
22
+ /**
23
+ * @param array|scbFormField_I $args
24
+ * @param array $formdata
25
+ *
26
+ * @return string
27
+ */
28
  static function input( $args, $formdata = null ) {
29
  $field = scbFormField::create( $args );
30
 
31
  return $field->render( scbForms::get_value( $args['name'], $formdata ) );
32
  }
33
 
34
+ /**
35
+ * Generates a table wrapped in a form
36
+ *
37
+ * @param array $rows
38
+ * @param array $formdata
39
+ *
40
+ * @return string
41
+ */
42
  static function form_table( $rows, $formdata = null ) {
43
  $output = '';
44
  foreach ( $rows as $row )
49
  return $output;
50
  }
51
 
52
+ /**
53
+ * Generates a form
54
+ *
55
+ * @param array $inputs
56
+ * @param array $formdata
57
+ * @param string $nonce
58
+ *
59
+ * @return string
60
+ */
61
  static function form( $inputs, $formdata = null, $nonce ) {
62
  $output = '';
63
  foreach ( $inputs as $input )
68
  return $output;
69
  }
70
 
71
+ /**
72
+ * Generates a table
73
+ *
74
+ * @param array $rows
75
+ * @param array $formdata
76
+ *
77
+ * @return string
78
+ */
79
  static function table( $rows, $formdata = null ) {
80
  $output = '';
81
  foreach ( $rows as $row )
86
  return $output;
87
  }
88
 
89
+ /**
90
+ * Generates a table row
91
+ *
92
+ * @param array $args
93
+ * @param array $formdata
94
+ *
95
+ * @return string
96
+ */
97
  static function table_row( $args, $formdata = null ) {
98
  return self::row_wrap( $args['title'], self::input( $args, $formdata ) );
99
  }
101
 
102
  // ____________WRAPPERS____________
103
 
104
+ /**
105
+ * @param string $content
106
+ * @param string $nonce
107
+ *
108
+ * @return string
109
+ */
110
  static function form_table_wrap( $content, $nonce = 'update_options' ) {
111
  return self::form_wrap( self::table_wrap( $content ), $nonce );
112
  }
113
 
114
+ /**
115
+ * @param string $content
116
+ * @param string $nonce
117
+ *
118
+ * @return string
119
+ */
120
  static function form_wrap( $content, $nonce = 'update_options' ) {
121
  return html( "form method='post' action=''",
122
  $content,
124
  );
125
  }
126
 
127
+ /**
128
+ * @param string $content
129
+ *
130
+ * @return string
131
+ */
132
  static function table_wrap( $content ) {
133
  return html( "table class='form-table'", $content );
134
  }
135
 
136
+ /**
137
+ * @param string $title
138
+ * @param string $content
139
+ *
140
+ * @return string
141
+ */
142
  static function row_wrap( $title, $content ) {
143
+ return html( 'tr',
144
  html( "th scope='row'", $title ),
145
+ html( 'td', $content )
146
  );
147
  }
148
 
175
  /**
176
  * Traverses the formdata and retrieves the correct value.
177
  *
178
+ * @param string $name The name of the value
179
+ * @param array $value The data that will be traversed
180
+ * @param mixed $fallback The value returned when the key is not found
181
  *
182
  * @return mixed
183
  */
195
  /**
196
  * Given a list of fields, validate some data.
197
  *
198
+ * @param array $fields List of args that would be sent to scbForms::input()
199
+ * @param array $data The data to validate. Defaults to $_POST
200
  * @param array $to_update Existing data to populate. Necessary for nested values
201
  *
202
  * @return array
225
  * For single-choice fields, we can't distinguish either, because of how self::update_meta() works.
226
  * Therefore, the 'default' parameter is always ignored.
227
  *
228
+ * @param array $args Field arguments.
229
+ * @param int $object_id The object ID the metadata is attached to
230
  * @param string $meta_type
231
  *
232
  * @return string
242
  return self::input_with_value( $args, $value );
243
  }
244
 
245
+ /**
246
+ * @param array $fields
247
+ * @param array $data
248
+ * @param int $object_id
249
+ * @param string $meta_type
250
+ */
251
  static function update_meta( $fields, $data, $object_id, $meta_type = 'post' ) {
252
  foreach ( $fields as $field_args ) {
253
  $key = $field_args['name'];
263
  foreach ( array_diff( $old_values, $new_values ) as $value )
264
  delete_metadata( $meta_type, $object_id, $key, $value );
265
  } else {
266
+ $value = isset( $data[$key] ) ? $data[$key] : '';
267
 
268
  if ( '' === $value )
269
  delete_metadata( $meta_type, $object_id, $key );
273
  }
274
  }
275
 
276
+ /**
277
+ * @param array $arr
278
+ * @param string $name
279
+ * @param mixed $value
280
+ */
281
  private static function set_value( &$arr, $name, $value ) {
282
  $name = (array) $name;
283
 
301
  * A wrapper for scbForms, containing the formdata
302
  */
303
  class scbForm {
304
+ protected $data = array();
305
  protected $prefix = array();
306
 
307
+ /**
308
+ * @param array $data
309
+ * @param string|boolean $prefix
310
+ */
311
  function __construct( $data, $prefix = false ) {
312
  if ( is_array( $data ) )
313
  $this->data = $data;
316
  $this->prefix = (array) $prefix;
317
  }
318
 
319
+ /**
320
+ * @param string $path
321
+ *
322
+ * @return scbForm
323
+ */
324
  function traverse_to( $path ) {
325
  $data = scbForms::get_value( $path, $this->data );
326
 
329
  return new scbForm( $data, $prefix );
330
  }
331
 
332
+ /**
333
+ * @param array $args
334
+ *
335
+ * @return string
336
+ */
337
  function input( $args ) {
338
  $value = scbForms::get_value( $args['name'], $this->data );
339
 
345
  }
346
  }
347
 
348
+ /**
349
+ * Interface for form fields.
350
+ */
351
  interface scbFormField_I {
352
 
353
  /**
369
  function validate( $value );
370
  }
371
 
372
+ /**
373
+ * Base class for form fields implementations.
374
+ */
375
  abstract class scbFormField implements scbFormField_I {
376
 
377
  protected $args;
378
 
379
+ /**
380
+ * @param array|scbFormField_I $args
381
+ *
382
+ * @return mixed false on failure or instance of form class
383
+ */
384
  public static function create( $args ) {
385
  if ( is_a( $args, 'scbFormField_I' ) )
386
  return $args;
403
  $args['extra'] = shortcode_parse_atts( $args['extra'] );
404
 
405
  $args = wp_parse_args( $args, array(
406
+ 'desc' => '',
407
+ 'desc_pos' => 'after',
408
+ 'wrap' => scbForms::TOKEN,
409
  'wrap_each' => scbForms::TOKEN,
410
  ) );
411
 
430
  }
431
  }
432
 
433
+ /**
434
+ * @param array $args
435
+ */
436
  protected function __construct( $args ) {
437
  $this->args = $args;
438
  }
439
 
440
+ /**
441
+ * @param string $key
442
+ *
443
+ * @return mixed
444
+ */
445
  public function __get( $key ) {
446
  return $this->args[ $key ];
447
  }
448
 
449
+ /**
450
+ * @param string $key
451
+ *
452
+ * @return bool
453
+ */
454
  public function __isset( $key ) {
455
  return isset( $this->args[ $key ] );
456
  }
457
 
458
+ /**
459
+ * @param mixed $value
460
+ *
461
+ * @return string
462
+ */
463
  public function render( $value = null ) {
464
  if ( null === $value && isset( $this->default ) )
465
  $value = $this->default;
474
  return str_replace( scbForms::TOKEN, $this->_render( $args ), $this->wrap );
475
  }
476
 
477
+ /**
478
+ * Mutate the field arguments so that the value passed is rendered.
479
+ *
480
+ * @param array $args
481
+ * @param mixed $value
482
+ */
483
  abstract protected function _set_value( &$args, $value );
484
 
485
+ /**
486
+ * The actual rendering
487
+ *
488
+ * @param array $args
489
+ */
490
  abstract protected function _render( $args );
491
 
492
+ /**
493
+ * Handle args for a single checkbox or radio input
494
+ *
495
+ * @param array $args
496
+ *
497
+ * @return string
498
+ */
499
  protected static function _checkbox( $args ) {
500
  $args = wp_parse_args( $args, array(
501
+ 'value' => true,
502
+ 'desc' => null,
503
  'checked' => false,
504
+ 'extra' => array(),
505
  ) );
506
 
507
+ $args['extra']['checked'] = $args['checked'];
 
 
508
 
509
+ if ( is_null( $args['desc'] ) && ! is_bool( $args['value'] ) )
510
+ $args['desc'] = str_replace( '[]', '', $args['value'] );
 
 
511
 
512
  return self::_input_gen( $args );
513
  }
514
 
515
+ /**
516
+ * Generate html with the final args
517
+ *
518
+ * @param array $args
519
+ *
520
+ * @return string
521
+ */
522
  protected static function _input_gen( $args ) {
523
+ $args = wp_parse_args( $args, array(
524
  'value' => null,
525
+ 'desc' => null,
526
+ 'extra' => array(),
527
+ ) );
528
 
529
+ $args['extra']['name'] = $args['name'];
530
 
531
+ if ( 'textarea' == $args['type'] ) {
532
+ $input = html( 'textarea', $args['extra'], esc_textarea( $args['value'] ) );
533
  } else {
534
+ $args['extra']['value'] = $args['value'];
535
+ $args['extra']['type'] = $args['type'];
536
+ $input = html( 'input', $args['extra'] );
537
  }
538
 
539
+ return self::add_label( $input, $args['desc'], $args['desc_pos'] );
540
  }
541
 
542
+ /**
543
+ * @param string $input
544
+ * @param string $desc
545
+ * @param string $desc_pos
546
+ *
547
+ * @return string
548
+ */
549
  protected static function add_label( $input, $desc, $desc_pos ) {
550
  return html( 'label', self::add_desc( $input, $desc, $desc_pos ) ) . "\n";
551
  }
552
 
553
+ /**
554
+ * @param string $input
555
+ * @param string $desc
556
+ * @param string $desc_pos
557
+ *
558
+ * @return string
559
+ */
560
  protected static function add_desc( $input, $desc, $desc_pos ) {
561
  if ( empty( $desc ) )
562
  return $input;
567
  return $input . ' ' . $desc;
568
  }
569
 
570
+ /**
571
+ * @param array $args
572
+ */
573
  private static function _expand_choices( &$args ) {
574
  $choices =& $args['choices'];
575
 
583
  }
584
  }
585
 
586
+ /**
587
+ * @param array $array
588
+ *
589
+ * @return bool
590
+ */
591
  private static function is_associative( $array ) {
592
  $keys = array_keys( $array );
593
  return array_keys( $keys ) !== $keys;
594
  }
595
  }
596
 
597
+ /**
598
+ * Text form field.
599
+ */
600
  class scbTextField extends scbFormField {
601
 
602
+ /**
603
+ * @param string $value
604
+ *
605
+ * @return string
606
+ */
607
  public function validate( $value ) {
608
+ $sanitize = isset( $this->sanitize ) ? $this->sanitize : 'wp_kses_data';
609
 
610
  return call_user_func( $sanitize, $value, $this );
611
  }
612
 
613
+ /**
614
+ * @param array $args
615
+ *
616
+ * @return string
617
+ */
618
  protected function _render( $args ) {
619
  $args = wp_parse_args( $args, array(
620
+ 'value' => '',
621
  'desc_pos' => 'after',
622
+ 'extra' => array( 'class' => 'regular-text' ),
623
  ) );
624
 
625
+ if ( ! isset( $args['extra']['id'] ) && ! is_array( $args['name'] ) && false === strpos( $args['name'], '[' ) )
626
+ $args['extra']['id'] = $args['name'];
 
 
 
 
627
 
628
  return scbFormField::_input_gen( $args );
629
  }
630
 
631
+ /**
632
+ * @param array $args
633
+ * @param string $value
634
+ */
635
  protected function _set_value( &$args, $value ) {
636
  $args['value'] = $value;
637
  }
638
  }
639
 
640
+ /**
641
+ * Base class for form fields with single choice.
642
+ */
643
  abstract class scbSingleChoiceField extends scbFormField {
644
 
645
+ /**
646
+ * @param mixed $value
647
+ *
648
+ * @return mixed|null
649
+ */
650
  public function validate( $value ) {
651
  if ( isset( $this->choices[ $value ] ) )
652
  return $value;
654
  return null;
655
  }
656
 
657
+ /**
658
+ * @param array $args
659
+ *
660
+ * @return string
661
+ */
662
  protected function _render( $args ) {
663
  $args = wp_parse_args( $args, array(
664
+ 'numeric' => false, // use numeric array instead of associative
 
665
  ) );
666
 
667
+ if ( isset( $args['selected'] ) ) {
668
+ $args['selected'] = (string) $args['selected'];
669
+ } else {
670
+ $args['selected'] = array('foo'); // hack to make default blank
671
+ }
672
+
673
  return $this->_render_specific( $args );
674
  }
675
 
676
+ /**
677
+ * @param array $args
678
+ * @param mixed $value
679
+ */
680
  protected function _set_value( &$args, $value ) {
681
  $args['selected'] = $value;
682
  }
683
 
684
+ /**
685
+ * @param array $args
686
+ *
687
+ * @return string
688
+ */
689
  abstract protected function _render_specific( $args );
690
  }
691
 
692
+ /**
693
+ * Dropdown field.
694
+ */
695
  class scbSelectField extends scbSingleChoiceField {
696
 
697
+ /**
698
+ * @param array $args
699
+ *
700
+ * @return string
701
+ */
702
  protected function _render_specific( $args ) {
703
+ $args = wp_parse_args( $args, array(
704
+ 'text' => false,
705
+ 'extra' => array(),
706
+ ) );
707
 
708
  $options = array();
709
 
710
+ if ( false !== $args['text'] ) {
711
  $options[] = array(
712
+ 'value' => '',
713
+ 'selected' => ( $args['selected'] === array( 'foo' ) ),
714
+ 'title' => $args['text'],
715
  );
716
  }
717
 
718
+ foreach ( $args['choices'] as $value => $title ) {
719
+ $value = (string) $value;
720
+
721
  $options[] = array(
722
+ 'value' => $value,
723
+ 'selected' => ( $value == $args['selected'] ),
724
+ 'title' => $title,
725
  );
726
  }
727
 
728
  $opts = '';
729
  foreach ( $options as $option ) {
730
+ $opts .= html( 'option', array( 'value' => $option['value'], 'selected' => $option['selected'] ), $option['title'] );
 
 
731
  }
732
 
733
+ $args['extra']['name'] = $args['name'];
734
 
735
+ $input = html( 'select', $args['extra'], $opts );
736
 
737
+ return scbFormField::add_label( $input, $args['desc'], $args['desc_pos'] );
738
  }
739
  }
740
 
741
+ /**
742
+ * Radio field.
743
+ */
744
  class scbRadiosField extends scbSelectField {
745
 
746
+ /**
747
+ * @param array $args
748
+ *
749
+ * @return string
750
+ */
751
  protected function _render_specific( $args ) {
 
752
 
753
+ if ( array( 'foo' ) === $args['selected'] ) {
754
  // radio buttons should always have one option selected
755
+ $args['selected'] = key( $args['choices'] );
756
  }
757
 
758
  $opts = '';
759
+ foreach ( $args['choices'] as $value => $title ) {
760
+ $value = (string) $value;
761
+
762
  $single_input = scbFormField::_checkbox( array(
763
+ 'name' => $args['name'],
764
+ 'type' => 'radio',
765
+ 'value' => $value,
766
+ 'checked' => ( $value == $args['selected'] ),
767
+ 'desc' => $title,
768
+ 'desc_pos' => 'after',
769
  ) );
770
 
771
+ $opts .= str_replace( scbForms::TOKEN, $single_input, $args['wrap_each'] );
772
  }
773
 
774
+ return scbFormField::add_desc( $opts, $args['desc'], $args['desc_pos'] );
775
  }
776
  }
777
 
778
+ /**
779
+ * Checkbox field with multiple choices.
780
+ */
781
  class scbMultipleChoiceField extends scbFormField {
782
 
783
+ /**
784
+ * @param mixed $value
785
+ *
786
+ * @return array
787
+ */
788
  public function validate( $value ) {
789
  return array_intersect( array_keys( $this->choices ), (array) $value );
790
  }
791
 
792
+ /**
793
+ * @param array $args
794
+ *
795
+ * @return string
796
+ */
797
  protected function _render( $args ) {
798
  $args = wp_parse_args( $args, array(
799
+ 'numeric' => false, // use numeric array instead of associative
800
  'checked' => null,
801
  ) );
802
 
803
+ if ( ! is_array( $args['checked'] ) )
804
+ $args['checked'] = array();
 
 
805
 
806
  $opts = '';
807
+ foreach ( $args['choices'] as $value => $title ) {
808
  $single_input = scbFormField::_checkbox( array(
809
+ 'name' => $args['name'] . '[]',
810
+ 'type' => 'checkbox',
811
+ 'value' => $value,
812
+ 'checked' => in_array( $value, $args['checked'] ),
813
+ 'desc' => $title,
814
+ 'desc_pos' => 'after',
815
  ) );
816
 
817
+ $opts .= str_replace( scbForms::TOKEN, $single_input, $args['wrap_each'] );
818
  }
819
 
820
+ return scbFormField::add_desc( $opts, $args['desc'], $args['desc_pos'] );
821
  }
822
 
823
+ /**
824
+ * @param array $args
825
+ * @param mixed $value
826
+ */
827
  protected function _set_value( &$args, $value ) {
828
  $args['checked'] = (array) $value;
829
  }
830
  }
831
 
832
+ /**
833
+ * Checkbox field.
834
+ */
835
  class scbSingleCheckboxField extends scbFormField {
836
 
837
+ /**
838
+ * @param mixed $value
839
+ *
840
+ * @return boolean
841
+ */
842
  public function validate( $value ) {
843
  return (bool) $value;
844
  }
845
 
846
+ /**
847
+ * @param array $args
848
+ *
849
+ * @return string
850
+ */
851
  protected function _render( $args ) {
852
  $args = wp_parse_args( $args, array(
853
+ 'value' => true,
854
+ 'desc' => null,
855
  'checked' => false,
856
+ 'extra' => array(),
857
  ) );
858
 
859
+ $args['extra']['checked'] = $args['checked'];
 
 
860
 
861
+ if ( is_null( $args['desc'] ) && ! is_bool( $args['value'] ) )
862
+ $args['desc'] = str_replace( '[]', '', $args['value'] );
 
 
863
 
864
  return scbFormField::_input_gen( $args );
865
  }
866
 
867
+ /**
868
+ * @param array $args
869
+ * @param mixed $value
870
+ */
871
  protected function _set_value( &$args, $value ) {
872
  $args['checked'] = ( $value || ( isset( $args['value'] ) && $value == $args['value'] ) );
873
  }
874
  }
875
 
876
+ /**
877
+ * Wrapper field for custom callbacks.
878
+ */
879
  class scbCustomField implements scbFormField_I {
880
 
881
  protected $args;
882
 
883
+ /**
884
+ * @param array $args
885
+ */
886
  function __construct( $args ) {
887
  $this->args = wp_parse_args( $args, array(
888
+ 'render' => 'var_dump',
889
  'sanitize' => 'wp_filter_kses',
890
  ) );
891
  }
892
 
893
+ /**
894
+ * @param string $key
895
+ *
896
+ * @return mixed
897
+ */
898
  public function __get( $key ) {
899
  return $this->args[ $key ];
900
  }
901
 
902
+ /**
903
+ * @param string $key
904
+ *
905
+ * @return boolean
906
+ */
907
  public function __isset( $key ) {
908
  return isset( $this->args[ $key ] );
909
  }
910
 
911
+ /**
912
+ * @param mixed $value
913
+ *
914
+ * @return string
915
+ */
916
  public function render( $value = null ) {
917
  return call_user_func( $this->render, $value, $this );
918
  }
919
 
920
+ /**
921
+ * @param mixed $value
922
+ *
923
+ * @return mixed
924
+ */
925
  public function validate( $value ) {
926
  return call_user_func( $this->sanitize, $value, $this );
927
  }
scb/PostMetabox.php ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class scbPostMetabox {
4
+
5
+ private $id, $title;
6
+
7
+ private $post_types;
8
+
9
+ private $post_data = array();
10
+
11
+ protected $actions = array( 'admin_enqueue_scripts', 'post_updated_messages' );
12
+
13
+ public function __construct( $id, $title, $args = array() ) {
14
+ $this->id = $id;
15
+ $this->title = $title;
16
+
17
+ $args = wp_parse_args( $args, array(
18
+ 'post_type' => 'post',
19
+ 'context' => 'advanced',
20
+ 'priority' => 'default'
21
+ ) );
22
+
23
+ if ( is_string( $args['post_type'] ) )
24
+ $args['post_type'] = array( $args['post_type'] );
25
+ $this->post_types = $args['post_type'];
26
+
27
+ $this->context = $args['context'];
28
+ $this->priority = $args['priority'];
29
+
30
+ add_action( 'load-post.php', array( $this, 'pre_register' ) );
31
+ add_action( 'load-post-new.php', array( $this, 'pre_register' ) );
32
+ }
33
+
34
+ final public function pre_register() {
35
+ if ( ! in_array( get_current_screen()->post_type, $this->post_types ) )
36
+ return;
37
+
38
+ if ( ! $this->condition() )
39
+ return;
40
+
41
+ if ( isset( $_GET['post'] ) )
42
+ $this->post_data = $this->get_meta( intval( $_GET['post'] ) );
43
+
44
+ add_action( 'add_meta_boxes', array( $this, 'register' ) );
45
+ add_action( 'save_post', array( $this, '_save_post' ), 10, 2 );
46
+
47
+ foreach ( $this->actions as $action ) {
48
+ if ( method_exists( $this, $action ) )
49
+ add_action( $action, array( $this, $action ) );
50
+ }
51
+ }
52
+
53
+ // Additional checks before registering the metabox
54
+ protected function condition() {
55
+ return true;
56
+ }
57
+
58
+ final public function register() {
59
+ add_meta_box( $this->id, $this->title, array( $this, 'display' ), null, $this->context, $this->priority );
60
+ }
61
+
62
+ public function before_display( $form_data, $post ) {
63
+ return $form_data;
64
+ }
65
+
66
+ public function display( $post ) {
67
+ $form_fields = $this->form_fields();
68
+ if ( ! $form_fields )
69
+ return;
70
+
71
+ $form_data = $this->post_data;
72
+ $error_fields = array();
73
+
74
+ if ( isset( $form_data['_error_data_' . $this->id ] ) ) {
75
+ $data = maybe_unserialize( $form_data['_error_data_' . $this->id ] );
76
+
77
+ $error_fields = $data['fields'];
78
+ $form_data = $data['data'];
79
+ }
80
+
81
+ $form_data = $this->before_display( $form_data, $post );
82
+
83
+ $this->before_form( $post );
84
+ echo $this->table( $form_fields, $form_data, $error_fields );
85
+ $this->after_form( $post );
86
+
87
+ delete_post_meta( $post->ID, '_error_data_' . $this->id );
88
+ }
89
+
90
+ public function table( $rows, $formdata, $errors = array() ) {
91
+ $output = '';
92
+ foreach ( $rows as $row ) {
93
+ $output .= $this->table_row( $row, $formdata, $errors );
94
+ }
95
+
96
+ $output = scbForms::table_wrap( $output );
97
+
98
+ return $output;
99
+ }
100
+
101
+ public function table_row( $row, $formdata, $errors = array() ) {
102
+ $input = scbForms::input( $row, $formdata );
103
+
104
+ // If row has an error, highlight it
105
+ $style = ( in_array( $row['name'], $errors ) ) ? 'style= "background-color: #FFCCCC"' : '';
106
+
107
+ return html( 'tr',
108
+ html( "th $style scope='row'", $row['title'] ),
109
+ html( "td $style", $input )
110
+ );
111
+ }
112
+
113
+ // Display some extra HTML before the form
114
+ public function before_form( $post ) { }
115
+
116
+ // Return the list of form fields
117
+ public function form_fields() {
118
+ return array();
119
+ }
120
+
121
+ // Display some extra HTML after the form
122
+ public function after_form( $post ) { }
123
+
124
+ // Makes sure that the saving occurs only for the post being edited
125
+ final public function _save_post( $post_id, $post ) {
126
+ if ( ! isset( $_POST['action'] ) || $_POST['action'] != 'editpost' )
127
+ return;
128
+
129
+ if ( $post_id != $_POST['post_ID'] )
130
+ return;
131
+
132
+ if ( ! in_array( $post->post_type, $this->post_types ) )
133
+ return;
134
+
135
+ $this->save( $post->ID );
136
+ }
137
+
138
+ protected function save( $post_id ) {
139
+ $form_fields = $this->form_fields();
140
+
141
+ $to_update = scbForms::validate_post_data( $form_fields );
142
+
143
+ // Filter data
144
+ $to_update = $this->before_save( $to_update, $post_id );
145
+
146
+ // Validate dataset
147
+ $is_valid = $this->validate_post_data( $to_update, $post_id );
148
+ if ( $is_valid instanceof WP_Error && $is_valid->get_error_codes() ) {
149
+
150
+ $error_data = array(
151
+ 'fields' => $is_valid->get_error_codes(),
152
+ 'data' => $to_update
153
+ );
154
+ update_post_meta( $post_id, '_error_data_' . $this->id, $error_data );
155
+
156
+ $location = add_query_arg( 'message', 1, get_edit_post_link( $post_id, 'url' ) );
157
+ wp_redirect( apply_filters( 'redirect_post_location', $location, $post_id ) );
158
+ exit;
159
+ }
160
+
161
+ foreach ( $to_update as $key => $value ) {
162
+ update_post_meta( $post_id, $key, $value );
163
+ }
164
+ }
165
+
166
+ protected function before_save( $post_data, $post_id ) {
167
+ return $post_data;
168
+ }
169
+
170
+ protected function validate_post_data( $post_data, $post_id ) {
171
+ return false;
172
+ }
173
+
174
+ private function get_meta( $post_id ) {
175
+ $meta = get_post_custom( $post_id );
176
+ foreach ( $meta as $key => $values )
177
+ $meta[ $key ] = maybe_unserialize( $meta[ $key ][0] );
178
+
179
+ return $meta;
180
+ }
181
+ }
182
+
scb/Table.php CHANGED
@@ -29,50 +29,3 @@ class scbTable {
29
  }
30
  }
31
 
32
- /**
33
- * Register a table with $wpdb
34
- *
35
- * @param string $key The key to be used on the $wpdb object
36
- * @param string $name The actual name of the table, without $wpdb->prefix
37
- */
38
- function scb_register_table( $key, $name = false ) {
39
- global $wpdb;
40
-
41
- if ( !$name )
42
- $name = $key;
43
-
44
- $wpdb->tables[] = $name;
45
- $wpdb->$key = $wpdb->prefix . $name;
46
- }
47
-
48
- function scb_install_table( $key, $columns, $upgrade_method = 'dbDelta' ) {
49
- global $wpdb;
50
-
51
- $full_table_name = $wpdb->$key;
52
-
53
- $charset_collate = '';
54
- if ( $wpdb->has_cap( 'collation' ) ) {
55
- if ( ! empty( $wpdb->charset ) )
56
- $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
57
- if ( ! empty( $wpdb->collate ) )
58
- $charset_collate .= " COLLATE $wpdb->collate";
59
- }
60
-
61
- if ( 'dbDelta' == $upgrade_method ) {
62
- require_once ABSPATH . 'wp-admin/includes/upgrade.php';
63
- dbDelta( "CREATE TABLE $full_table_name ( $columns ) $charset_collate" );
64
- return;
65
- }
66
-
67
- if ( 'delete_first' == $upgrade_method )
68
- $wpdb->query( "DROP TABLE IF EXISTS $full_table_name;" );
69
-
70
- $wpdb->query( "CREATE TABLE IF NOT EXISTS $full_table_name ( $columns ) $charset_collate;" );
71
- }
72
-
73
- function scb_uninstall_table( $key ) {
74
- global $wpdb;
75
-
76
- $wpdb->query( "DROP TABLE IF EXISTS " . $wpdb->$key );
77
- }
78
-
29
  }
30
  }
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
scb/Util.php CHANGED
@@ -28,7 +28,9 @@ class scbUtil {
28
  $content = str_replace( array( "'", "\n" ), array( '"', '' ), ob_get_clean() );
29
 
30
  echo "<script type='text/javascript'>\n";
 
31
  echo "jQuery(function ($) { $('head').prepend('$content'); });\n";
 
32
  echo "</script>";
33
  }
34
 
@@ -137,6 +139,93 @@ function scb_list_fold( $list, $key, $value ) {
137
  return $r;
138
  }
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
  //_____Minimalist HTML framework_____
142
 
28
  $content = str_replace( array( "'", "\n" ), array( '"', '' ), ob_get_clean() );
29
 
30
  echo "<script type='text/javascript'>\n";
31
+ echo "//<![CDATA[";
32
  echo "jQuery(function ($) { $('head').prepend('$content'); });\n";
33
+ echo "//]]>";
34
  echo "</script>";
35
  }
36
 
139
  return $r;
140
  }
141
 
142
+ /**
143
+ * Splits a list into sets, grouped by the result of running each value through $fn.
144
+ *
145
+ * @param array List of items to be partitioned
146
+ * @param callback Function that takes an element and returns a string key
147
+ */
148
+ function scb_list_group_by( $list, $fn ) {
149
+ $groups = array();
150
+
151
+ foreach ( $list as $item ) {
152
+ $key = call_user_func( $fn, $item );
153
+
154
+ if ( null === $key )
155
+ continue;
156
+
157
+ $groups[ $key ][] = $item;
158
+ }
159
+
160
+ return $groups;
161
+ }
162
+
163
+ //_____Database Table Utilities_____
164
+
165
+ /**
166
+ * Register a table with $wpdb
167
+ *
168
+ * @param string $key The key to be used on the $wpdb object
169
+ * @param string $name The actual name of the table, without $wpdb->prefix
170
+ */
171
+ function scb_register_table( $key, $name = false ) {
172
+ global $wpdb;
173
+
174
+ if ( !$name )
175
+ $name = $key;
176
+
177
+ $wpdb->tables[] = $name;
178
+ $wpdb->$key = $wpdb->prefix . $name;
179
+ }
180
+
181
+ /**
182
+ * Runs the SQL query for installing/upgrading a table
183
+ *
184
+ * @param string $key The key used in scb_register_table()
185
+ * @param string $columns The SQL columns for the CREATE TABLE statement
186
+ * @param array $opts Various other options
187
+ */
188
+ function scb_install_table( $key, $columns, $opts = array() ) {
189
+ global $wpdb;
190
+
191
+ $full_table_name = $wpdb->$key;
192
+
193
+ if ( is_string( $opts ) ) {
194
+ $opts = array( 'upgrade_method' => $opts );
195
+ }
196
+
197
+ $opts = wp_parse_args( $opts, array(
198
+ 'upgrade_method' => 'dbDelta',
199
+ 'table_options' => '',
200
+ ) );
201
+
202
+ $charset_collate = '';
203
+ if ( $wpdb->has_cap( 'collation' ) ) {
204
+ if ( ! empty( $wpdb->charset ) )
205
+ $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
206
+ if ( ! empty( $wpdb->collate ) )
207
+ $charset_collate .= " COLLATE $wpdb->collate";
208
+ }
209
+
210
+ $table_options = $charset_collate . ' ' . $opts['table_options'];
211
+
212
+ if ( 'dbDelta' == $opts['upgrade_method'] ) {
213
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
214
+ dbDelta( "CREATE TABLE $full_table_name ( $columns ) $table_options" );
215
+ return;
216
+ }
217
+
218
+ if ( 'delete_first' == $opts['upgrade_method'] )
219
+ $wpdb->query( "DROP TABLE IF EXISTS $full_table_name;" );
220
+
221
+ $wpdb->query( "CREATE TABLE IF NOT EXISTS $full_table_name ( $columns ) $table_options;" );
222
+ }
223
+
224
+ function scb_uninstall_table( $key ) {
225
+ global $wpdb;
226
+
227
+ $wpdb->query( "DROP TABLE IF EXISTS " . $wpdb->$key );
228
+ }
229
 
230
  //_____Minimalist HTML framework_____
231
 
scb/composer.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name" : "scribu/scb-framework",
3
+ "description": "A set of useful classes for faster plugin development",
4
+ "keywords" : ["wordpress"],
5
+ "homepage" : "https://github.com/scribu/wp-scb-framework",
6
+ "license" : "GPL-3.0+",
7
+ "authors" : [
8
+ {
9
+ "name" : "Cristi Burcă",
10
+ "homepage": "http://scribu.net/"
11
+ }
12
+ ],
13
+ "support" : {
14
+ "issues": "https://github.com/scribu/wp-scb-framework/issues",
15
+ "source": "https://github.com/scribu/wp-scb-framework",
16
+ "wiki": "https://github.com/scribu/wp-scb-framework/wiki"
17
+ },
18
+ "autoload" : {
19
+ "classmap": ["."],
20
+ "files" : ["load-composer.php", "Util.php"]
21
+ }
22
+ }
scb/load-composer.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Pass through version to use when Composer handles classes load.
5
+ *
6
+ * @param callable $callback
7
+ */
8
+ function scb_init( $callback = null ) {
9
+ if ( $callback )
10
+ call_user_func( $callback );
11
+ }
scb/load.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- $GLOBALS['_scb_data'] = array( 57, __FILE__, array(
4
  'scbUtil', 'scbOptions', 'scbForms', 'scbTable',
5
- 'scbWidget', 'scbAdminPage', 'scbBoxesPage',
6
  'scbCron', 'scbHooks',
7
  ) );
8
 
1
  <?php
2
 
3
+ $GLOBALS['_scb_data'] = array( 60, __FILE__, array(
4
  'scbUtil', 'scbOptions', 'scbForms', 'scbTable',
5
+ 'scbWidget', 'scbAdminPage', 'scbBoxesPage', 'scbPostMetabox',
6
  'scbCron', 'scbHooks',
7
  ) );
8
 
template-tags.php CHANGED
@@ -108,7 +108,7 @@ class UserOnline_Template {
108
 
109
  private static $cache = array();
110
 
111
- function compact_list( $type, $output = 'html', $page_url = '') {
112
  UserOnline_Core::$add_script = true;
113
 
114
  if ( !isset( self::$cache[$type] ) ) {
@@ -183,7 +183,7 @@ class UserOnline_Template {
183
  return $output;
184
  }
185
 
186
- function detailed_list( $counts, $user_buckets, $nicetexts ) {
187
  UserOnline_Core::$add_script = true;
188
 
189
  if ( $counts['user'] == 0 )
@@ -208,7 +208,7 @@ class UserOnline_Template {
208
  foreach ( $users as $user ) {
209
  $nr = number_format_i18n( $i++ );
210
  $name = self::format_name( $user );
211
- $user_ip = self::format_ip( $user->user_ip );
212
  $date = self::format_date( $user->timestamp, true );
213
 
214
  if ( current_user_can( 'edit_users' ) || false === strpos( $user->page_url, 'wp-admin' ) ) {
@@ -224,36 +224,39 @@ class UserOnline_Template {
224
  return $output;
225
  }
226
 
227
- private function format_link($url, $title) {
228
  if ( !empty($url) )
229
- return '[' . html_link( esc_url($url), $title ) . ']';
230
 
231
  return '';
232
  }
233
 
234
- function format_ip( $ip ) {
235
- if ( current_user_can( 'edit_users' ) && !empty( $ip ) && $ip != 'unknown' )
 
 
236
  return
237
  html( 'span', array('dir' => 'ltr'),
238
  html( 'a', array(
239
  'href' => 'http://whois.domaintools.com/' . $ip,
240
- 'title' => gethostbyaddr( $ip ),
241
  ), $ip )
242
  );
 
243
  }
244
 
245
- function format_date( $date, $mysql = false ) {
246
  if ( $mysql )
247
  return mysql2date( sprintf( __( '%s @ %s', 'wp-useronline' ), get_option( 'date_format' ), get_option( 'time_format' ) ), $date, true );
248
 
249
  return date_i18n( sprintf( __( '%s @ %s', 'wp-useronline' ), get_option( 'date_format' ), get_option( 'time_format' ) ), $date );
250
  }
251
 
252
- function format_name( $user ) {
253
  return apply_filters( 'useronline_display_user', esc_html( $user->user_name ), $user );
254
  }
255
 
256
- function format_count( $count, $user_type, $template = false ) {
257
  $i = ( $count == 1 ) ? '' : 's';
258
  $string = UserOnline_Core::$options->naming[$user_type . $i];
259
 
@@ -265,14 +268,14 @@ class UserOnline_Template {
265
  return str_ireplace( '%USERS%', $output, $template );
266
  }
267
 
268
- function format_most_users() {
269
  return sprintf( __( 'Most users ever online were <strong>%s</strong>, on <strong>%s</strong>', 'wp-useronline' ),
270
  number_format_i18n( get_most_users_online() ),
271
  get_most_users_online_date()
272
  );
273
  }
274
 
275
- function get_counts( $buckets ) {
276
  $counts = array();
277
  $total = 0;
278
  foreach ( array( 'member', 'guest', 'bot' ) as $user_type )
108
 
109
  private static $cache = array();
110
 
111
+ static function compact_list( $type, $output = 'html', $page_url = '') {
112
  UserOnline_Core::$add_script = true;
113
 
114
  if ( !isset( self::$cache[$type] ) ) {
183
  return $output;
184
  }
185
 
186
+ static function detailed_list( $counts, $user_buckets, $nicetexts ) {
187
  UserOnline_Core::$add_script = true;
188
 
189
  if ( $counts['user'] == 0 )
208
  foreach ( $users as $user ) {
209
  $nr = number_format_i18n( $i++ );
210
  $name = self::format_name( $user );
211
+ $user_ip = self::format_ip( $user );
212
  $date = self::format_date( $user->timestamp, true );
213
 
214
  if ( current_user_can( 'edit_users' ) || false === strpos( $user->page_url, 'wp-admin' ) ) {
224
  return $output;
225
  }
226
 
227
+ static private function format_link($url, $title) {
228
  if ( !empty($url) )
229
+ return '[' . html_link( $url, $title ) . ']';
230
 
231
  return '';
232
  }
233
 
234
+ static function format_ip( $user ) {
235
+ $ip = $user->user_ip;
236
+
237
+ if ( current_user_can( 'edit_users' ) && !empty( $ip ) && $ip != 'unknown' ) {
238
  return
239
  html( 'span', array('dir' => 'ltr'),
240
  html( 'a', array(
241
  'href' => 'http://whois.domaintools.com/' . $ip,
242
+ 'title' => $user->user_agent
243
  ), $ip )
244
  );
245
+ }
246
  }
247
 
248
+ static function format_date( $date, $mysql = false ) {
249
  if ( $mysql )
250
  return mysql2date( sprintf( __( '%s @ %s', 'wp-useronline' ), get_option( 'date_format' ), get_option( 'time_format' ) ), $date, true );
251
 
252
  return date_i18n( sprintf( __( '%s @ %s', 'wp-useronline' ), get_option( 'date_format' ), get_option( 'time_format' ) ), $date );
253
  }
254
 
255
+ static function format_name( $user ) {
256
  return apply_filters( 'useronline_display_user', esc_html( $user->user_name ), $user );
257
  }
258
 
259
+ static function format_count( $count, $user_type, $template = false ) {
260
  $i = ( $count == 1 ) ? '' : 's';
261
  $string = UserOnline_Core::$options->naming[$user_type . $i];
262
 
268
  return str_ireplace( '%USERS%', $output, $template );
269
  }
270
 
271
+ static function format_most_users() {
272
  return sprintf( __( 'Most users ever online were <strong>%s</strong>, on <strong>%s</strong>', 'wp-useronline' ),
273
  number_format_i18n( get_most_users_online() ),
274
  get_most_users_online_date()
275
  );
276
  }
277
 
278
+ static function get_counts( $buckets ) {
279
  $counts = array();
280
  $total = 0;
281
  foreach ( array( 'member', 'guest', 'bot' ) as $user_type )
wp-useronline.php CHANGED
@@ -1,10 +1,12 @@
1
  <?php
2
  /*
3
  Plugin Name: WP-UserOnline
4
- Plugin URI: http://wordpress.org/extend/plugins/wp-useronline/
5
  Description: Enable you to display how many users are online on your Wordpress site
6
- Version: 2.82
7
  Author: Lester 'GaMerZ' Chan & scribu
 
 
8
  */
9
 
10
  @include dirname( __FILE__ ) . '/scb/load.php';
1
  <?php
2
  /*
3
  Plugin Name: WP-UserOnline
4
+ Plugin URI: http://lesterchan.net/portfolio/programming/php/
5
  Description: Enable you to display how many users are online on your Wordpress site
6
+ Version: 2.83
7
  Author: Lester 'GaMerZ' Chan & scribu
8
+ Author URI: http://lesterchan.net
9
+ Text Domain: wp-useronline
10
  */
11
 
12
  @include dirname( __FILE__ ) . '/scb/load.php';