WP-PageNavi - Version 2.80

Version Description

  • support for multi-part pages and user queries
  • moved prev/next links before/after first/last links
  • more info
Download this release

Release Info

Developer scribu
Plugin Icon WP-PageNavi
Version 2.80
Comparing to
See all releases

Code changes from version 2.74 to 2.80

core.php CHANGED
@@ -25,16 +25,13 @@ function wp_pagenavi( $args = array() ) {
25
  extract( $args, EXTR_SKIP );
26
  }
27
 
28
- $options = wp_parse_args( $options, PageNavi_Core::$options->get() );
29
 
30
- $posts_per_page = intval( $query->get( 'posts_per_page' ) );
31
- $paged = max( 1, absint( $query->get( 'paged' ) ) );
32
- $total_pages = max( 1, absint( $query->max_num_pages ) );
33
 
34
  if ( 1 == $total_pages && !$options['always_show'] )
35
  return;
36
 
37
- $request = $query->request;
38
  $numposts = $query->found_posts;
39
 
40
  $pages_to_show = absint( $options['num_pages'] );
@@ -65,6 +62,7 @@ function wp_pagenavi( $args = array() ) {
65
  switch ( intval( $options['style'] ) ) {
66
  // Normal
67
  case 1:
 
68
  if ( !empty( $options['pages_text'] ) ) {
69
  $pages_text = str_replace(
70
  array( "%CURRENT_PAGE%", "%TOTAL_PAGES%" ),
@@ -74,13 +72,19 @@ function wp_pagenavi( $args = array() ) {
74
  }
75
 
76
  if ( $start_page >= 2 && $pages_to_show < $total_pages ) {
 
77
  $first_text = str_replace( '%TOTAL_PAGES%', number_format_i18n( $total_pages ), $options['first_text'] );
78
  $out .= _wp_pagenavi_single( 1, 'first', $first_text, '%TOTAL_PAGES%' );
79
 
 
 
 
 
80
  if ( !empty( $options['dotleft_text'] ) )
81
  $out .= "<span class='extend'>{$options['dotleft_text']}</span>";
82
  }
83
 
 
84
  $larger_pages_array = array();
85
  if ( $larger_page_multiple )
86
  for ( $i = $larger_page_multiple; $i <= $total_pages; $i+= $larger_page_multiple )
@@ -88,15 +92,16 @@ function wp_pagenavi( $args = array() ) {
88
 
89
  $larger_page_start = 0;
90
  foreach ( $larger_pages_array as $larger_page ) {
91
- if ( $larger_page < $start_page && $larger_page_start < $larger_page_to_show ) {
92
  $out .= _wp_pagenavi_single( $larger_page, 'smaller page', $options['page_text'] );
93
  $larger_page_start++;
94
  }
95
  }
96
 
97
- if ( !empty( $options['prev_text'] ) )
98
- $out .= get_previous_posts_link( $options['prev_text'] );
99
 
 
100
  $timeline = 'smaller';
101
  foreach ( range( $start_page, $end_page ) as $i ) {
102
  if ( $i == $paged && !empty( $options['current_text'] ) ) {
@@ -108,21 +113,30 @@ function wp_pagenavi( $args = array() ) {
108
  }
109
  }
110
 
111
- if ( !empty( $options['next_text'] ) )
112
- $out .= get_next_posts_link( $options['next_text'], $total_pages );
113
-
114
  $larger_page_end = 0;
 
115
  foreach ( $larger_pages_array as $larger_page ) {
116
- if ( $larger_page > $end_page && $larger_page_end < $larger_page_to_show ) {
117
- $out .= _wp_pagenavi_single( $larger_page, 'larger page', $options['page_text'] );
118
  $larger_page_end++;
119
  }
120
  }
121
 
 
 
 
 
 
122
  if ( $end_page < $total_pages ) {
123
  if ( !empty( $options['dotright_text'] ) )
124
  $out .= "<span class='extend'>{$options['dotright_text']}</span>";
125
 
 
 
 
 
 
126
  $out .= _wp_pagenavi_single( $total_pages, 'last', $options['last_text'], '%TOTAL_PAGES%' );
127
  }
128
  break;
@@ -139,10 +153,10 @@ function wp_pagenavi( $args = array() ) {
139
 
140
  if ( $i == $paged ) {
141
  $current_page_text = str_replace( '%PAGE_NUMBER%', number_format_i18n( $i ), $options['current_text'] );
142
- $out .= '<option value="'.esc_url( get_pagenum_link( $page_num ) ).'" selected="selected" class="current">'.$current_page_text."</option>\n";
143
  } else {
144
  $page_text = str_replace( '%PAGE_NUMBER%', number_format_i18n( $i ), $options['page_text'] );
145
- $out .= '<option value="'.esc_url( get_pagenum_link( $page_num ) ).'">'.$page_text."</option>\n";
146
  }
147
  }
148
 
@@ -155,17 +169,68 @@ function wp_pagenavi( $args = array() ) {
155
  echo apply_filters( 'wp_pagenavi', $out );
156
  }
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  function _wp_pagenavi_single( $page, $class, $raw_text, $format = '%PAGE_NUMBER%' ) {
159
  if ( empty( $raw_text ) )
160
  return '';
161
 
162
  $text = str_replace( $format, number_format_i18n( $page ), $raw_text );
163
 
164
- return "<a href='" . esc_url( get_pagenum_link( $page ) ) . "' class='$class'>$text</a>";
 
 
 
 
 
 
 
165
  }
166
 
 
 
 
 
167
 
168
- // Template tag: Drop Down Menu ( Deprecated )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  function wp_pagenavi_dropdown() {
170
  wp_pagenavi();
171
  }
@@ -178,31 +243,20 @@ class PageNavi_Core {
178
  self::$options = $options;
179
 
180
  add_action( 'wp_print_styles', array( __CLASS__, 'stylesheets' ) );
181
-
182
- add_filter( 'previous_posts_link_attributes', array( __CLASS__, 'previous_posts_link_attributes' ) );
183
- add_filter( 'next_posts_link_attributes', array( __CLASS__, 'next_posts_link_attributes' ) );
184
  }
185
 
186
  function stylesheets() {
187
  if ( !self::$options->use_pagenavi_css )
188
  return;
189
 
190
- if ( @file_exists( STYLESHEETPATH . '/pagenavi-css.css' ) )
191
  $css_file = get_stylesheet_directory_uri() . '/pagenavi-css.css';
192
- elseif ( @file_exists( TEMPLATEPATH . '/pagenavi-css.css' ) )
193
  $css_file = get_template_directory_uri() . '/pagenavi-css.css';
194
  else
195
  $css_file = plugins_url( 'pagenavi-css.css', __FILE__ );
196
 
197
  wp_enqueue_style( 'wp-pagenavi', $css_file, false, '2.70' );
198
  }
199
-
200
- function previous_posts_link_attributes() {
201
- return 'class="previouspostslink"';
202
- }
203
-
204
- function next_posts_link_attributes() {
205
- return 'class="nextpostslink"';
206
- }
207
  }
208
 
25
  extract( $args, EXTR_SKIP );
26
  }
27
 
28
+ list( $posts_per_page, $paged, $total_pages ) = _wp_pagenavi_get_args( $query );
29
 
30
+ $options = wp_parse_args( $options, PageNavi_Core::$options->get() );
 
 
31
 
32
  if ( 1 == $total_pages && !$options['always_show'] )
33
  return;
34
 
 
35
  $numposts = $query->found_posts;
36
 
37
  $pages_to_show = absint( $options['num_pages'] );
62
  switch ( intval( $options['style'] ) ) {
63
  // Normal
64
  case 1:
65
+ // Text
66
  if ( !empty( $options['pages_text'] ) ) {
67
  $pages_text = str_replace(
68
  array( "%CURRENT_PAGE%", "%TOTAL_PAGES%" ),
72
  }
73
 
74
  if ( $start_page >= 2 && $pages_to_show < $total_pages ) {
75
+ // First
76
  $first_text = str_replace( '%TOTAL_PAGES%', number_format_i18n( $total_pages ), $options['first_text'] );
77
  $out .= _wp_pagenavi_single( 1, 'first', $first_text, '%TOTAL_PAGES%' );
78
 
79
+ // Previous
80
+ if ( $paged > 1 && !empty( $options['prev_text'] ) )
81
+ $out .= _wp_pagenavi_single( $paged - 1, 'previouspostslink', $options['prev_text'] );
82
+
83
  if ( !empty( $options['dotleft_text'] ) )
84
  $out .= "<span class='extend'>{$options['dotleft_text']}</span>";
85
  }
86
 
87
+ // Smaller pages
88
  $larger_pages_array = array();
89
  if ( $larger_page_multiple )
90
  for ( $i = $larger_page_multiple; $i <= $total_pages; $i+= $larger_page_multiple )
92
 
93
  $larger_page_start = 0;
94
  foreach ( $larger_pages_array as $larger_page ) {
95
+ if ( $larger_page < ($start_page - $half_page_start) && $larger_page_start < $larger_page_to_show ) {
96
  $out .= _wp_pagenavi_single( $larger_page, 'smaller page', $options['page_text'] );
97
  $larger_page_start++;
98
  }
99
  }
100
 
101
+ if ( $larger_page_start )
102
+ $out .= "<span class='extend'>{$options['dotleft_text']}</span>";
103
 
104
+ // Page numbers
105
  $timeline = 'smaller';
106
  foreach ( range( $start_page, $end_page ) as $i ) {
107
  if ( $i == $paged && !empty( $options['current_text'] ) ) {
113
  }
114
  }
115
 
116
+ // Large pages
 
 
117
  $larger_page_end = 0;
118
+ $larger_page_out = '';
119
  foreach ( $larger_pages_array as $larger_page ) {
120
+ if ( $larger_page > ($end_page + $half_page_end) && $larger_page_end < $larger_page_to_show ) {
121
+ $larger_page_out .= _wp_pagenavi_single( $larger_page, 'larger page', $options['page_text'] );
122
  $larger_page_end++;
123
  }
124
  }
125
 
126
+ if ( $larger_page_out ) {
127
+ $out .= "<span class='extend'>{$options['dotright_text']}</span>";
128
+ }
129
+ $out .= $larger_page_out;
130
+
131
  if ( $end_page < $total_pages ) {
132
  if ( !empty( $options['dotright_text'] ) )
133
  $out .= "<span class='extend'>{$options['dotright_text']}</span>";
134
 
135
+ // Next
136
+ if ( $paged < $total_pages && !empty( $options['next_text'] ) )
137
+ $out .= _wp_pagenavi_single( $paged + 1, 'nextpostslink', $options['next_text'] );
138
+
139
+ // Last
140
  $out .= _wp_pagenavi_single( $total_pages, 'last', $options['last_text'], '%TOTAL_PAGES%' );
141
  }
142
  break;
153
 
154
  if ( $i == $paged ) {
155
  $current_page_text = str_replace( '%PAGE_NUMBER%', number_format_i18n( $i ), $options['current_text'] );
156
+ $out .= '<option value="'.esc_url( _wp_pagenavi_get_url( $page_num ) ).'" selected="selected" class="current">'.$current_page_text."</option>\n";
157
  } else {
158
  $page_text = str_replace( '%PAGE_NUMBER%', number_format_i18n( $i ), $options['page_text'] );
159
+ $out .= '<option value="'.esc_url( _wp_pagenavi_get_url( $page_num ) ).'">'.$page_text."</option>\n";
160
  }
161
  }
162
 
169
  echo apply_filters( 'wp_pagenavi', $out );
170
  }
171
 
172
+ // This does the messy job of extracting the necessary information from $wp_query
173
+ function _wp_pagenavi_get_args( $query ) {
174
+ global $wp, $page, $numpages, $multipage;
175
+
176
+ if ( $multipage ) {
177
+ // Multipart page
178
+ $posts_per_page = 1;
179
+ $paged = max( 1, absint( $query->get( 'page' ) ) );
180
+ $total_pages = max( 1, $numpages );
181
+ } elseif ( isset( $query->total_users ) ) {
182
+ // WP_User_Query
183
+ $posts_per_page = $query->query_vars['number'];
184
+ $paged = max( 1, floor( $query->query_vars['offset'] / $posts_per_page ) + 1 );
185
+ $total_pages = max( 1, ceil( $query->total_users / $posts_per_page ) );
186
+ } else {
187
+ // WP_Query
188
+ $posts_per_page = intval( $query->get( 'posts_per_page' ) );
189
+ $paged = max( 1, absint( $query->get( 'paged' ) ) );
190
+ $total_pages = max( 1, absint( $query->max_num_pages ) );
191
+ }
192
+
193
+ return array( $posts_per_page, $paged, $total_pages );
194
+ }
195
+
196
+ // This outputs a single page link
197
  function _wp_pagenavi_single( $page, $class, $raw_text, $format = '%PAGE_NUMBER%' ) {
198
  if ( empty( $raw_text ) )
199
  return '';
200
 
201
  $text = str_replace( $format, number_format_i18n( $page ), $raw_text );
202
 
203
+ return "<a href='" . esc_url( _wp_pagenavi_get_url( $page ) ) . "' class='$class'>$text</a>";
204
+ }
205
+
206
+ // This gets the correct URL, either for an archive page or a multipage
207
+ function _wp_pagenavi_get_url( $page ) {
208
+ global $multipage;
209
+
210
+ return $multipage ? get_multipage_link( $page ) : get_pagenum_link( $page );
211
  }
212
 
213
+ # http://core.trac.wordpress.org/ticket/16973
214
+ if ( !function_exists( 'get_multipage_link' ) ) :
215
+ function get_multipage_link( $page = 1 ) {
216
+ global $post, $wp_rewrite;
217
 
218
+ if ( 1 == $page ) {
219
+ $url = get_permalink();
220
+ } else {
221
+ if ( '' == get_option('permalink_structure') || in_array( $post->post_status, array( 'draft', 'pending') ) )
222
+ $url = add_query_arg( 'page', $page, get_permalink() );
223
+ elseif ( 'page' == get_option( 'show_on_front' ) && get_option('page_on_front') == $post->ID )
224
+ $url = trailingslashit( get_permalink() ) . user_trailingslashit( $wp_rewrite->pagination_base . "/$page", 'single_paged' );
225
+ else
226
+ $url = trailingslashit( get_permalink() ) . user_trailingslashit( $page, 'single_paged' );
227
+ }
228
+
229
+ return $url;
230
+ }
231
+ endif;
232
+
233
+ // Template tag: Drop Down Menu (Deprecated)
234
  function wp_pagenavi_dropdown() {
235
  wp_pagenavi();
236
  }
243
  self::$options = $options;
244
 
245
  add_action( 'wp_print_styles', array( __CLASS__, 'stylesheets' ) );
 
 
 
246
  }
247
 
248
  function stylesheets() {
249
  if ( !self::$options->use_pagenavi_css )
250
  return;
251
 
252
+ if ( @file_exists( get_stylesheet_directory() . '/pagenavi-css.css' ) )
253
  $css_file = get_stylesheet_directory_uri() . '/pagenavi-css.css';
254
+ elseif ( @file_exists( get_template_directory() . '/pagenavi-css.css' ) )
255
  $css_file = get_template_directory_uri() . '/pagenavi-css.css';
256
  else
257
  $css_file = plugins_url( 'pagenavi-css.css', __FILE__ );
258
 
259
  wp_enqueue_style( 'wp-pagenavi', $css_file, false, '2.70' );
260
  }
 
 
 
 
 
 
 
 
261
  }
262
 
lang/wp-pagenavi-ar.mo ADDED
Binary file
lang/wp-pagenavi-ar.po ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of the WordPress plugin WP-PageNavi 2.73 by Lester 'GaMerZ' Chan & scribu.
2
+ # Copyright (C) 2010 Lester 'GaMerZ' Chan & scribu
3
+ # This file is distributed under the same license as the WP-PageNavi package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
5
+ #
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: WP-PageNavi 2.73\n"
9
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-pagenavi\n"
10
+ "POT-Creation-Date: 2010-08-17 17:28+0300\n"
11
+ "PO-Revision-Date: 2011-08-21 06:58+0400\n"
12
+ "Last-Translator: yaser mohammed ahmed <fubu_sss_05@hotmail.com>\n"
13
+ "Language-Team: Englize.com - Yaser Maadan <yaser@englize.com>\n"
14
+ "MIME-Version: 1.0\n"
15
+ "Content-Type: text/plain; charset=UTF-8\n"
16
+ "Content-Transfer-Encoding: 8bit\n"
17
+ "X-Poedit-Language: Arabic\n"
18
+ "X-Poedit-Country: UNITED ARAB EMIRATES\n"
19
+
20
+ #: admin.php:9
21
+ msgid "PageNavi Settings"
22
+ msgstr "إعدادات الإضافة"
23
+
24
+ #: admin.php:10
25
+ msgid "PageNavi"
26
+ msgstr "PageNavi"
27
+
28
+ #: admin.php:28
29
+ msgid "Text For Number Of Pages"
30
+ msgstr "نص عدد الصفحات"
31
+
32
+ #: admin.php:33
33
+ msgid "The current page number."
34
+ msgstr "رقم الصفحة الحالية."
35
+
36
+ #: admin.php:34
37
+ #: admin.php:58
38
+ #: admin.php:66
39
+ msgid "The total number of pages."
40
+ msgstr "إجمالي عدد الصفحات."
41
+
42
+ #: admin.php:38
43
+ msgid "Text For Current Page"
44
+ msgstr "نص الصفحة الحالية"
45
+
46
+ #: admin.php:42
47
+ #: admin.php:50
48
+ msgid "The page number."
49
+ msgstr "رقم الصفحة."
50
+
51
+ #: admin.php:46
52
+ msgid "Text For Page"
53
+ msgstr "نص للصفحة"
54
+
55
+ #: admin.php:54
56
+ msgid "Text For First Page"
57
+ msgstr "نص الصفحة الأولى"
58
+
59
+ #: admin.php:62
60
+ msgid "Text For Last Page"
61
+ msgstr "نص الصفحة الأخيرة"
62
+
63
+ #: admin.php:70
64
+ msgid "Text For Previous Page"
65
+ msgstr "نص الصفحة السابقة"
66
+
67
+ #: admin.php:76
68
+ msgid "Text For Next Page"
69
+ msgstr "نص الصفحة التالية"
70
+
71
+ #: admin.php:82
72
+ msgid "Text For Previous ..."
73
+ msgstr "نص (السابق ...)"
74
+
75
+ #: admin.php:88
76
+ msgid "Text For Next ..."
77
+ msgstr "نص (التالي ...)"
78
+
79
+ #: admin.php:95
80
+ msgid "Page Navigation Text"
81
+ msgstr "نص عارض الصفحات"
82
+
83
+ #: admin.php:96
84
+ msgid "Leaving a field blank will hide that part of the navigation."
85
+ msgstr "ترك الحقل فارغاً سيؤدي إلى اخفاءه."
86
+
87
+ #: admin.php:102
88
+ msgid "Use pagenavi-css.css"
89
+ msgstr "استخدم pagenavi-css.css"
90
+
91
+ #: admin.php:108
92
+ msgid "Page Navigation Style"
93
+ msgstr "نمط عارض الصفحات"
94
+
95
+ #: admin.php:111
96
+ msgid "Normal"
97
+ msgstr "عادي"
98
+
99
+ #: admin.php:111
100
+ msgid "Drop-down List"
101
+ msgstr "قائمة منسدلة"
102
+
103
+ #: admin.php:116
104
+ msgid "Always Show Page Navigation"
105
+ msgstr "قم دائماً بعرض عارض الصفحات"
106
+
107
+ #: admin.php:119
108
+ msgid "Show navigation even if there's only one page."
109
+ msgstr "إظهار عارض الصفحات حتى لو كانت صفحة واحدة."
110
+
111
+ #: admin.php:123
112
+ msgid "Number Of Pages To Show"
113
+ msgstr "عدد الصفحات للعرض"
114
+
115
+ #: admin.php:130
116
+ msgid "Number Of Larger Page Numbers To Show"
117
+ msgstr "أكبر عدد عادي للصفحة تريد عرضه"
118
+
119
+ #: admin.php:135
120
+ msgid "Larger page numbers are in addition to the normal page numbers. They are useful when there are many pages of posts."
121
+ msgstr "أكبر عدد من الصفحات الذي سيعرض بشكل عادي وتسلسلي. سيكون مناسباً عندما يكون هناك عدد كبير من الصفحات ."
122
+
123
+ #: admin.php:136
124
+ msgid "For example, WP-PageNavi will display: Pages 1, 2, 3, 4, 5, 10, 20, 30, 40, 50."
125
+ msgstr "مثل: ستقوم الإضافة بعرض الصفحات هكذا: 1، 2، 3، 5، 10، 20، 30، 40، 50."
126
+
127
+ #: admin.php:137
128
+ msgid "Enter 0 to disable."
129
+ msgstr "أدخل 0 للتعطيل."
130
+
131
+ #: admin.php:141
132
+ msgid "Show Larger Page Numbers In Multiples Of"
133
+ msgstr "أعرض أرقام الصفحات الأكبر بمضاعفات الرقم:"
134
+
135
+ #: admin.php:146
136
+ msgid "For example, if mutiple is 5, it will show: 5, 10, 15, 20, 25"
137
+ msgstr "على سبيل المثال، إذا اخترت عرض مضاعفات الـ5، سيعرض لك: 5، 10، 15، 20، 25"
138
+
139
+ #: admin.php:151
140
+ msgid "Page Navigation Options"
141
+ msgstr "إعدادات عارض الصفحات"
142
+
143
+ #: scb/AdminPage.php:167
144
+ msgid "Settings <strong>saved</strong>."
145
+ msgstr "الإعدادات <strong>حفظت</strong>."
146
+
147
+ #: scb/AdminPage.php:179
148
+ #: scb/AdminPage.php:189
149
+ msgid "Save Changes"
150
+ msgstr "حفظ الإعدادات"
151
+
152
+ #: scb/AdminPage.php:371
153
+ msgid "Settings"
154
+ msgstr "الإعدادات"
155
+
156
+ #: wp-pagenavi.php:37
157
+ msgid "Page %CURRENT_PAGE% of %TOTAL_PAGES%"
158
+ msgstr "صفحة %CURRENT_PAGE% من %TOTAL_PAGES%"
159
+
160
+ #: wp-pagenavi.php:40
161
+ msgid "&laquo; First"
162
+ msgstr "&laquo; الأولى"
163
+
164
+ #: wp-pagenavi.php:41
165
+ msgid "Last &raquo;"
166
+ msgstr "آخر &raquo;"
167
+
168
+ #: wp-pagenavi.php:42
169
+ msgid "&laquo;"
170
+ msgstr "&laquo;"
171
+
172
+ #: wp-pagenavi.php:43
173
+ msgid "&raquo;"
174
+ msgstr "&raquo;"
175
+
176
+ #: wp-pagenavi.php:44
177
+ #: wp-pagenavi.php:45
178
+ msgid "..."
179
+ msgstr "..."
180
+
181
+ #. Plugin Name of the plugin/theme
182
+ msgid "WP-PageNavi"
183
+ msgstr "WP-PageNavi"
184
+
185
+ #. Plugin URI of the plugin/theme
186
+ msgid "http://wordpress.org/extend/plugins/wp-pagenavi/"
187
+ msgstr "http://wordpress.org/extend/plugins/wp-pagenavi/"
188
+
189
+ #. Description of the plugin/theme
190
+ msgid "Adds a more advanced paging navigation to your WordPress blog"
191
+ msgstr "أضف المزيد من "
192
+
193
+ #. Author of the plugin/theme
194
+ msgid "Lester 'GaMerZ' Chan & scribu"
195
+ msgstr "Lester 'GaMerZ' Chan & scribu"
196
+
lang/wp-pagenavi-ua_UA.mo ADDED
Binary file
lang/wp-pagenavi-ua_UA.po ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of the WordPress plugin WP-PageNavi 2.73 by Lester 'GaMerZ' Chan & scribu.
2
+ # Copyright (C) 2010 Lester 'GaMerZ' Chan & scribu
3
+ # This file is distributed under the same license as the WP-PageNavi package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
5
+ #
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: WP-PageNavi 2.73\n"
9
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-pagenavi\n"
10
+ "POT-Creation-Date: 2010-08-17 17:28+0300\n"
11
+ "PO-Revision-Date: 2011-10-30 12:50+0200\n"
12
+ "Last-Translator: bohgdan zograf <bozograf@gmail.com>\n"
13
+ "Language-Team: Itransition <djsoldier1988@gmail.com>\n"
14
+ "MIME-Version: 1.0\n"
15
+ "Content-Type: text/plain; charset=utf-8\n"
16
+ "Content-Transfer-Encoding: 8bit\n"
17
+ "X-Poedit-Language: Ukrainian\n"
18
+ "X-Poedit-Country: UKRAINE\n"
19
+
20
+ #: admin.php:9
21
+ msgid "PageNavi Settings"
22
+ msgstr "PageNavi Настройки"
23
+
24
+ #: admin.php:10
25
+ msgid "PageNavi"
26
+ msgstr "PageNavi"
27
+
28
+ #: admin.php:28
29
+ msgid "Text For Number Of Pages"
30
+ msgstr "Текст Для Кількість сторінок"
31
+
32
+ #: admin.php:33
33
+ msgid "The current page number."
34
+ msgstr "Номер поточної сторінки."
35
+
36
+ #: admin.php:34
37
+ #: admin.php:58
38
+ #: admin.php:66
39
+ msgid "The total number of pages."
40
+ msgstr "Загальна кількість сторінок."
41
+
42
+ #: admin.php:38
43
+ msgid "Text For Current Page"
44
+ msgstr "Текст Для поточну сторінку"
45
+
46
+ #: admin.php:42
47
+ #: admin.php:50
48
+ msgid "The page number."
49
+ msgstr "Номер сторінки."
50
+
51
+ #: admin.php:46
52
+ msgid "Text For Page"
53
+ msgstr "Текст Для сторінку"
54
+
55
+ #: admin.php:54
56
+ msgid "Text For First Page"
57
+ msgstr "Текст Для першої сторінки"
58
+
59
+ #: admin.php:62
60
+ msgid "Text For Last Page"
61
+ msgstr "Текст Для Остання сторінка"
62
+
63
+ #: admin.php:70
64
+ msgid "Text For Previous Page"
65
+ msgstr "Текст Для попередню сторінку"
66
+
67
+ #: admin.php:76
68
+ msgid "Text For Next Page"
69
+ msgstr "Текст Для Наступна сторінка"
70
+
71
+ #: admin.php:82
72
+ msgid "Text For Previous ..."
73
+ msgstr "Текст Для Попередня..."
74
+
75
+ #: admin.php:88
76
+ msgid "Text For Next ..."
77
+ msgstr "Текст Для Далі..."
78
+
79
+ #: admin.php:95
80
+ msgid "Page Navigation Text"
81
+ msgstr "Page Navigation Текст"
82
+
83
+ #: admin.php:96
84
+ msgid "Leaving a field blank will hide that part of the navigation."
85
+ msgstr "Залишаючи поле порожнім, буде приховувати, що частина навігації."
86
+
87
+ #: admin.php:102
88
+ msgid "Use pagenavi-css.css"
89
+ msgstr "Використовуйте PageNavi - css.css"
90
+
91
+ #: admin.php:108
92
+ msgid "Page Navigation Style"
93
+ msgstr "Page Navigation Стиль"
94
+
95
+ #: admin.php:111
96
+ msgid "Normal"
97
+ msgstr "нормальний"
98
+
99
+ #: admin.php:111
100
+ msgid "Drop-down List"
101
+ msgstr "Список, що розкривається"
102
+
103
+ #: admin.php:116
104
+ msgid "Always Show Page Navigation"
105
+ msgstr "Завжди показувати панель навігації"
106
+
107
+ #: admin.php:119
108
+ msgid "Show navigation even if there's only one page."
109
+ msgstr "Показати навігації, навіть якщо є тільки одна сторінка."
110
+
111
+ #: admin.php:123
112
+ msgid "Number Of Pages To Show"
113
+ msgstr "Число сторінок Показати"
114
+
115
+ #: admin.php:130
116
+ msgid "Number Of Larger Page Numbers To Show"
117
+ msgstr "Кількість великих чисел сторінку Щоб показати"
118
+
119
+ #: admin.php:135
120
+ msgid "Larger page numbers are in addition to the normal page numbers. They are useful when there are many pages of posts."
121
+ msgstr "Великі номери сторінок на додаток до звичайної номери сторінок. Вони корисні, коли Є багато сторінок повідомлень."
122
+
123
+ #: admin.php:136
124
+ msgid "For example, WP-PageNavi will display: Pages 1, 2, 3, 4, 5, 10, 20, 30, 40, 50."
125
+ msgstr "Наприклад, WP - PageNavi покаже: сторінки 1, 2, 3, 4, 5, 10, 20, 30, 40, 50."
126
+
127
+ #: admin.php:137
128
+ msgid "Enter 0 to disable."
129
+ msgstr "Введіть 0 для відключення."
130
+
131
+ #: admin.php:141
132
+ msgid "Show Larger Page Numbers In Multiples Of"
133
+ msgstr "Показати Великі номери сторінок, кратним"
134
+
135
+ #: admin.php:146
136
+ msgid "For example, if mutiple is 5, it will show: 5, 10, 15, 20, 25"
137
+ msgstr "Наприклад, якщо Mutiple становить 5, він покаже: 5, 10, 15, 20, 25"
138
+
139
+ #: admin.php:151
140
+ msgid "Page Navigation Options"
141
+ msgstr "Page Navigation параметри"
142
+
143
+ #: scb/AdminPage.php:167
144
+ msgid "Settings <strong>saved</strong>."
145
+ msgstr "Установки <strong> збережені <strong>."
146
+
147
+ #: scb/AdminPage.php:179
148
+ #: scb/AdminPage.php:189
149
+ msgid "Save Changes"
150
+ msgstr "зберегти зміни"
151
+
152
+ #: scb/AdminPage.php:371
153
+ msgid "Settings"
154
+ msgstr "Установки"
155
+
156
+ #: wp-pagenavi.php:37
157
+ msgid "Page %CURRENT_PAGE% of %TOTAL_PAGES%"
158
+ msgstr "сторінка %CURRENT_PAGE% з %TOTAL_PAGES%"
159
+
160
+ #: wp-pagenavi.php:40
161
+ msgid "&laquo; First"
162
+ msgstr "&laquo;перший"
163
+
164
+ #: wp-pagenavi.php:41
165
+ msgid "Last &raquo;"
166
+ msgstr "останній &raquo;"
167
+
168
+ #: wp-pagenavi.php:42
169
+ msgid "&laquo;"
170
+ msgstr "&laquo;"
171
+
172
+ #: wp-pagenavi.php:43
173
+ msgid "&raquo;"
174
+ msgstr "&raquo;"
175
+
176
+ #: wp-pagenavi.php:44
177
+ #: wp-pagenavi.php:45
178
+ msgid "..."
179
+ msgstr "..."
180
+
181
+ #. Plugin Name of the plugin/theme
182
+ msgid "WP-PageNavi"
183
+ msgstr "WP-PageNavi плагин"
184
+
185
+ #. Plugin URI of the plugin/theme
186
+ msgid "http://wordpress.org/extend/plugins/wp-pagenavi/"
187
+ msgstr "http://wordpress.org/extend/plugins/wp-pagenavi/"
188
+
189
+ #. Description of the plugin/theme
190
+ msgid "Adds a more advanced paging navigation to your WordPress blog"
191
+ msgstr "Додає більш просунуті підкачки навігації на ваш блог WordPress"
192
+
193
+ #. Author of the plugin/theme
194
+ msgid "Lester 'GaMerZ' Chan & scribu"
195
+ msgstr "Lester 'GaMerZ' Chan & scribu"
196
+
197
+ msgid "WP-PageNavi"
198
+ msgstr "WP-PageNavi плагин"
199
+
200
+ #. Plugin URI of the plugin/theme
201
+ msgid "http://wordpress.org/extend/plugins/wp-pagenavi/"
202
+ msgstr ""
203
+
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === WP-PageNavi ===
2
  Contributors: GamerZ, scribu
3
  Tags: navigation, pagination, paging, pages
4
- Requires at least: 2.8
5
- Tested up to: 3.1
6
- Stable tag: 2.74
7
 
8
  Adds a more advanced paging navigation interface.
9
 
@@ -37,6 +37,14 @@ You would replace those two lines with this:
37
 
38
  `<?php wp_pagenavi(); ?>`
39
 
 
 
 
 
 
 
 
 
40
  Go to *WP-Admin -> Settings -> PageNavi* for configuration.
41
 
42
  = Changing the CSS =
@@ -74,6 +82,11 @@ You can do that like so:
74
 
75
  == Changelog ==
76
 
 
 
 
 
 
77
  = 2.74 (2011-02-17) =
78
  * added 'smaller' and 'larger' classes
79
  * added $query arg to wp_pagenavi()
1
  === WP-PageNavi ===
2
  Contributors: GamerZ, scribu
3
  Tags: navigation, pagination, paging, pages
4
+ Requires at least: 3.1
5
+ Tested up to: 3.3
6
+ Stable tag: 2.80
7
 
8
  Adds a more advanced paging navigation interface.
9
 
37
 
38
  `<?php wp_pagenavi(); ?>`
39
 
40
+ For multipart pages, you would look for code like this:
41
+
42
+ `<?php wp_link_pages( ... ); ?>`
43
+
44
+ and again replace it with this:
45
+
46
+ `<?php wp_pagenavi(); ?>`
47
+
48
  Go to *WP-Admin -> Settings -> PageNavi* for configuration.
49
 
50
  = Changing the CSS =
82
 
83
  == Changelog ==
84
 
85
+ = 2.80 =
86
+ * support for multi-part pages and user queries
87
+ * moved prev/next links before/after first/last links
88
+ * [more info](http://scribu.net/wordpress/wp-pagenavi/wpn-2-80.html)
89
+
90
  = 2.74 (2011-02-17) =
91
  * added 'smaller' and 'larger' classes
92
  * added $query arg to wp_pagenavi()
scb/AdminPage.php CHANGED
@@ -1,22 +1,21 @@
1
  <?php
2
 
3
- /*
4
- Creates an admin page
5
-
6
- You must set $this->args and define the page_content() method
7
- */
8
 
9
  abstract class scbAdminPage {
10
  /** Page args
11
- * $toplevel string If not empty, will create a new top level menu
12
- * $icon string Path to an icon for the top level menu
13
- * $parent string ( default: options-general.php )
14
- * $capability string ( default: 'manage_options' )
15
- * $page_title string ( mandatory )
16
- * $menu_title string ( default: $page_title )
17
- * $page_slug string ( default: sanitized $page_title )
18
- * $nonce string ( default: $page_slug )
19
- * $action_link string|bool Text of the action link on the Plugins page ( default: 'Settings' )
 
 
 
20
  */
21
  protected $args;
22
 
@@ -97,7 +96,7 @@ abstract class scbAdminPage {
97
  add_action( 'admin_notices', 'settings_errors' );
98
  }
99
 
100
- add_action( 'admin_menu', array( $this, 'page_init' ) );
101
  add_filter( 'contextual_help', array( $this, '_contextual_help' ), 10, 2 );
102
 
103
  if ( $this->args['action_link'] )
@@ -118,7 +117,7 @@ abstract class scbAdminPage {
118
  // A generic page header
119
  function page_header() {
120
  echo "<div class='wrap'>\n";
121
- screen_icon();
122
  echo "<h2>" . $this->args['page_title'] . "</h2>\n";
123
  }
124
 
@@ -147,7 +146,7 @@ abstract class scbAdminPage {
147
  return false;
148
  }
149
 
150
- $new_data = scbUtil::array_extract( $_POST, array_keys( $this->options->get_defaults() ) );
151
 
152
  $new_data = stripslashes_deep( $new_data );
153
 
@@ -173,10 +172,12 @@ abstract class scbAdminPage {
173
  // Generates a form submit button
174
  function submit_button( $value = '', $action = 'action', $class = "button" ) {
175
  if ( is_array( $value ) ) {
176
- extract( wp_parse_args( $value, array( 'value' => __( 'Save Changes', $this->textdomain ),
 
177
  'action' => 'action',
178
  'class' => 'button',
179
- 'ajax' => true ) ) );
 
180
 
181
  if ( ! $ajax )
182
  $class .= ' no-ajax';
@@ -215,7 +216,7 @@ abstract class scbAdminPage {
215
  */
216
  function form_wrap( $content, $submit_button = true ) {
217
  if ( is_array( $submit_button ) ) {
218
- $content .= call_user_func( array( $this, 'submit_button' ), $submit_button );
219
  } elseif ( true === $submit_button ) {
220
  $content .= $this->submit_button();
221
  } elseif ( false !== strpos( $submit_button, '<input' ) ) {
@@ -228,13 +229,8 @@ abstract class scbAdminPage {
228
  return scbForms::form_wrap( $content, $this->nonce );
229
  }
230
 
231
- // See scbForms::form()
232
- function form( $rows, $formdata = array() ) {
233
- return scbForms::form( $rows, $formdata, $this->nonce );
234
- }
235
-
236
  // Generates a table wrapped in a form
237
- function form_table( $rows, $formdata = array() ) {
238
  $output = '';
239
  foreach ( $rows as $row )
240
  $output .= $this->table_row( $row, $formdata );
@@ -247,13 +243,13 @@ abstract class scbAdminPage {
247
  // Wraps the given content in a <form><table>
248
  function form_table_wrap( $content ) {
249
  $output = $this->table_wrap( $content );
250
- $output = $this->form_wrap( $output, $this->nonce );
251
 
252
  return $output;
253
  }
254
 
255
  // Generates a form table
256
- function table( $rows, $formdata = array() ) {
257
  $output = '';
258
  foreach ( $rows as $row )
259
  $output .= $this->table_row( $row, $formdata );
@@ -264,7 +260,7 @@ abstract class scbAdminPage {
264
  }
265
 
266
  // Generates a table row
267
- function table_row( $args, $formdata = array() ) {
268
  return $this->row_wrap( $args['title'], $this->input( $args, $formdata ) );
269
  }
270
 
@@ -276,40 +272,22 @@ abstract class scbAdminPage {
276
 
277
  // Wraps the given content in a <tr><td>
278
  function row_wrap( $title, $content ) {
279
- return
280
- html( 'tr',
281
  html( 'th scope="row"', $title )
282
  .html( 'td', $content ) );
283
  }
284
 
285
- function input( $args, $formdata = array() ) {
286
- if ( empty( $formdata ) && isset( $this->options ) )
287
- $formdata = $this->options->get();
288
-
289
- if ( isset( $args['name_tree'] ) ) {
290
- $tree = ( array ) $args['name_tree'];
291
- unset( $args['name_tree'] );
292
-
293
- $value = $formdata;
294
- $name = $this->option_name;
295
- foreach ( $tree as $key ) {
296
- $value = $value[$key];
297
- $name .= '[' . $key . ']';
298
- }
299
-
300
- $args['name'] = $name;
301
- unset( $args['names'] );
302
-
303
- unset( $args['values'] );
304
 
305
- $formdata = array( $name => $value );
 
306
  }
307
 
308
- return scbForms::input( $args, $formdata );
309
- }
310
-
311
- // Mimic scbForms inheritance
312
- function __call( $method, $args ) {
313
  return call_user_func_array( array( 'scbForms', $method ), $args );
314
  }
315
 
@@ -335,7 +313,7 @@ abstract class scbAdminPage {
335
  $this->pagehook = add_submenu_page( $parent, $page_title, $menu_title, $capability, $page_slug, array( $this, '_page_content_hook' ) );
336
  } else {
337
  $func = 'add_' . $toplevel . '_page';
338
- $this->pagehook = $func( $page_title, $menu_title, $capability, $page_slug, array( $this, '_page_content_hook' ), $icon_url );
339
  }
340
 
341
  if ( ! $this->pagehook )
@@ -357,16 +335,19 @@ abstract class scbAdminPage {
357
  if ( empty( $this->args['page_title'] ) )
358
  trigger_error( 'Page title cannot be empty', E_USER_WARNING );
359
 
360
- $this->args = wp_parse_args( $this->args, array(
361
  'toplevel' => '',
362
- 'icon' => '',
 
 
363
  'parent' => 'options-general.php',
364
  'capability' => 'manage_options',
365
  'menu_title' => $this->args['page_title'],
366
  'page_slug' => '',
367
  'nonce' => '',
368
  'action_link' => __( 'Settings', $this->textdomain ),
369
- 'ajax_submit' => false,
 
370
  ) );
371
 
372
  if ( empty( $this->args['page_slug'] ) )
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
14
+ * - $position (int) Position of the toplevel menu (caution!)
15
+ * $screen_icon (string) The icon type to use in the screen header
16
+ * $nonce string (default: $page_slug)
17
+ * $action_link (string|bool) Text of the action link on the Plugins page (default: 'Settings')
18
+ * $admin_action_priority int The priority that the admin_menu action should be executed at (default: 10)
19
  */
20
  protected $args;
21
 
96
  add_action( 'admin_notices', 'settings_errors' );
97
  }
98
 
99
+ add_action( 'admin_menu', array( $this, 'page_init' ), $this->args['admin_action_priority'] );
100
  add_filter( 'contextual_help', array( $this, '_contextual_help' ), 10, 2 );
101
 
102
  if ( $this->args['action_link'] )
117
  // A generic page header
118
  function page_header() {
119
  echo "<div class='wrap'>\n";
120
+ screen_icon( $this->args['screen_icon'] );
121
  echo "<h2>" . $this->args['page_title'] . "</h2>\n";
122
  }
123
 
146
  return false;
147
  }
148
 
149
+ $new_data = wp_array_slice_assoc( $_POST, array_keys( $this->options->get_defaults() ) );
150
 
151
  $new_data = stripslashes_deep( $new_data );
152
 
172
  // Generates a form submit button
173
  function submit_button( $value = '', $action = 'action', $class = "button" ) {
174
  if ( is_array( $value ) ) {
175
+ extract( wp_parse_args( $value, array(
176
+ 'value' => __( 'Save Changes', $this->textdomain ),
177
  'action' => 'action',
178
  'class' => 'button',
179
+ 'ajax' => true
180
+ ) ) );
181
 
182
  if ( ! $ajax )
183
  $class .= ' no-ajax';
216
  */
217
  function form_wrap( $content, $submit_button = true ) {
218
  if ( is_array( $submit_button ) ) {
219
+ $content .= $this->submit_button( $submit_button );
220
  } elseif ( true === $submit_button ) {
221
  $content .= $this->submit_button();
222
  } elseif ( false !== strpos( $submit_button, '<input' ) ) {
229
  return scbForms::form_wrap( $content, $this->nonce );
230
  }
231
 
 
 
 
 
 
232
  // Generates a table wrapped in a form
233
+ function form_table( $rows, $formdata = false ) {
234
  $output = '';
235
  foreach ( $rows as $row )
236
  $output .= $this->table_row( $row, $formdata );
243
  // Wraps the given content in a <form><table>
244
  function form_table_wrap( $content ) {
245
  $output = $this->table_wrap( $content );
246
+ $output = $this->form_wrap( $output );
247
 
248
  return $output;
249
  }
250
 
251
  // Generates a form table
252
+ function table( $rows, $formdata = false ) {
253
  $output = '';
254
  foreach ( $rows as $row )
255
  $output .= $this->table_row( $row, $formdata );
260
  }
261
 
262
  // Generates a table row
263
+ function table_row( $args, $formdata = false ) {
264
  return $this->row_wrap( $args['title'], $this->input( $args, $formdata ) );
265
  }
266
 
272
 
273
  // Wraps the given content in a <tr><td>
274
  function row_wrap( $title, $content ) {
275
+ return
276
+ html( 'tr',
277
  html( 'th scope="row"', $title )
278
  .html( 'td', $content ) );
279
  }
280
 
281
+ // Mimic scbForms inheritance
282
+ function __call( $method, $args ) {
283
+ if ( in_array( $method, array( 'input', 'form' ) ) ) {
284
+ if ( empty( $args[1] ) && isset( $this->options ) )
285
+ $args[1] = $this->options->get();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
 
287
+ if ( 'form' == $method )
288
+ $args[2] = $this->nonce;
289
  }
290
 
 
 
 
 
 
291
  return call_user_func_array( array( 'scbForms', $method ), $args );
292
  }
293
 
313
  $this->pagehook = add_submenu_page( $parent, $page_title, $menu_title, $capability, $page_slug, array( $this, '_page_content_hook' ) );
314
  } else {
315
  $func = 'add_' . $toplevel . '_page';
316
+ $this->pagehook = $func( $page_title, $menu_title, $capability, $page_slug, array( $this, '_page_content_hook' ), $icon_url, $position );
317
  }
318
 
319
  if ( ! $this->pagehook )
335
  if ( empty( $this->args['page_title'] ) )
336
  trigger_error( 'Page title cannot be empty', E_USER_WARNING );
337
 
338
+ $this->args = wp_parse_args( $this->args, array(
339
  'toplevel' => '',
340
+ 'position' => null,
341
+ 'icon_url' => '',
342
+ 'screen_icon' => '',
343
  'parent' => 'options-general.php',
344
  'capability' => 'manage_options',
345
  'menu_title' => $this->args['page_title'],
346
  'page_slug' => '',
347
  'nonce' => '',
348
  'action_link' => __( 'Settings', $this->textdomain ),
349
+ 'ajax_submit' => false,
350
+ 'admin_action_priority' => 10,
351
  ) );
352
 
353
  if ( empty( $this->args['page_slug'] ) )
scb/BoxesPage.php CHANGED
@@ -1,19 +1,7 @@
1
  <?php
2
 
3
- /*
4
- Creates an admin page with widgets, similar to the dashboard
5
 
6
- For example, if you defined the boxes like this:
7
-
8
- $this->boxes = array( array( 'settings', 'Settings box', 'normal' )
9
- ... );
10
-
11
- You must also define two methods in your class for each box:
12
-
13
- function settings_box() - this is where the box content is echoed
14
- function settings_handler() - this is where the box settings are saved
15
- ...
16
- */
17
  abstract class scbBoxesPage extends scbAdminPage {
18
  /*
19
  A box definition looks like this:
@@ -37,7 +25,6 @@ abstract class scbBoxesPage extends scbAdminPage {
37
  parent::page_init();
38
 
39
  add_action( 'load-' . $this->pagehook, array( $this, 'boxes_init' ) );
40
- add_filter( 'screen_layout_columns', array( $this, 'columns' ) );
41
  }
42
 
43
  function default_css() {
@@ -52,7 +39,6 @@ abstract class scbBoxesPage extends scbAdminPage {
52
  .inside {
53
  clear: both;
54
  overflow: hidden;
55
- padding: 10px 10px 0 !important;
56
  }
57
  .inside table {
58
  margin: 0 !important;
@@ -79,6 +65,7 @@ abstract class scbBoxesPage extends scbAdminPage {
79
  .inside p.submit {
80
  float: left !important;
81
  padding: 0 !important;
 
82
  }
83
  </style>
84
  <?php
@@ -93,34 +80,40 @@ abstract class scbBoxesPage extends scbAdminPage {
93
  $hide2 = $hide3 = $hide4 = '';
94
  switch ( $screen_layout_columns ) {
95
  case 4:
96
- $width = 'width:24.5%;';
 
97
  break;
98
  case 3:
99
- $width = 'width:32.67%;';
 
100
  $hide4 = 'display:none;';
101
  break;
102
  case 2:
103
- $width = 'width:49%;';
 
104
  $hide3 = $hide4 = 'display:none;';
105
  break;
106
  default:
107
- $width = 'width:98%;';
 
108
  $hide2 = $hide3 = $hide4 = 'display:none;';
109
  }
 
 
110
  }
111
  ?>
112
  <div id='<?php echo $this->pagehook ?>-widgets' class='metabox-holder'>
113
  <?php
114
- echo "\t<div class='postbox-container' style='$width'>\n";
115
  do_meta_boxes( $this->pagehook, 'normal', '' );
116
 
117
- echo "\t</div><div class='postbox-container' style='{$hide2}$width'>\n";
118
  do_meta_boxes( $this->pagehook, 'side', '' );
119
 
120
- echo "\t</div><div class='postbox-container' style='{$hide3}$width'>\n";
121
  do_meta_boxes( $this->pagehook, 'column3', '' );
122
 
123
- echo "\t</div><div class='postbox-container' style='{$hide4}$width'>\n";
124
  do_meta_boxes( $this->pagehook, 'column4', '' );
125
  ?>
126
  </div></div>
@@ -149,12 +142,6 @@ abstract class scbBoxesPage extends scbAdminPage {
149
  }
150
  }
151
 
152
- function columns( $columns ) {
153
- $columns[$this->pagehook] = $this->args['columns'];
154
-
155
- return $columns;
156
- }
157
-
158
  function uninstall() {
159
  global $wpdb;
160
 
@@ -172,10 +159,13 @@ abstract class scbBoxesPage extends scbAdminPage {
172
  }
173
 
174
  function boxes_init() {
175
- wp_enqueue_script( 'common' );
176
- wp_enqueue_script( 'wp-lists' );
177
  wp_enqueue_script( 'postbox' );
178
 
 
 
 
 
 
179
  $registered = array();
180
  foreach( $this->boxes as $box_args ) {
181
  @list( $name, $title, $context, $priority, $args ) = $box_args;
@@ -244,3 +234,5 @@ EOT
244
  }
245
  }
246
 
 
 
1
  <?php
2
 
3
+ // Admin screen with metaboxes base class
 
4
 
 
 
 
 
 
 
 
 
 
 
 
5
  abstract class scbBoxesPage extends scbAdminPage {
6
  /*
7
  A box definition looks like this:
25
  parent::page_init();
26
 
27
  add_action( 'load-' . $this->pagehook, array( $this, 'boxes_init' ) );
 
28
  }
29
 
30
  function default_css() {
39
  .inside {
40
  clear: both;
41
  overflow: hidden;
 
42
  }
43
  .inside table {
44
  margin: 0 !important;
65
  .inside p.submit {
66
  float: left !important;
67
  padding: 0 !important;
68
+ margin-bottom: 0 !important;
69
  }
70
  </style>
71
  <?php
80
  $hide2 = $hide3 = $hide4 = '';
81
  switch ( $screen_layout_columns ) {
82
  case 4:
83
+ if( !isset( $this->args['column_widths'] ) )
84
+ $this->args['column_widths'] = array( 24.5, 24.5, 24.5, 24.5 );
85
  break;
86
  case 3:
87
+ if( !isset( $this->args['column_widths'] ) )
88
+ $this->args['column_widths'] = array( 32.67, 32.67, 32.67 );
89
  $hide4 = 'display:none;';
90
  break;
91
  case 2:
92
+ if( !isset( $this->args['column_widths'] ) )
93
+ $this->args['column_widths'] = array( 49, 49 );
94
  $hide3 = $hide4 = 'display:none;';
95
  break;
96
  default:
97
+ if( !isset( $this->args['column_widths'] ) )
98
+ $this->args['column_widths'] = array( 98 );
99
  $hide2 = $hide3 = $hide4 = 'display:none;';
100
  }
101
+
102
+ $this->args['column_widths'] = array_pad( $this->args['column_widths'], 4, 0 );
103
  }
104
  ?>
105
  <div id='<?php echo $this->pagehook ?>-widgets' class='metabox-holder'>
106
  <?php
107
+ echo "\t<div class='postbox-container' style='width:{$this->args['column_widths'][0]}%'>\n";
108
  do_meta_boxes( $this->pagehook, 'normal', '' );
109
 
110
+ echo "\t</div><div class='postbox-container' style='width:{$hide2}{$this->args['column_widths'][1]}%'>\n";
111
  do_meta_boxes( $this->pagehook, 'side', '' );
112
 
113
+ echo "\t</div><div class='postbox-container' style='width:{$hide3}{$this->args['column_widths'][2]}%'>\n";
114
  do_meta_boxes( $this->pagehook, 'column3', '' );
115
 
116
+ echo "\t</div><div class='postbox-container' style='width:{$hide4}{$this->args['column_widths'][3]}%'>\n";
117
  do_meta_boxes( $this->pagehook, 'column4', '' );
118
  ?>
119
  </div></div>
142
  }
143
  }
144
 
 
 
 
 
 
 
145
  function uninstall() {
146
  global $wpdb;
147
 
159
  }
160
 
161
  function boxes_init() {
 
 
162
  wp_enqueue_script( 'postbox' );
163
 
164
+ add_screen_option( 'layout_columns', array(
165
+ 'max' => $this->args['columns'],
166
+ 'default' => $this->args['columns']
167
+ ) );
168
+
169
  $registered = array();
170
  foreach( $this->boxes as $box_args ) {
171
  @list( $name, $title, $context, $priority, $args ) = $box_args;
234
  }
235
  }
236
 
237
+
238
+
scb/Cron.php CHANGED
@@ -1,12 +1,14 @@
1
  <?php
2
 
 
 
3
  class scbCron {
4
  protected $schedule;
5
  protected $interval;
6
  protected $time;
7
 
8
  protected $hook;
9
- protected $callback_args;
10
 
11
  /**
12
  * Create a new cron job
@@ -15,7 +17,7 @@ class scbCron {
15
  * @param array List of args:
16
  string $action OR callback $callback
17
  string $schedule OR number $interval
18
- array $callback_args ( optional )
19
  */
20
  function __construct( $file, $args ) {
21
  extract( $args, EXTR_SKIP );
@@ -45,9 +47,9 @@ class scbCron {
45
  }
46
 
47
  if ( isset( $callback_args ) )
48
- $this->callback_args = ( array ) $callback_args;
49
 
50
- if ( $this->schedule ) {
51
  scbUtil::add_activation_hook( $file, array( $this, 'reset' ) );
52
  register_deactivation_hook( $file, array( $this, 'unschedule' ) );
53
  }
1
  <?php
2
 
3
+ // wp-cron job container
4
+
5
  class scbCron {
6
  protected $schedule;
7
  protected $interval;
8
  protected $time;
9
 
10
  protected $hook;
11
+ protected $callback_args = array();
12
 
13
  /**
14
  * Create a new cron job
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, $args ) {
23
  extract( $args, EXTR_SKIP );
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' ) );
54
  register_deactivation_hook( $file, array( $this, 'unschedule' ) );
55
  }
scb/Forms.php CHANGED
@@ -1,18 +1,15 @@
1
  <?php
2
 
3
- // Documentation: http://scribu.net/wordpress/scb-framework/scb-forms.html
4
 
5
  class scbForms {
6
 
7
  const token = '%input%';
8
 
9
- protected static $args;
10
- protected static $formdata = array();
11
 
12
- static function input( $args, $formdata = array() ) {
13
- $args = self::validate_data( $args );
14
-
15
- $error = false;
16
  foreach ( array( 'name', 'value' ) as $key ) {
17
  $old = $key . 's';
18
 
@@ -22,16 +19,43 @@ class scbForms {
22
  }
23
  }
24
 
 
 
 
 
 
25
  if ( empty( $args['name'] ) )
26
  return trigger_error( 'Empty name', E_USER_WARNING );
27
 
28
- self::$args = $args;
29
- self::$formdata = self::validate_data( $formdata );
 
 
30
 
31
- if ( 'select' == $args['type'] )
32
- return self::_select();
33
- else
34
- return self::_input();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  }
36
 
37
 
@@ -114,134 +138,135 @@ class scbForms {
114
  // ____________PRIVATE METHODS____________
115
 
116
 
117
- // Recursivly transform empty arrays to ''
118
- private static function validate_data( $data ) {
119
- if ( !is_array( $data ) )
120
- return $data;
121
-
122
- if ( empty( $data ) )
123
- return '';
124
 
125
- foreach ( $data as $key => &$value )
126
- $value = self::validate_data( $value );
127
 
128
- return $data;
 
 
 
129
  }
130
 
131
- // From multiple inputs to single inputs
132
- private static function _input() {
133
- extract( wp_parse_args( self::$args, array(
134
- 'name' => NULL,
135
- 'value' => NULL,
136
- 'desc' => NULL,
137
- 'checked' => NULL,
138
- ) ) );
139
 
140
- $m_name = is_array( $name );
141
- $m_value = is_array( $value );
142
- $m_desc = is_array( $desc );
143
 
144
- // Correct name
145
- if ( !$m_name && $m_value
146
- && 'checkbox' == $type
147
- && false === strpos( $name, '[' )
148
- )
149
- $args['name'] = $name = $name . '[]';
150
 
151
- // Expand names or values
152
- if ( !$m_name && !$m_value ) {
153
- $a = array( $name => $value );
154
- }
155
- elseif ( $m_name && !$m_value ) {
156
- $a = array_fill_keys( $name, $value );
157
- }
158
- elseif ( !$m_name && $m_value ) {
159
- $a = array_fill_keys( $value, $name );
160
- }
161
- else {
162
- $a = array_combine( $name, $value );
 
 
 
 
 
163
  }
164
 
165
- // Correct descriptions
166
- $_after = '';
167
- if ( isset( $desc ) && !$m_desc && false === strpos( $desc, self::token ) ) {
168
- if ( $m_value ) {
169
- $_after = $desc;
170
- $args['desc'] = $desc = $value;
171
- }
172
- elseif ( $m_name ) {
173
- $_after = $desc;
174
- $args['desc'] = $desc = $name;
 
175
  }
176
  }
 
177
 
178
- // Determine what goes where
179
- if ( !$m_name && $m_value ) {
180
- $i1 = 'val';
181
- $i2 = 'name';
182
- } else {
183
- $i1 = 'name';
184
- $i2 = 'val';
185
  }
186
 
187
- $func = in_array( $type, array( 'checkbox', 'radio' ) ) ? '_checkbox_single' : '_input_single';
 
 
 
188
 
189
- // Set constant args
190
- $const_args = self::array_extract( self::$args, array( 'type', 'desc_pos', 'checked' ) );
191
- if ( isset( $extra ) ) {
192
- if ( !is_array( $extra ) )
193
- $extra = self::attr_to_array( $extra );
194
- $const_args['extra'] = $extra;
 
195
  }
196
 
197
- $i = 0;
198
- foreach ( $a as $name => $val ) {
199
- $cur_args = $const_args;
200
-
201
- if ( $$i1 !== NULL )
202
- $cur_args['name'] = $$i1;
203
 
204
- if ( $$i2 !== NULL )
205
- $cur_args['value'] = $$i2;
 
 
 
206
 
207
- // Set desc
208
- if ( is_array( $desc ) )
209
- $cur_args['desc'] = $desc[$i];
210
- elseif ( isset( $desc ) )
211
- $cur_args['desc'] = $desc;
212
 
213
- // Find relevant formdata
214
- $match = NULL;
215
- if ( $checked === NULL ) {
216
- $key = str_replace( '[]', '', $$i1 );
 
 
 
217
 
218
- if ( isset( self::$formdata[ $key ] ) ) {
219
- $match = self::$formdata[ $key ];
 
220
 
221
- if ( is_array( $match ) ) {
222
- $match = $match[$i];
223
- }
224
- }
225
- } else if ( is_array( $checked ) ) {
226
- $cur_args['checked'] = isset( $checked[$i] ) && $checked[$i];
227
- }
228
 
229
- $output[] = self::$func( $cur_args, $match );
 
 
230
 
231
- $i++;
232
  }
233
 
234
- return implode( "\n", $output ) . $_after;
 
 
 
 
235
  }
236
 
237
- // Handle args for checkboxes and radio inputs
238
- private static function _checkbox_single( $args, $data ) {
239
- $args = wp_parse_args( $args, array(
240
- 'name' => NULL,
241
  'value' => true,
242
- 'desc_pos' => 'after',
243
  'desc' => NULL,
244
- 'checked' => NULL,
245
  'extra' => array(),
246
  ) );
247
 
@@ -249,11 +274,7 @@ class scbForms {
249
  $$key = &$val;
250
  unset( $val );
251
 
252
- if ( $checked === NULL && $value == $data )
253
- $checked = true;
254
-
255
- if ( $checked )
256
- $extra['checked'] = 'checked';
257
 
258
  if ( is_null( $desc ) && !is_bool( $value ) )
259
  $desc = str_replace( '[]', '', $value );
@@ -262,9 +283,9 @@ class scbForms {
262
  }
263
 
264
  // Handle args for text inputs
265
- private static function _input_single( $args, $data ) {
266
- $args = wp_parse_args( $args, array(
267
- 'value' => $data,
268
  'desc_pos' => 'after',
269
  'extra' => array( 'class' => 'regular-text' ),
270
  ) );
@@ -273,7 +294,7 @@ class scbForms {
273
  $$key = &$val;
274
  unset( $val );
275
 
276
- if ( !isset( $extra['id'] ) && FALSE === strpos( $name, '[' ) )
277
  $extra['id'] = $name;
278
 
279
  return self::_input_gen( $args );
@@ -281,72 +302,22 @@ class scbForms {
281
 
282
  // Generate html with the final args
283
  private static function _input_gen( $args ) {
284
- extract( wp_parse_args( $args, array(
285
- 'name' => NULL,
286
  'value' => NULL,
287
  'desc' => NULL,
288
  'extra' => array()
289
  ) ) );
290
 
291
- $extra = self::array_to_attr( $extra );
292
 
293
  if ( 'textarea' == $type ) {
294
- $value = esc_html( $value );
295
- $input = "<textarea name='{$name}'{$extra}>{$value}</textarea>\n";
296
- }
297
- else {
298
- $value = esc_attr( $value );
299
- $input = "<input name='{$name}' value='{$value}' type='{$type}'{$extra} /> ";
300
- }
301
-
302
- return self::add_label( $input, $desc, $desc_pos );
303
- }
304
-
305
- private static function _select() {
306
- extract( wp_parse_args( self::$args, array(
307
- 'name' => '',
308
- 'value' => array(),
309
- 'text' => '',
310
- 'selected' => array( 'foo' ), // hack to make default blank
311
- 'extra' => array(),
312
- 'numeric' => false, // use numeric array instead of associative
313
- 'desc' => '',
314
- 'desc_pos' => '',
315
- ) ), EXTR_SKIP );
316
-
317
- if ( empty( $value ) )
318
- $value = array( '' => '' );
319
-
320
- if ( !is_array( $value ) )
321
- return trigger_error( "'value' argument is expected to be an array", E_USER_WARNING );
322
-
323
- if ( !self::is_associative( $value ) && !$numeric )
324
- $value = array_combine( $value, $value );
325
-
326
- if ( isset( self::$formdata[$name] ) )
327
- $cur_val = self::$formdata[$name];
328
- else
329
- $cur_val = $selected;
330
-
331
- if ( false === $text ) {
332
- $opts = '';
333
  } else {
334
- $opts = "\t<option value=''" . selected( $cur_val, array( 'foo' ), false ) . ">{$text}</option>\n";
335
- }
336
-
337
- foreach ( $value as $key => $value ) {
338
- if ( empty( $key ) || empty( $value ) )
339
- continue;
340
-
341
- $opts .= "\t<option value='{$key}'" . selected( (string) $key, (string) $cur_val, false) . '>' . $value . "</option>\n";
342
  }
343
 
344
- if ( !is_array( $extra ) )
345
- $extra = self::attr_to_array( $extra );
346
- $extra = self::array_to_attr( $extra );
347
-
348
- $input = "<select name='{$name}'$extra>\n{$opts}</select>";
349
-
350
  return self::add_label( $input, $desc, $desc_pos );
351
  }
352
 
@@ -367,61 +338,109 @@ class scbForms {
367
  $label = trim( str_replace( self::token, $input, $label ) );
368
 
369
  if ( empty( $desc ) )
370
- $output = $input . "\n";
371
  else
372
- $output = "<label>{$label}</label>\n";
373
 
374
- return $output;
375
  }
376
 
377
 
378
  // Utilities
379
 
380
 
381
- private static function attr_to_array( $html ) {
382
- return shortcode_parse_atts( $html );
383
- }
 
 
 
 
 
 
384
 
385
- private static function array_to_attr( $attr ) {
386
- $attr = array_filter( (array) $attr );
387
 
388
- $out = '';
389
- foreach ( $attr as $key => $value )
390
- $out .= ' ' . $key . '=' . '"' . esc_attr( $value ) . '"';
391
 
392
- return $out;
393
  }
394
 
395
- private static function is_associative( $array ) {
396
- if ( !is_array( $array ) || empty( $array ) )
397
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
398
 
399
- $keys = array_keys( $array );
 
400
 
 
 
401
  return array_keys( $keys ) !== $keys;
402
  }
 
 
 
 
 
 
 
 
403
 
404
- private static function array_extract( $array, $keys ) {
405
- $r = array();
406
- foreach ( $keys as $key )
407
- if ( isset( $array[$key] ) )
408
- $r[$key] = $array[$key];
409
 
410
- return $r;
 
411
  }
412
- }
413
 
414
- // PHP < 5.2
415
- if ( !function_exists( 'array_fill_keys' ) ) :
416
- function array_fill_keys( $keys, $value ) {
417
- if ( !is_array( $keys ) )
418
- trigger_error( 'First argument is expected to be an array.' . gettype( $keys ) . 'given', E_USER_WARNING );
419
 
420
- $r = array();
421
- foreach ( $keys as $key )
422
- $r[$key] = $value;
423
 
424
- return $r;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
  }
426
- endif;
427
 
1
  <?php
2
 
3
+ // Data-aware form generator
4
 
5
  class scbForms {
6
 
7
  const token = '%input%';
8
 
9
+ protected static $cur_name;
 
10
 
11
+ static function input( $args, $formdata = false ) {
12
+ // setle on singular keys
 
 
13
  foreach ( array( 'name', 'value' ) as $key ) {
14
  $old = $key . 's';
15
 
19
  }
20
  }
21
 
22
+ if ( !empty( $formdata ) ) {
23
+ $form = new scbForm( $formdata );
24
+ return $form->input( $args );
25
+ }
26
+
27
  if ( empty( $args['name'] ) )
28
  return trigger_error( 'Empty name', E_USER_WARNING );
29
 
30
+ $args = wp_parse_args( $args, array(
31
+ 'desc' => '',
32
+ 'desc_pos' => '',
33
+ ) );
34
 
35
+ $val_is_array = isset( $args['value'] ) && is_array( $args['value'] );
36
+
37
+ if ( isset( $args['extra'] ) && !is_array( $args['extra'] ) )
38
+ $args['extra'] = shortcode_parse_atts( $args['extra'] );
39
+
40
+ self::$cur_name = self::get_name( $args['name'] );
41
+
42
+ switch ( $args['type'] ) {
43
+ case 'select':
44
+ case 'radio':
45
+ if ( ! $val_is_array )
46
+ return trigger_error( "'value' argument is expected to be an array", E_USER_WARNING );
47
+
48
+ return self::_single_choice( $args );
49
+ break;
50
+ case 'checkbox':
51
+ if ( $val_is_array )
52
+ return self::_multiple_choice( $args );
53
+ else
54
+ return self::_checkbox( $args );
55
+ break;
56
+ default:
57
+ return self::_input( $args );
58
+ }
59
  }
60
 
61
 
138
  // ____________PRIVATE METHODS____________
139
 
140
 
141
+ private static function _single_choice( $args ) {
142
+ $args = wp_parse_args( $args, array(
143
+ 'numeric' => false, // use numeric array instead of associative
144
+ 'selected' => array( 'foo' ), // hack to make default blank
145
+ ) );
 
 
146
 
147
+ self::_expand_values( $args );
 
148
 
149
+ if ( 'select' == $args['type'] )
150
+ return self::_select( $args );
151
+ else
152
+ return self::_radio( $args );
153
  }
154
 
155
+ private static function _multiple_choice( $args ) {
156
+ $args = wp_parse_args( $args, array(
157
+ 'numeric' => false, // use numeric array instead of associative
158
+ 'checked' => null,
159
+ ) );
 
 
 
160
 
161
+ self::$cur_name .= '[]';
 
 
162
 
163
+ self::_expand_values( $args );
 
 
 
 
 
164
 
165
+ extract( $args );
166
+
167
+ if ( !is_array( $checked ) )
168
+ $checked = array();
169
+
170
+ $opts = '';
171
+ foreach ( $value as $value => $title ) {
172
+ if ( empty( $value ) || empty( $title ) )
173
+ continue;
174
+
175
+ $opts .= self::_checkbox( array(
176
+ 'type' => 'checkbox',
177
+ 'value' => $value,
178
+ 'checked' => in_array( $value, $checked ),
179
+ 'desc' => $title,
180
+ 'desc_pos' => $desc_pos
181
+ ) );
182
  }
183
 
184
+ return $opts;
185
+ }
186
+
187
+ private static function _expand_values( &$args ) {
188
+ $value =& $args['value'];
189
+
190
+ if ( !empty( $value ) && !self::is_associative( $value ) ) {
191
+ if ( is_array( $args['desc'] ) ) {
192
+ $value = array_combine( $value, $args['desc'] ); // back-compat
193
+ } elseif ( !$args['numeric'] ) {
194
+ $value = array_combine( $value, $value );
195
  }
196
  }
197
+ }
198
 
199
+ private static function _radio( $args ) {
200
+ extract( $args );
201
+
202
+ if ( array( 'foo' ) == $selected ) {
203
+ $selected = key( $value ); // radio buttons should always have one option selected
 
 
204
  }
205
 
206
+ $opts = '';
207
+ foreach ( $value as $value => $title ) {
208
+ if ( empty( $value ) || empty( $title ) )
209
+ continue;
210
 
211
+ $opts .= self::_checkbox( array(
212
+ 'type' => 'radio',
213
+ 'value' => $value,
214
+ 'checked' => ( (string) $value == (string) $selected ),
215
+ 'desc' => $title,
216
+ 'desc_pos' => $desc_pos
217
+ ) );
218
  }
219
 
220
+ return $opts;
221
+ }
 
 
 
 
222
 
223
+ private static function _select( $args ) {
224
+ extract( wp_parse_args( $args, array(
225
+ 'text' => '',
226
+ 'extra' => array()
227
+ ) ) );
228
 
229
+ $options = array();
 
 
 
 
230
 
231
+ if ( false !== $text ) {
232
+ $options[] = array(
233
+ 'value' => '',
234
+ 'selected' => ( $selected == array( 'foo' ) ),
235
+ 'title' => $text
236
+ );
237
+ }
238
 
239
+ foreach ( $value as $value => $title ) {
240
+ if ( empty( $value ) || empty( $title ) )
241
+ continue;
242
 
243
+ $options[] = array(
244
+ 'value' => $value,
245
+ 'selected' => ( (string) $value == (string) $selected ),
246
+ 'title' => $title
247
+ );
248
+ }
 
249
 
250
+ $opts = '';
251
+ foreach ( $options as $option ) {
252
+ extract( $option );
253
 
254
+ $opts .= html( 'option', compact( 'value', 'selected' ), $title );
255
  }
256
 
257
+ $extra['name'] = self::$cur_name;
258
+
259
+ $input = html( 'select', $extra, $opts );
260
+
261
+ return self::add_label( $input, $desc, $desc_pos );
262
  }
263
 
264
+ // Handle args for a single checkbox or radio input
265
+ private static function _checkbox( $args ) {
266
+ $args = wp_parse_args( $args, array(
 
267
  'value' => true,
 
268
  'desc' => NULL,
269
+ 'checked' => false,
270
  'extra' => array(),
271
  ) );
272
 
274
  $$key = &$val;
275
  unset( $val );
276
 
277
+ $extra['checked'] = $checked;
 
 
 
 
278
 
279
  if ( is_null( $desc ) && !is_bool( $value ) )
280
  $desc = str_replace( '[]', '', $value );
283
  }
284
 
285
  // Handle args for text inputs
286
+ private static function _input( $args ) {
287
+ $args = wp_parse_args( $args, array(
288
+ 'value' => '',
289
  'desc_pos' => 'after',
290
  'extra' => array( 'class' => 'regular-text' ),
291
  ) );
294
  $$key = &$val;
295
  unset( $val );
296
 
297
+ if ( !isset( $extra['id'] ) && !is_array( $name ) && false === strpos( $name, '[' ) )
298
  $extra['id'] = $name;
299
 
300
  return self::_input_gen( $args );
302
 
303
  // Generate html with the final args
304
  private static function _input_gen( $args ) {
305
+ extract( wp_parse_args( $args, array(
 
306
  'value' => NULL,
307
  'desc' => NULL,
308
  'extra' => array()
309
  ) ) );
310
 
311
+ $extra['name'] = self::$cur_name;
312
 
313
  if ( 'textarea' == $type ) {
314
+ $input = html( 'textarea', $extra, esc_textarea( $value ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  } else {
316
+ $extra['value'] = $value;
317
+ $extra['type'] = $type;
318
+ $input = html( 'input', $extra );
 
 
 
 
 
319
  }
320
 
 
 
 
 
 
 
321
  return self::add_label( $input, $desc, $desc_pos );
322
  }
323
 
338
  $label = trim( str_replace( self::token, $input, $label ) );
339
 
340
  if ( empty( $desc ) )
341
+ $output = $input;
342
  else
343
+ $output = html( 'label', $label );
344
 
345
+ return $output . "\n";
346
  }
347
 
348
 
349
  // Utilities
350
 
351
 
352
+ /**
353
+ * Generates the proper string for a name attribute.
354
+ *
355
+ * @param array|string $name The raw name
356
+ *
357
+ * @return string
358
+ */
359
+ static function get_name( $name ) {
360
+ $name = (array) $name;
361
 
362
+ $name_str = array_shift( $name );
 
363
 
364
+ foreach ( $name as $key ) {
365
+ $name_str .= '[' . esc_attr( $key ) . ']';
366
+ }
367
 
368
+ return $name_str;
369
  }
370
 
371
+ /**
372
+ * Traverses the formdata and retrieves the correct value.
373
+ *
374
+ * @param array|string $name The name of the value
375
+ * @param array $value The data that will be traversed
376
+ *
377
+ * @return mixed
378
+ */
379
+ static function get_value( $name, $value ) {
380
+ foreach ( (array) $name as $key ) {
381
+ if ( !isset( $value[ $key ] ) )
382
+ return null;
383
+
384
+ $value = $value[$key];
385
+ }
386
 
387
+ return $value;
388
+ }
389
 
390
+ private static function is_associative( $array ) {
391
+ $keys = array_keys( $array );
392
  return array_keys( $keys ) !== $keys;
393
  }
394
+ }
395
+
396
+ /**
397
+ * A wrapper for scbForms, containing the formdata
398
+ */
399
+ class scbForm {
400
+ protected $data = array();
401
+ protected $prefix = array();
402
 
403
+ function __construct( $data, $prefix = false ) {
404
+ if ( is_array( $data ) )
405
+ $this->data = $data;
 
 
406
 
407
+ if ( $prefix )
408
+ $this->prefix = (array) $prefix;
409
  }
 
410
 
411
+ function traverse_to( $path ) {
412
+ $data = scbForms::get_value( $path, $this->data );
 
 
 
413
 
414
+ $prefix = array_merge( $this->prefix, (array) $path );
 
 
415
 
416
+ return new scbForm( $data, $prefix );
417
+ }
418
+
419
+ function input( $args ) {
420
+ $value = scbForms::get_value( $args['name'], $this->data );
421
+
422
+ if ( !is_null( $value ) ) {
423
+ switch ( $args['type'] ) {
424
+ case 'select':
425
+ case 'radio':
426
+ $args['selected'] = $value;
427
+ break;
428
+ case 'checkbox':
429
+ if ( is_array( $value ) )
430
+ $args['checked'] = $value;
431
+ else
432
+ $args['checked'] = ( $value || ( isset( $args['value'] ) && $value == $args['value'] ) );
433
+ break;
434
+ default:
435
+ $args['value'] = $value;
436
+ }
437
+ }
438
+
439
+ if ( !empty( $this->prefix ) ) {
440
+ $args['name'] = array_merge( $this->prefix, (array) $args['name'] );
441
+ }
442
+
443
+ return scbForms::input( $args );
444
+ }
445
  }
 
446
 
scb/Hooks.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class scbHooks {
4
+ private static $mangle_name;
5
+
6
+ public static function add( $class ) {
7
+ self::_do( 'add_filter', $class );
8
+ }
9
+
10
+ public static function remove( $class ) {
11
+ self::_do( 'remove_filter', $class );
12
+ }
13
+
14
+ public static function debug( $class, $mangle_name = false ) {
15
+ self::$mangle_name = $mangle_name;
16
+
17
+ echo "<pre>";
18
+ self::_do( array( __CLASS__, '_print' ), $class );
19
+ echo "</pre>";
20
+ }
21
+
22
+ private static function _print( $tag, $callback, $prio, $argc ) {
23
+ $static = !is_object( $callback[0] );
24
+
25
+ if ( self::$mangle_name )
26
+ $class = $static ? '__CLASS__' : '$this';
27
+ else if ( $static )
28
+ $class = "'" . $callback[0] . "'";
29
+ else
30
+ $class = '$' . get_class( $callback[0] );
31
+
32
+ $func = "array( $class, '$callback[1]' )";
33
+
34
+ echo "add_filter( '$tag', $func";
35
+
36
+ if ( $prio != 10 || $argc > 1 ) {
37
+ echo ", $prio";
38
+
39
+ if ( $argc > 1 )
40
+ echo ", $argc";
41
+ }
42
+
43
+ echo " );\n";
44
+ }
45
+
46
+ private static function _do( $action, $class ) {
47
+ $reflection = new ReflectionClass( $class );
48
+
49
+ foreach ( $reflection->getMethods() as $method ) {
50
+ if ( $method->isPublic() && !$method->isConstructor() ) {
51
+ $comment = $method->getDocComment();
52
+
53
+ if ( preg_match( '/@nohook[ \t\*\n]+/', $comment ) ) {
54
+ continue;
55
+ }
56
+
57
+ preg_match_all( '/@hook:?\s+([^\s]+)/', $comment, $matches ) ? $matches[1] : $method->name;
58
+ if ( empty( $matches[1] ) )
59
+ $hooks = array( $method->name );
60
+ else
61
+ $hooks = $matches[1];
62
+
63
+ $priority = preg_match( '/@priority:?\s+(\d+)/', $comment, $matches ) ? $matches[1] : 10;
64
+
65
+ foreach ( $hooks as $hook ) {
66
+ call_user_func( $action, $hook, array( $class, $method->name ), $priority, $method->getNumberOfParameters() );
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+
scb/Options.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
 
3
- // Documentation: http://scribu.net/wordpress/scb-framework/scb-options.html
4
 
5
  class scbOptions {
6
 
7
- protected $key; // the option name
8
 
9
- protected $defaults; // the default value( s )
10
 
11
  public $wp_filter_id; // used by WP hooks
12
 
@@ -15,15 +15,16 @@ class scbOptions {
15
  *
16
  * @param string $key Option name
17
  * @param string $file Reference to main plugin file
18
- * @param array $defaults An associative array of default values ( optional )
19
  */
20
- public function __construct( $key, $file, $defaults = '' ) {
21
  $this->key = $key;
22
  $this->defaults = $defaults;
23
 
24
- scbUtil::add_activation_hook( $file, array( $this, '_update_reset' ) );
25
-
26
- scbUtil::add_uninstall_hook( $file, array( $this, 'delete' ) );
 
27
  }
28
 
29
  /**
@@ -36,15 +37,14 @@ class scbOptions {
36
  /**
37
  * Get option values for one, many or all fields
38
  *
39
- * @param string|array $field The field( s ) to get
40
  * @return mixed Whatever is in those fields
41
  */
42
  public function get( $field = '' ) {
43
- $data = get_option( $this->key );
 
 
44
 
45
- if ( is_array( $this->defaults ) )
46
- $data = ( array ) $data;
47
-
48
  return $this->_get( $field, $data );
49
  }
50
 
@@ -119,21 +119,17 @@ class scbOptions {
119
  //_____INTERNAL METHODS_____
120
 
121
 
122
- // Add new fields with their default values
123
- function _update_reset() {
124
- if ( is_array( $this->defaults ) )
125
- $this->update( array_merge( $this->defaults, $this->get() ) );
126
- else
127
- add_option( $this->key, $this->defaults );
128
  }
129
 
 
130
  private function _clean( $data ) {
131
- if ( !is_array( $data ) || !is_array( $this->defaults ) )
132
- return $data;
133
-
134
  $r = array();
135
  foreach ( array_keys( $this->defaults ) as $key )
136
- $r[$key] = @$data[$key];
 
137
 
138
  return $r;
139
  }
1
  <?php
2
 
3
+ // Container for an array of options
4
 
5
  class scbOptions {
6
 
7
+ protected $key; // the option name
8
 
9
+ protected $defaults; // the default values
10
 
11
  public $wp_filter_id; // used by WP hooks
12
 
15
  *
16
  * @param string $key Option name
17
  * @param string $file Reference to main plugin file
18
+ * @param array $defaults An associative array of default values (optional)
19
  */
20
+ public function __construct( $key, $file, $defaults = array() ) {
21
  $this->key = $key;
22
  $this->defaults = $defaults;
23
 
24
+ if ( $file ) {
25
+ scbUtil::add_activation_hook( $file, array( $this, '_activation' ) );
26
+ scbUtil::add_uninstall_hook( $file, array( $this, 'delete' ) );
27
+ }
28
  }
29
 
30
  /**
37
  /**
38
  * Get option values for one, many or all fields
39
  *
40
+ * @param string|array $field The field(s) to get
41
  * @return mixed Whatever is in those fields
42
  */
43
  public function get( $field = '' ) {
44
+ $data = get_option( $this->key, array() );
45
+
46
+ $data = array_merge( $this->defaults, $data );
47
 
 
 
 
48
  return $this->_get( $field, $data );
49
  }
50
 
119
  //_____INTERNAL METHODS_____
120
 
121
 
122
+ // Saves an extra query
123
+ function _activation() {
124
+ add_option( $this->key, $this->defaults );
 
 
 
125
  }
126
 
127
+ // Keep only the keys defined in $this->defaults
128
  private function _clean( $data ) {
 
 
 
129
  $r = array();
130
  foreach ( array_keys( $this->defaults ) as $key )
131
+ if ( isset( $data[$key] ) )
132
+ $r[$key] = $data[$key];
133
 
134
  return $r;
135
  }
scb/QueryManipulation.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
-
3
- class scbQueryManipulation {
4
-
5
- private $bits = array();
6
- private $wp_query;
7
-
8
- private static $filters = array(
9
- 'posts_where',
10
- 'posts_join',
11
- 'posts_groupby',
12
- 'posts_orderby',
13
- 'posts_distinct',
14
- 'post_limits',
15
- 'posts_fields'
16
- );
17
-
18
- public function __construct( $callback, $once = true ) {
19
- global $wp_version;
20
-
21
- if ( version_compare( $wp_version, '3.1-alpha', '>=' ) ) {
22
- if ( !$once ) {
23
- add_filter( 'posts_clauses', $callback, 10, 2 );
24
- return;
25
- }
26
- }
27
-
28
- $this->callback = $callback;
29
-
30
- $this->enable();
31
-
32
- if ( $once )
33
- add_filter( 'posts_request', array( $this, '_disable' ) );
34
- }
35
-
36
- function _disable( $request ) {
37
- remove_filter( 'posts_request', array( $this, '_disable' ) );
38
-
39
- $this->disable();
40
-
41
- return $request;
42
- }
43
-
44
- public function enable() {
45
- foreach ( self::$filters as $filter ) {
46
- add_filter( $filter, array( $this, 'collect' ), 999, 2 );
47
- add_filter( $filter . '_request' , array( $this, 'update' ), 9 );
48
- }
49
-
50
- add_action( 'posts_selection' , array( $this, 'alter' ) );
51
- }
52
-
53
- public function disable() {
54
- foreach ( self::$filters as $filter ) {
55
- remove_filter( $filter, array( $this, 'collect' ), 999, 2 );
56
- remove_filter( $filter . '_request' , array( $this, 'update' ), 9 );
57
- }
58
-
59
- remove_action( 'posts_selection' , array( $this, 'alter' ) );
60
- }
61
-
62
- function collect( $value, $wp_query ) {
63
- // remove 'posts_'
64
- $key = explode( '_', current_filter() );
65
- $key = array_slice( $key, 1 );
66
- $key = implode( '_', $key );
67
-
68
- $this->bits[ $key ] = $value;
69
-
70
- $this->wp_query = $wp_query;
71
-
72
- return $value;
73
- }
74
-
75
- function alter( $query ) {
76
- // suppress_filters => true
77
- if ( is_null( $this->wp_query ) ) {
78
- return;
79
- }
80
-
81
- $this->bits = call_user_func( $this->callback, $this->bits, $this->wp_query );
82
- }
83
-
84
- function update( $value ) {
85
- // remove 'posts_' and '_request'
86
- $key = explode( '_', current_filter() );
87
- $key = array_slice( $key, 1, -1 );
88
- $key = implode( '_', $key );
89
-
90
- return $this->bits[ $key ];
91
- }
92
- }
93
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
scb/Table.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
  // Takes care of creating, updating and deleting database tables
 
4
  class scbTable {
5
  protected $name;
6
  protected $columns;
@@ -9,20 +10,24 @@ class scbTable {
9
  function __construct( $name, $file, $columns, $upgrade_method = 'dbDelta' ) {
10
  global $wpdb;
11
 
12
- $this->name = $wpdb->prefix . $name;
13
  $this->columns = $columns;
14
  $this->upgrade_method = $upgrade_method;
15
 
16
  $wpdb->tables[] = $name;
17
- $wpdb->$name = $this->name;
18
 
19
- scbUtil::add_activation_hook( $file, array( $this, 'install' ) );
20
- scbUtil::add_uninstall_hook( $file, array( $this, 'uninstall' ) );
 
 
21
  }
22
 
23
  function install() {
24
  global $wpdb;
25
 
 
 
26
  $charset_collate = '';
27
  if ( $wpdb->has_cap( 'collation' ) ) {
28
  if ( ! empty( $wpdb->charset ) )
@@ -33,20 +38,22 @@ class scbTable {
33
 
34
  if ( 'dbDelta' == $this->upgrade_method ) {
35
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
36
- dbDelta( "CREATE TABLE $this->name ( $this->columns ) $charset_collate" );
37
  return;
38
  }
39
 
40
  if ( 'delete_first' == $this->upgrade_method )
41
- $wpdb->query( "DROP TABLE IF EXISTS $this->name;" );
42
 
43
- $wpdb->query( "CREATE TABLE IF NOT EXISTS $this->name ( $this->columns ) $charset_collate;" );
44
  }
45
 
46
  function uninstall() {
47
  global $wpdb;
48
 
49
- $wpdb->query( "DROP TABLE IF EXISTS $this->name" );
 
 
50
  }
51
  }
52
 
1
  <?php
2
 
3
  // Takes care of creating, updating and deleting database tables
4
+
5
  class scbTable {
6
  protected $name;
7
  protected $columns;
10
  function __construct( $name, $file, $columns, $upgrade_method = 'dbDelta' ) {
11
  global $wpdb;
12
 
13
+ $this->name = $name;
14
  $this->columns = $columns;
15
  $this->upgrade_method = $upgrade_method;
16
 
17
  $wpdb->tables[] = $name;
18
+ $wpdb->$name = $wpdb->prefix . $name;
19
 
20
+ if ( $file ) {
21
+ scbUtil::add_activation_hook( $file, array( $this, 'install' ) );
22
+ scbUtil::add_uninstall_hook( $file, array( $this, 'uninstall' ) );
23
+ }
24
  }
25
 
26
  function install() {
27
  global $wpdb;
28
 
29
+ $full_table_name = $wpdb->prefix . $this->name;
30
+
31
  $charset_collate = '';
32
  if ( $wpdb->has_cap( 'collation' ) ) {
33
  if ( ! empty( $wpdb->charset ) )
38
 
39
  if ( 'dbDelta' == $this->upgrade_method ) {
40
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
41
+ dbDelta( "CREATE TABLE $full_table_name ( $this->columns ) $charset_collate" );
42
  return;
43
  }
44
 
45
  if ( 'delete_first' == $this->upgrade_method )
46
+ $wpdb->query( "DROP TABLE IF EXISTS $full_table_name;" );
47
 
48
+ $wpdb->query( "CREATE TABLE IF NOT EXISTS $full_table_name ( $this->columns ) $charset_collate;" );
49
  }
50
 
51
  function uninstall() {
52
  global $wpdb;
53
 
54
+ $full_table_name = $wpdb->prefix . $this->name;
55
+
56
+ $wpdb->query( "DROP TABLE IF EXISTS $full_table_name" );
57
  }
58
  }
59
 
scb/Util.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class scbUtil {
4
 
5
  // Force script enqueue
@@ -23,18 +25,19 @@ class scbUtil {
23
 
24
  ob_start();
25
  $wp_styles->do_items( ( array ) $handles );
26
- $content = str_replace( array( '"', "\n" ), array( "'", '' ), ob_get_clean() );
27
 
28
  echo "<script type='text/javascript'>\n";
29
- echo "jQuery( document ).ready( function( $ ) {\n";
30
- echo "$( 'head' ).prepend( \"$content\" );\n";
31
- echo "} );\n";
32
  echo "</script>";
33
  }
34
 
35
  // Enable delayed activation ( to be used with scb_init() )
36
  static function add_activation_hook( $plugin, $callback ) {
37
- add_action( 'scb_activation_' . plugin_basename( $plugin ), $callback );
 
 
 
38
  }
39
 
40
  // Have more than one uninstall hooks; also prevents an UPDATE query on each page load
@@ -44,6 +47,11 @@ class scbUtil {
44
  add_action( 'uninstall_' . plugin_basename( $plugin ), $callback );
45
  }
46
 
 
 
 
 
 
47
  // Apply a function to each element of a ( nested ) array recursively
48
  static function array_map_recursive( $callback, $array ) {
49
  array_walk_recursive( $array, array( __CLASS__, 'array_map_recursive_helper' ), $callback );
@@ -57,37 +65,20 @@ class scbUtil {
57
 
58
  // Extract certain $keys from $array
59
  static function array_extract( $array, $keys ) {
60
- $r = array();
61
-
62
- foreach ( $keys as $key )
63
- if ( array_key_exists( $key, $array ) )
64
- $r[$key] = $array[$key];
65
-
66
- return $r;
67
  }
68
 
69
  // Extract a certain value from a list of arrays
70
  static function array_pluck( $array, $key ) {
71
- $r = array();
72
-
73
- foreach ( $array as $value ) {
74
- if ( is_object( $value ) )
75
- $value = get_object_vars( $value );
76
- if ( array_key_exists( $key, $value ) )
77
- $r[] = $value[$key];
78
- }
79
-
80
- return $r;
81
  }
82
 
83
  // Transform a list of objects into an associative array
84
  static function objects_to_assoc( $objects, $key, $value ) {
85
- $r = array();
86
-
87
- foreach ( $objects as $obj )
88
- $r[$obj->$key] = $obj->$value;
89
-
90
- return $r;
91
  }
92
 
93
  // Prepare an array for an IN statement
@@ -113,15 +104,26 @@ class scbUtil {
113
  }
114
 
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  //_____Minimalist HTML framework_____
117
 
118
- /*
119
- * Examples:
120
- *
121
- * html( 'p', 'Hello world!' ); <p>Hello world!</p>
122
- * html( 'a', array( 'href' => 'http://example.com' ), 'A link' ); <a href="http://example.com">A link</a>
123
- * html( 'img', array( 'src' => 'http://example.com/f.jpg' ) ); <img src="http://example.com/f.jpg" />
124
- * html( 'ul', html( 'li', 'a' ), html( 'li', 'b' ) ); <ul><li>a</li><li>b</li></ul>
125
  */
126
  if ( ! function_exists( 'html' ) ):
127
  function html( $tag ) {
@@ -133,7 +135,13 @@ function html( $tag ) {
133
  $closing = $tag;
134
  $attributes = array_shift( $args );
135
  foreach ( $attributes as $key => $value ) {
136
- $tag .= ' ' . $key . '="' . htmlspecialchars( $value, ENT_QUOTES ) . '"';
 
 
 
 
 
 
137
  }
138
  } else {
139
  list( $closing ) = explode( ' ', $tag, 2 );
@@ -155,7 +163,7 @@ function html_link( $url, $title = '' ) {
155
  if ( empty( $title ) )
156
  $title = $url;
157
 
158
- return sprintf( "<a href='%s'>%s</a>", esc_url( $url ), $title );
159
  }
160
  endif;
161
 
1
  <?php
2
 
3
+ // Various utilities
4
+
5
  class scbUtil {
6
 
7
  // Force script enqueue
25
 
26
  ob_start();
27
  $wp_styles->do_items( ( array ) $handles );
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
 
35
  // Enable delayed activation ( to be used with scb_init() )
36
  static function add_activation_hook( $plugin, $callback ) {
37
+ if ( defined( 'SCB_LOAD_MU' ) )
38
+ register_activation_hook( $plugin, $callback );
39
+ else
40
+ add_action( 'scb_activation_' . plugin_basename( $plugin ), $callback );
41
  }
42
 
43
  // Have more than one uninstall hooks; also prevents an UPDATE query on each page load
47
  add_action( 'uninstall_' . plugin_basename( $plugin ), $callback );
48
  }
49
 
50
+ // Get the current, full URL
51
+ static function get_current_url() {
52
+ return ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
53
+ }
54
+
55
  // Apply a function to each element of a ( nested ) array recursively
56
  static function array_map_recursive( $callback, $array ) {
57
  array_walk_recursive( $array, array( __CLASS__, 'array_map_recursive_helper' ), $callback );
65
 
66
  // Extract certain $keys from $array
67
  static function array_extract( $array, $keys ) {
68
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'WP 3.1', 'wp_array_slice_assoc()' );
69
+ return wp_array_slice_assoc( $array, $keys );
 
 
 
 
 
70
  }
71
 
72
  // Extract a certain value from a list of arrays
73
  static function array_pluck( $array, $key ) {
74
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'WP 3.1', 'wp_list_pluck()' );
75
+ return wp_list_pluck( $array, $key );
 
 
 
 
 
 
 
 
76
  }
77
 
78
  // Transform a list of objects into an associative array
79
  static function objects_to_assoc( $objects, $key, $value ) {
80
+ _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'r41', 'scb_list_fold()' );
81
+ return scb_list_fold( $objects, $key, $value );
 
 
 
 
82
  }
83
 
84
  // Prepare an array for an IN statement
104
  }
105
 
106
 
107
+ // Transform a list of objects into an associative array
108
+ function scb_list_fold( $list, $key, $value ) {
109
+ $r = array();
110
+
111
+ if ( is_array( reset( $list ) ) ) {
112
+ foreach ( $list as $item )
113
+ $r[ $item[ $key ] ] = $item[ $value ];
114
+ } else {
115
+ foreach ( $list as $item )
116
+ $r[ $item->$key ] = $item->$value;
117
+ }
118
+
119
+ return $r;
120
+ }
121
+
122
+
123
  //_____Minimalist HTML framework_____
124
 
125
+ /**
126
+ * Generate an HTML tag. Atributes are escaped. Content is NOT escaped.
 
 
 
 
 
127
  */
128
  if ( ! function_exists( 'html' ) ):
129
  function html( $tag ) {
135
  $closing = $tag;
136
  $attributes = array_shift( $args );
137
  foreach ( $attributes as $key => $value ) {
138
+ if ( false === $value )
139
+ continue;
140
+
141
+ if ( true === $value )
142
+ $value = $key;
143
+
144
+ $tag .= ' ' . $key . '="' . esc_attr( $value ) . '"';
145
  }
146
  } else {
147
  list( $closing ) = explode( ' ', $tag, 2 );
163
  if ( empty( $title ) )
164
  $title = $url;
165
 
166
+ return html( 'a', array( 'href' => $url ), $title );
167
  }
168
  endif;
169
 
scb/Widget.php CHANGED
@@ -50,40 +50,26 @@ abstract class scbWidget extends WP_Widget {
50
  // See scbForms::input()
51
  // Allows extra parameter $args['title']
52
  protected function input( $args, $formdata = array() ) {
 
 
 
 
53
  // Add default class
54
- if ( !isset( $args['extra'] ) )
55
- $args['extra'] = 'class="regular-text"';
56
 
57
  // Add default label position
58
  if ( !in_array( $args['type'], array( 'checkbox', 'radio' ) ) && empty( $args['desc_pos'] ) )
59
  $args['desc_pos'] = 'before';
60
 
61
- // Then add prefix to names and formdata
62
- $new_formdata = array();
63
- foreach ( ( array ) $args['name'] as $name )
64
- $new_formdata[$this->scb_get_field_name( $name )] = @$formdata[$name];
65
- $new_names = array_keys( $new_formdata );
66
-
67
- // Finally, replace the old names
68
- if ( 1 == count( $new_names ) )
69
- $args['name'] = $new_names[0];
70
- else
71
- $args['name'] = $new_names;
72
-
73
- return scbForms::input( $args, $new_formdata );
74
- }
75
-
76
-
77
- //_____INTERNAL METHODS_____
78
 
 
 
79
 
80
- private function scb_get_field_name( $name ) {
81
- if ( $split = scbUtil::split_at( '[', $name ) )
82
- list( $basename, $extra ) = $split;
83
- else
84
- return $this->get_field_name( $name );
85
 
86
- return str_replace( '[]', '', $this->get_field_name( $basename ) ) . $extra;
87
  }
88
  }
89
 
50
  // See scbForms::input()
51
  // Allows extra parameter $args['title']
52
  protected function input( $args, $formdata = array() ) {
53
+ $prefix = array( 'widget-' . $this->id_base, $this->number );
54
+
55
+ $form = new scbForm( $formdata, $prefix );
56
+
57
  // Add default class
58
+ if ( !isset( $args['extra'] ) && 'text' == $args['type'] )
59
+ $args['extra'] = array( 'class' => 'widefat' );
60
 
61
  // Add default label position
62
  if ( !in_array( $args['type'], array( 'checkbox', 'radio' ) ) && empty( $args['desc_pos'] ) )
63
  $args['desc_pos'] = 'before';
64
 
65
+ $name = $args['name'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ if ( !is_array( $name ) && '[]' == substr( $name, -2 ) )
68
+ $name = array( substr( $name, 0, -2 ), '' );
69
 
70
+ $args['name'] = $name;
 
 
 
 
71
 
72
+ return $form->input( $args );
73
  }
74
  }
75
 
scb/load.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
 
3
- $GLOBALS['_scb_data'] = array( 31, __FILE__, array(
4
  'scbUtil', 'scbOptions', 'scbForms', 'scbTable',
5
  'scbWidget', 'scbAdminPage', 'scbBoxesPage',
6
- 'scbQueryManipulation', 'scbCron',
7
  ) );
8
 
9
  if ( !class_exists( 'scbLoad4' ) ) :
@@ -57,7 +57,7 @@ class scbLoad4 {
57
  foreach ( self::$classes[$file] as $class_name ) {
58
  if ( class_exists( $class_name ) )
59
  continue;
60
-
61
  $fpath = $path . substr( $class_name, 3 ) . '.php';
62
  if ( file_exists( $fpath ) ) {
63
  include $fpath;
1
  <?php
2
 
3
+ $GLOBALS['_scb_data'] = array( 42, __FILE__, array(
4
  'scbUtil', 'scbOptions', 'scbForms', 'scbTable',
5
  'scbWidget', 'scbAdminPage', 'scbBoxesPage',
6
+ 'scbCron', 'scbHooks',
7
  ) );
8
 
9
  if ( !class_exists( 'scbLoad4' ) ) :
57
  foreach ( self::$classes[$file] as $class_name ) {
58
  if ( class_exists( $class_name ) )
59
  continue;
60
+
61
  $fpath = $path . substr( $class_name, 3 ) . '.php';
62
  if ( file_exists( $fpath ) ) {
63
  include $fpath;
screenshot-1.png CHANGED
Binary file
wp-pagenavi.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  /*
3
  Plugin Name: WP-PageNavi
4
- Version: 2.74
5
  Description: Adds a more advanced paging navigation to your WordPress blog
6
  Author: Lester 'GaMerZ' Chan & scribu
7
  Plugin URI: http://wordpress.org/extend/plugins/wp-pagenavi/
@@ -9,7 +9,7 @@ Text Domain: wp-pagenavi
9
  Domain Path: /lang
10
 
11
 
12
- Copyright 2009 Lester Chan ( email : lesterchan@gmail.com )
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License as published by
1
  <?php
2
  /*
3
  Plugin Name: WP-PageNavi
4
+ Version: 2.80
5
  Description: Adds a more advanced paging navigation to your WordPress blog
6
  Author: Lester 'GaMerZ' Chan & scribu
7
  Plugin URI: http://wordpress.org/extend/plugins/wp-pagenavi/
9
  Domain Path: /lang
10
 
11
 
12
+ Copyright 2009 Lester Chan (lesterchan@gmail.com)
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License as published by