Better WordPress Google XML Sitemaps (support Sitemap Index, Multi-site and Google News) - Version 1.0.5

Version Description

  • Unregistered modules (such as redundant modules from 1.0.3) will now have a 404 HTTP status to prevent search engines from requesting them again.
  • Time for each log entry will now make use of your current timezone setting in Settings -> General.
  • And other minor fixes.

Thanks everyone for using this plugin!

Download this release

Release Info

Developer OddOneOut
Plugin Icon wp plugin Better WordPress Google XML Sitemaps (support Sitemap Index, Multi-site and Google News)
Version 1.0.5
Comparing to
See all releases

Version 1.0.5

bwp-simple-gxs-ms.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+ include_once(dirname(__FILE__). '/bwp-google-xml-sitemaps/bwp-simple-gxs.php');
3
+ ?>
bwp-simple-gxs.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: BWP Google XML Sitemaps
4
+ Plugin URI: http://betterwp.net/wordpress-plugins/google-xml-sitemaps/
5
+ Description: A more lightweight Google XML Sitemap WordPress plugin that generates a <a href="http://en.wikipedia.org/wiki/Sitemap_index">Sitemap index</a> rather than a single sitemap. Despite its simplicity, it is still very powerful and has plenty of options to choose.
6
+ Version: 1.0.5
7
+ Text Domain: bwp-simple-gxs
8
+ Domain Path: /languages/
9
+ Author: Khang Minh
10
+ Author URI: http://betterwp.net
11
+ License: GPLv3
12
+ */
13
+
14
+ // Frontend
15
+ require_once(dirname(__FILE__) . '/includes/class-bwp-simple-gxs.php');
16
+ $bwp_gxs = new BWP_SIMPLE_GXS();
17
+
18
+ // Backend
19
+ add_action('admin_menu', 'bwp_gxs_init_admin', 1);
20
+
21
+ function bwp_gxs_init_admin()
22
+ {
23
+ global $bwp_gxs;
24
+ $bwp_gxs->init_admin();
25
+ }
26
+ ?>
bwp-simple-gxs.pot ADDED
@@ -0,0 +1,484 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: BWP Google XML Sitemaps\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2011-04-19 09:59+0700\n"
6
+ "PO-Revision-Date: 2011-04-19 09:59+0700\n"
7
+ "Last-Translator: \n"
8
+ "Language-Team: \n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
13
+ "X-Poedit-Basepath: .\n"
14
+ "X-Poedit-SourceCharset: utf-8\n"
15
+ "X-Poedit-SearchPath-0: .\n"
16
+
17
+ #: includes/class-bwp-framework.php:172
18
+ #, php-format
19
+ msgid "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</strong> or higher. The plugin will not function until you update your software. Please deactivate this plugin."
20
+ msgstr ""
21
+
22
+ #: includes/class-bwp-framework.php:181
23
+ msgid "log"
24
+ msgstr ""
25
+
26
+ #: includes/class-bwp-framework.php:186
27
+ msgid "You can buy me some coffees if you appreciate my work, thank you!"
28
+ msgstr ""
29
+
30
+ #: includes/class-bwp-framework.php:211
31
+ #, php-format
32
+ msgid "You are using version %s!"
33
+ msgstr ""
34
+
35
+ #: includes/class-bwp-framework.php:343
36
+ msgid "Settings"
37
+ msgstr ""
38
+
39
+ #: includes/class-bwp-gxs-cache.php:34
40
+ #, php-format
41
+ msgid "Cache directory (\"%s\") does not exist or is not writable."
42
+ msgstr ""
43
+
44
+ #: includes/class-bwp-gxs-cache.php:56
45
+ #, php-format
46
+ msgid "Cache file for module <em>%s</em> is not found and will be built right away."
47
+ msgstr ""
48
+
49
+ #: includes/class-bwp-gxs-cache.php:106
50
+ #: includes/class-bwp-simple-gxs.php:915
51
+ #, php-format
52
+ msgid "Successfully served a cached version of <em>%s.xml</em>."
53
+ msgstr ""
54
+
55
+ #: includes/class-bwp-simple-gxs.php:121
56
+ #: includes/class-bwp-simple-gxs.php:270
57
+ msgid "Sitemap Statistics"
58
+ msgstr ""
59
+
60
+ #: includes/class-bwp-simple-gxs.php:122
61
+ #: includes/class-bwp-simple-gxs.php:271
62
+ msgid "Sitemap Generator"
63
+ msgstr ""
64
+
65
+ #: includes/class-bwp-simple-gxs.php:145
66
+ #, php-format
67
+ msgid "This sitemap was originally generated in %s second(s) (Memory usage: %s) - %s queries - %s URL(s) listed"
68
+ msgstr ""
69
+
70
+ #: includes/class-bwp-simple-gxs.php:268
71
+ msgid "BWP Google XML Sitemaps"
72
+ msgstr ""
73
+
74
+ #: includes/class-bwp-simple-gxs.php:270
75
+ msgid "BWP Google XML Sitemaps Statistics"
76
+ msgstr ""
77
+
78
+ #: includes/class-bwp-simple-gxs.php:271
79
+ msgid "BWP Google XML Sitemaps Generator"
80
+ msgstr ""
81
+
82
+ #: includes/class-bwp-simple-gxs.php:282
83
+ msgid "You do not have sufficient permissions to access this page."
84
+ msgstr ""
85
+
86
+ #: includes/class-bwp-simple-gxs.php:300
87
+ msgid "What are Sitemaps?"
88
+ msgstr ""
89
+
90
+ #: includes/class-bwp-simple-gxs.php:301
91
+ msgid "Your sitemaps"
92
+ msgstr ""
93
+
94
+ #: includes/class-bwp-simple-gxs.php:302
95
+ msgid "Submit your sitemaps"
96
+ msgstr ""
97
+
98
+ #: includes/class-bwp-simple-gxs.php:303
99
+ msgid "Pinging search engines"
100
+ msgstr ""
101
+
102
+ #: includes/class-bwp-simple-gxs.php:304
103
+ msgid "Enable pinging functionality?"
104
+ msgstr ""
105
+
106
+ #: includes/class-bwp-simple-gxs.php:305
107
+ msgid "Enable pinging individual SE"
108
+ msgstr ""
109
+
110
+ #: includes/class-bwp-simple-gxs.php:306
111
+ msgid "Sitemap Generator's Log"
112
+ msgstr ""
113
+
114
+ #: includes/class-bwp-simple-gxs.php:307
115
+ msgid "Enable logging?"
116
+ msgstr ""
117
+
118
+ #: includes/class-bwp-simple-gxs.php:308
119
+ msgid "Enable debugging?"
120
+ msgstr ""
121
+
122
+ #: includes/class-bwp-simple-gxs.php:318
123
+ msgid "In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional metadata about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site &mdash; <em>http://www.sitemaps.org/</em>"
124
+ msgstr ""
125
+
126
+ #: includes/class-bwp-simple-gxs.php:319
127
+ msgid "<em>Basic information about all your sitemaps.</em>"
128
+ msgstr ""
129
+
130
+ #: includes/class-bwp-simple-gxs.php:320
131
+ msgid "<em>More detailed information about how your sitemaps are generated including <span style=\"color: #999999;\">notices</span>, <span style=\"color: #FF0000;\">errors</span> and <span style=\"color: #009900;\">success messages</span>.</em>"
132
+ msgstr ""
133
+
134
+ #: includes/class-bwp-simple-gxs.php:321
135
+ #, php-format
136
+ msgid "<em>Submit your sitemapindex to major search engines like <a href=\"%s\" target=\"_blank\">Google</a>, <a href=\"%s\" target=\"_blank\">Yahoo</a>, <a href=\"%s\" target=\"_blank\">Bing</a> or <a href=\"%s\" target=\"_blank\">Ask</a>.</em>"
137
+ msgstr ""
138
+
139
+ #: includes/class-bwp-simple-gxs.php:322
140
+ msgid "<em>Now when you post something new to your blog, you can <em>ping</em> those search engines to tell them your blog just got updated. Pinging could be less effective than you think it is but you should enable such feature anyway.</em>"
141
+ msgstr ""
142
+
143
+ #: includes/class-bwp-simple-gxs.php:327
144
+ msgid "Selected SE below will be pinged when you publish new posts."
145
+ msgstr ""
146
+
147
+ #: includes/class-bwp-simple-gxs.php:328
148
+ msgid "No additional load is needed so enabling this is recommended."
149
+ msgstr ""
150
+
151
+ #: includes/class-bwp-simple-gxs.php:329
152
+ msgid "Minor errors will be printed on screen. Also, when debug is on, no caching is used, useful when you develop new modules."
153
+ msgstr ""
154
+
155
+ #: includes/class-bwp-simple-gxs.php:330
156
+ msgid "Google"
157
+ msgstr ""
158
+
159
+ #: includes/class-bwp-simple-gxs.php:331
160
+ #, php-format
161
+ msgid "Yahoo &mdash; <a href=\"%s\" target=\"_blank\">important</a>"
162
+ msgstr ""
163
+
164
+ #: includes/class-bwp-simple-gxs.php:332
165
+ msgid "Bing"
166
+ msgstr ""
167
+
168
+ #: includes/class-bwp-simple-gxs.php:333
169
+ msgid "Ask.com"
170
+ msgstr ""
171
+
172
+ #: includes/class-bwp-simple-gxs.php:336
173
+ #, php-format
174
+ msgid "After you activate this plugin, all sitemaps should be available right away. The next step is to submit the sitemapindex to major search engines. You only need the <strong>sitemapindex</strong> and nothing else, those search engines will automatically recognize other included sitemaps. You can read a small <a href=\"%s\">How-to</a> if you are interested."
175
+ msgstr ""
176
+
177
+ #: includes/class-bwp-simple-gxs.php:360
178
+ msgid "Output no more than"
179
+ msgstr ""
180
+
181
+ #: includes/class-bwp-simple-gxs.php:361
182
+ msgid "Default change frequency"
183
+ msgstr ""
184
+
185
+ #: includes/class-bwp-simple-gxs.php:362
186
+ msgid "Default priority"
187
+ msgstr ""
188
+
189
+ #: includes/class-bwp-simple-gxs.php:363
190
+ msgid "Minimum priority"
191
+ msgstr ""
192
+
193
+ #: includes/class-bwp-simple-gxs.php:364
194
+ msgid "Add sitemapindex to WordPress's virtual robots.txt?"
195
+ msgstr ""
196
+
197
+ #: includes/class-bwp-simple-gxs.php:365
198
+ msgid "In sitemapindex, include"
199
+ msgstr ""
200
+
201
+ #: includes/class-bwp-simple-gxs.php:366
202
+ msgid "Style your sitemaps with an XSLT stylesheet?"
203
+ msgstr ""
204
+
205
+ #: includes/class-bwp-simple-gxs.php:367
206
+ msgid "Custom XSLT stylesheet URL"
207
+ msgstr ""
208
+
209
+ #: includes/class-bwp-simple-gxs.php:368
210
+ msgid "Show build stats in sitemaps?"
211
+ msgstr ""
212
+
213
+ #: includes/class-bwp-simple-gxs.php:369
214
+ msgid "Enable credit?"
215
+ msgstr ""
216
+
217
+ #: includes/class-bwp-simple-gxs.php:370
218
+ msgid "Enable Gzip?"
219
+ msgstr ""
220
+
221
+ #: includes/class-bwp-simple-gxs.php:371
222
+ msgid "Module Options"
223
+ msgstr ""
224
+
225
+ #: includes/class-bwp-simple-gxs.php:372
226
+ msgid "Alternate module directory"
227
+ msgstr ""
228
+
229
+ #: includes/class-bwp-simple-gxs.php:373
230
+ msgid "Get no more than"
231
+ msgstr ""
232
+
233
+ #: includes/class-bwp-simple-gxs.php:374
234
+ msgid "Caching Options"
235
+ msgstr ""
236
+
237
+ #: includes/class-bwp-simple-gxs.php:375
238
+ msgid "Enable caching?"
239
+ msgstr ""
240
+
241
+ #: includes/class-bwp-simple-gxs.php:376
242
+ msgid "Enable auto cache re-generation?"
243
+ msgstr ""
244
+
245
+ #: includes/class-bwp-simple-gxs.php:377
246
+ msgid "Cached sitemaps will last for"
247
+ msgstr ""
248
+
249
+ #: includes/class-bwp-simple-gxs.php:378
250
+ msgid "Cached sitemaps are stored in (auto detected)"
251
+ msgstr ""
252
+
253
+ #: includes/class-bwp-simple-gxs.php:382
254
+ msgid "<em>Cache your sitemaps for better performance.</em>"
255
+ msgstr ""
256
+
257
+ #: includes/class-bwp-simple-gxs.php:383
258
+ #, php-format
259
+ msgid "<em>This plugin uses modules to build sitemap data so it is recommended that you extend this plugin using modules rather than hooks. Some of the settings below only affect modules extending the base module class. Read more about using modules <a href=\"%s#using-modules\">here</a>.</em>"
260
+ msgstr ""
261
+
262
+ #: includes/class-bwp-simple-gxs.php:393
263
+ #: includes/class-bwp-simple-gxs.php:399
264
+ msgid "second(s)"
265
+ msgstr ""
266
+
267
+ #: includes/class-bwp-simple-gxs.php:394
268
+ #: includes/class-bwp-simple-gxs.php:400
269
+ msgid "minute(s)"
270
+ msgstr ""
271
+
272
+ #: includes/class-bwp-simple-gxs.php:395
273
+ #: includes/class-bwp-simple-gxs.php:401
274
+ msgid "hour(s)"
275
+ msgstr ""
276
+
277
+ #: includes/class-bwp-simple-gxs.php:396
278
+ #: includes/class-bwp-simple-gxs.php:402
279
+ msgid "day(s)"
280
+ msgstr ""
281
+
282
+ #: includes/class-bwp-simple-gxs.php:409
283
+ #: includes/class-bwp-simple-gxs.php:410
284
+ #: includes/class-bwp-simple-gxs.php:411
285
+ msgid "read more"
286
+ msgstr ""
287
+
288
+ #: includes/class-bwp-simple-gxs.php:414
289
+ msgid "your sitemaps are generated and then cached to reduce unnecessary work."
290
+ msgstr ""
291
+
292
+ #: includes/class-bwp-simple-gxs.php:415
293
+ msgid "when a cached sitemap expires, this plugin will try to generate the cache again. If you disable this, remember to manually flush the cache once in a while."
294
+ msgstr ""
295
+
296
+ #: includes/class-bwp-simple-gxs.php:415
297
+ msgid "Flush the cache"
298
+ msgstr ""
299
+
300
+ #: includes/class-bwp-simple-gxs.php:416
301
+ msgid "tell you useful information such as build time, memory usage, SQL queries, etc."
302
+ msgstr ""
303
+
304
+ #: includes/class-bwp-simple-gxs.php:417
305
+ #, php-format
306
+ msgid "make your sitemaps ~ 70% smaller."
307
+ msgstr ""
308
+
309
+ #: includes/class-bwp-simple-gxs.php:418
310
+ msgid "static pages' sitemap."
311
+ msgstr ""
312
+
313
+ #: includes/class-bwp-simple-gxs.php:419
314
+ msgid "taxonomy archives' sitemaps, including custom taxonomies."
315
+ msgstr ""
316
+
317
+ #: includes/class-bwp-simple-gxs.php:420
318
+ msgid "tag archives' sitemaps."
319
+ msgstr ""
320
+
321
+ #: includes/class-bwp-simple-gxs.php:421
322
+ msgid "date archives' sitemaps."
323
+ msgstr ""
324
+
325
+ #: includes/class-bwp-simple-gxs.php:422
326
+ msgid "some copyrighted info is also added to your sitemaps. Thanks!"
327
+ msgstr ""
328
+
329
+ #: includes/class-bwp-simple-gxs.php:423
330
+ msgid "This will load the default stylesheet provided by this plugin. You can set a custom stylesheet below or filter the <code>bwp_gxs_xslt</code> hook."
331
+ msgstr ""
332
+
333
+ #: includes/class-bwp-simple-gxs.php:424
334
+ #, php-format
335
+ msgid "If you're on a Multi-site installation with Sub-domain enabled, each site will have its own robots.txt, sites in sub-directory will not. Please read the <a href=\"%s#toc-robots\" target=\"_blank\">documentation</a> for more info."
336
+ msgstr ""
337
+
338
+ #: includes/class-bwp-simple-gxs.php:427
339
+ msgid "item(s) in one sitemap. Actually, 5000 would be more ideal. You can not go over 50,000, though."
340
+ msgstr ""
341
+
342
+ #: includes/class-bwp-simple-gxs.php:428
343
+ msgid "Input a full path to the directory where you put your own modules (e.g. <code>/home/mysite/public_html/gxs-modules/</code>), you can also override a built-in module by having a module with the same filename in this directory. A filter is also available if you would like to use PHP instead."
344
+ msgstr ""
345
+
346
+ #: includes/class-bwp-simple-gxs.php:429
347
+ msgid "The cache directory must be writable (i.e. CHMOD to 755 or 777)."
348
+ msgstr ""
349
+
350
+ #: includes/class-bwp-simple-gxs.php:430
351
+ msgid "item(s) in one SQL query. This helps you avoid running too heavy queries."
352
+ msgstr ""
353
+
354
+ #: includes/class-bwp-simple-gxs.php:433
355
+ msgid "expected to be an absolute URL, e.g. <code>http://example.com/my-stylesheet.xsl</code>. You must also have a style sheet for the sitemapindex that can be accessed through the above URL, e.g. <code>my-stylesheet.xsl</code> and <code>my-stylesheetindex.xsl</code>). Please leave blank if you do not wish to use."
356
+ msgstr ""
357
+
358
+ #: includes/class-bwp-simple-gxs.php:460
359
+ #: includes/class-bwp-simple-gxs.php:462
360
+ msgid "Notice"
361
+ msgstr ""
362
+
363
+ #: includes/class-bwp-simple-gxs.php:460
364
+ #, php-format
365
+ msgid "<strong>%d</strong> cached sitemaps have been flushed successfully!"
366
+ msgstr ""
367
+
368
+ #: includes/class-bwp-simple-gxs.php:462
369
+ msgid "Could not delete any cached sitemaps. Please manually check the cache directory."
370
+ msgstr ""
371
+
372
+ #: includes/class-bwp-simple-gxs.php:514
373
+ msgid "Warning"
374
+ msgstr ""
375
+
376
+ #: includes/class-bwp-simple-gxs.php:514
377
+ msgid "Cache directory does not exist or is not writable. Please read more about directory permission <a href='http://www.zzee.com/solutions/unix-permissions.shtml'>here</a> (Unix)."
378
+ msgstr ""
379
+
380
+ #: includes/class-bwp-simple-gxs.php:568
381
+ msgid "(Debug is on)"
382
+ msgstr ""
383
+
384
+ #: includes/class-bwp-simple-gxs.php:581
385
+ msgid "<strong>BWP Google XML Sitemaps Error:</strong> "
386
+ msgstr ""
387
+
388
+ #: includes/class-bwp-simple-gxs.php:581
389
+ msgid "BWP Google XML Sitemaps Error"
390
+ msgstr ""
391
+
392
+ #: includes/class-bwp-simple-gxs.php:604
393
+ #, php-format
394
+ msgid "Nothing here... yet! Try submitting your <a href=\"%s\">sitemapindex</a> first!"
395
+ msgstr ""
396
+
397
+ #: includes/class-bwp-simple-gxs.php:604
398
+ msgid "No log yet!"
399
+ msgstr ""
400
+
401
+ #: includes/class-bwp-simple-gxs.php:614
402
+ #, php-format
403
+ msgid "%s"
404
+ msgstr ""
405
+
406
+ #: includes/class-bwp-simple-gxs.php:614
407
+ #, php-format
408
+ msgid "<a href=\"%s\" target=\"_blank\">%s</a> has been successfully built on <strong>%s</strong>."
409
+ msgstr ""
410
+
411
+ #: includes/class-bwp-simple-gxs.php:624
412
+ #: includes/class-bwp-simple-gxs.php:627
413
+ msgid "M j, Y : H:i:s"
414
+ msgstr ""
415
+
416
+ #: includes/class-bwp-simple-gxs.php:888
417
+ #, php-format
418
+ msgid "Requested module (<em>%s</em>) not found or not allowed."
419
+ msgstr ""
420
+
421
+ #: includes/class-bwp-simple-gxs.php:942
422
+ #: includes/class-bwp-simple-gxs.php:962
423
+ #, php-format
424
+ msgid "Loaded a custom sub-module file: <strong>%s</strong>."
425
+ msgstr ""
426
+
427
+ #: includes/class-bwp-simple-gxs.php:951
428
+ #, php-format
429
+ msgid "Mapped sub-module file: <strong>%s</strong> is not available in both default and custom module directory. The plugin will now try loading the requested sub-module instead."
430
+ msgstr ""
431
+
432
+ #: includes/class-bwp-simple-gxs.php:970
433
+ #, php-format
434
+ msgid "Sub-module file: <strong>%s</strong> is not available in both default and custom module directory. The plugin will now try loading the parent module instead."
435
+ msgstr ""
436
+
437
+ #: includes/class-bwp-simple-gxs.php:983
438
+ #, php-format
439
+ msgid "Loaded a custom module file: <strong>%s</strong>."
440
+ msgstr ""
441
+
442
+ #: includes/class-bwp-simple-gxs.php:989
443
+ #, php-format
444
+ msgid "Could not load module file: <strong>%s</strong> in both default and custom module directory. Please recheck if that module file exists."
445
+ msgstr ""
446
+
447
+ #: includes/class-bwp-simple-gxs.php:1007
448
+ #, php-format
449
+ msgid "There is no class named <strong>%s</strong> in the module file <strong>%s</strong>."
450
+ msgstr ""
451
+
452
+ #: includes/class-bwp-simple-gxs.php:1016
453
+ #, php-format
454
+ msgid "Loaded a custom sitemapindex module file: <strong>%s</strong>."
455
+ msgstr ""
456
+
457
+ #: includes/class-bwp-simple-gxs.php:1036
458
+ #, php-format
459
+ msgid "Successfully generated <em>%s.xml</em> using module <em>%s</em>."
460
+ msgstr ""
461
+
462
+ #: includes/class-bwp-simple-gxs.php:1146
463
+ #, php-format
464
+ msgid "Pinged %s successfully!"
465
+ msgstr ""
466
+
467
+ #: includes/class-bwp-simple-gxs.php:1152
468
+ #, php-format
469
+ msgid "Ping limit for today to %s has been reached, sorry!"
470
+ msgstr ""
471
+
472
+ #: includes/class-bwp-simple-gxs.php:1180
473
+ #, php-format
474
+ msgid "<em>%s.xml</em> does not have any item. The plugin has fired a 404 header to the search engine that requests it. You should check the module that generates that sitemap (<em>%s.php</em>)."
475
+ msgstr ""
476
+
477
+ #: includes/bwp-option-page/includes/class-bwp-option-page.php:74
478
+ msgid "Plugin Configurations"
479
+ msgstr ""
480
+
481
+ #: includes/bwp-option-page/includes/class-bwp-option-page.php:391
482
+ msgid "Save Changes"
483
+ msgstr ""
484
+
cache/.htaccess ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <Files *>
2
+ Order Allow,Deny
3
+ Deny from All
4
+ </Files>
css/bwp-simple-gxs.css ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * html .bwp-gxs-log {
2
+ height: expression( this.scrollHeight > 200 ? "200px" : "auto" );
3
+ }
4
+ .bwp-gxs-log {
5
+ font-size: 0.95em;
6
+ background-color: #ffffff;
7
+ padding: 5px 10px; padding-top: 0px;
8
+ width: 90%;
9
+ border: 1px solid #cccccc;
10
+ max-height: 200px;
11
+ overflow: auto;
12
+ }
images/icon_menu.png ADDED
Binary file
images/icon_menu_32.png ADDED
Binary file
includes/bwp-option-page/bwp-option-page.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ if (!is_admin()) return;
3
+
4
+ require_once(dirname(__FILE__) . '/includes/class-bwp-option-page.php');
5
+ ?>
includes/bwp-option-page/css/bwp-option-page.css ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* For WordPress of older versions */
2
+ .nav-tab{border-style:solid;border-color:#ccc #ccc #f9f9f9;border-width:1px 1px 0;color:#c1c1c1;text-shadow:rgba(255,255,255,1) 0 1px 0;font-size:12px;line-height:16px;display:inline-block;padding:4px 14px 6px;text-decoration:none;margin:0 6px -1px 0;-moz-border-radius:5px 5px 0 0;-webkit-border-top-left-radius:5px;-webkit-border-top-right-radius:5px;-khtml-border-top-left-radius:5px;-khtml-border-top-right-radius:5px;border-top-left-radius:5px;border-top-right-radius:5px;}.nav-tab-active{border-width:1px;color:#464646;}h2.nav-tab-wrapper,h3.nav-tab-wrapper{border-bottom:1px solid #ccc;padding-bottom:0;}h2 .nav-tab{padding:4px 20px 6px;font:italic normal normal 24px/35px Georgia,"Times New Roman","Bitstream Charter",Times,serif;}
3
+
4
+ .bwp-option-page {
5
+ margin-top: 1em;
6
+ }
7
+
8
+ .bwp-option-page p {
9
+ margin-top: 0px;
10
+ margin-bottom: 0px;
11
+ zoom: 1;
12
+ }
13
+
14
+ .bwp-option-page li.clear, .bwp-option-page div.clear {
15
+ clear: left;
16
+ margin: 1em 0 0 0;
17
+ zoom: 1;
18
+ }
19
+
20
+ .bwp-option-page p.submit {
21
+ clear: both;
22
+ padding-top: 1.5em;
23
+ }
24
+
25
+ .wrap .bwp-option-page-tabs {
26
+ border-bottom: 1px solid #CCCCCC;
27
+ padding-bottom: 0px;
28
+ margin-bottom: 20px;
29
+ }
30
+
31
+ .bwp-option-page-tabs a {
32
+ font-size: 19px;
33
+ }
34
+
35
+ .bwp-option-page-tabs a.version {
36
+ font-size: 17px;
37
+ line-height: 22px;
38
+ }
39
+
40
+ .bwp-opton-page-label {
41
+ display: block;
42
+ float: left;
43
+ width: 200px;
44
+ margin: 3px 0 1em 0;
45
+ }
46
+
47
+ .type-checkbox {
48
+ margin-top: 0px;
49
+ }
50
+
51
+ p.bwp-option-page-inputs {
52
+ margin: 0 0 0 220px;
53
+ padding: 0;
54
+ }
55
+
56
+ .bwp-option-page-inputs input {
57
+ margin: 0 0 5px 0;
58
+ }
59
+
60
+ .bwp-option-page-inputs label {
61
+ margin: 0;
62
+ }
63
+
64
+ .bwp-option-page-inputs select {
65
+ margin: 1px 0 0 0;
66
+ }
67
+
68
+ .bwp-option-page-inputs input[type="checkbox"] {
69
+ margin-left: 2px;
70
+ }
71
+
72
+ #icon-betterwp-net {
73
+ background: url("betterwp.jpg") no-repeat transparent;
74
+ border: 1px solid #E3E3E3;
75
+ height: 32px;
76
+ width: 32px;
77
+ }
78
+
79
+ #icon-bwp-plugin {
80
+ background-repeat: no-repeat;
81
+ background-position: left center;
82
+ margin-top: 21px; margin-left: 5px;
83
+ width: 36px;
84
+ }
85
+
86
+ #bwp-donation {
87
+ float: right;
88
+ width: 220px;
89
+ padding: 7px; padding-bottom: 0px; margin: 0 0 10px 10px;
90
+ background-color: #ffffff;
91
+ border: 1px solid #cccccc;
92
+ text-align: center;
93
+ }
94
+
95
+ #bwp-donation small {
96
+ font-size: 0.8em;
97
+ }
98
+
99
+ #bwp-donation .paypal-submit {
100
+ vertical-align: bottom;
101
+ display: inline-block;
102
+ margin: 0 0 1px 2px;
103
+ padding: 0px;
104
+ }
includes/bwp-option-page/images/icon-paypal.gif ADDED
Binary file
includes/bwp-option-page/includes/class-bwp-option-page.php ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE VERSION 3.0 OR LATER
5
+ */
6
+
7
+ class BWP_OPTION_PAGE {
8
+
9
+ /**
10
+ * The form
11
+ */
12
+ var $form;
13
+
14
+ /**
15
+ * The form name
16
+ */
17
+ var $form_name;
18
+
19
+ /**
20
+ * Tabs to build
21
+ */
22
+ var $form_tabs;
23
+
24
+ /**
25
+ * Current tab
26
+ */
27
+ var $current_tab;
28
+
29
+ /**
30
+ * This holds the form items, determining the position
31
+ */
32
+ var $form_items = array();
33
+
34
+ /**
35
+ * This holds the name for each items (an item can have more than one fields)
36
+ */
37
+ var $form_item_names = array();
38
+
39
+ /**
40
+ * This holds the form label
41
+ */
42
+ var $form_item_labels = array();
43
+
44
+ /**
45
+ * This holds the form option aka data
46
+ */
47
+ var $form_options = array(), $site_options = array();
48
+
49
+ /**
50
+ * Constructor
51
+ */
52
+ function __construct($form_name = 'bwp_option_page', $site_options = array())
53
+ {
54
+ $this->form_name = $form_name;
55
+ $this->site_options = $site_options;
56
+ }
57
+
58
+ /**
59
+ * Init the class
60
+ *
61
+ * @param array $form The form array that contains everything we need to build the form
62
+ * @param array $options The data array that contains all data fetched from db or by default
63
+ * @param string $form_name The name of the form, change this if you have more than one forms on a page
64
+ */
65
+ function init($form = array(), $options = array(), $form_tabs = array())
66
+ {
67
+ $this->form_items = $form['items'];
68
+ $this->form_item_names = $form['item_names'];
69
+ $this->form_item_labels = $form['item_labels'];
70
+ $this->form = $form;
71
+ $this->form_options = $options;
72
+ $this->form_tabs = $form_tabs;
73
+ if (sizeof($this->form_tabs) == 0)
74
+ $this->form_tabs = array(__('Plugin Configurations', 'bwp-option-page'));
75
+ }
76
+
77
+ function get_form_name()
78
+ {
79
+ return $this->form_name;
80
+ }
81
+
82
+ function set_current_tab($current_tab = 0)
83
+ {
84
+ $this->current_tab = $current_tab;
85
+ }
86
+
87
+ function get_options($options = array(), $options_default = array())
88
+ {
89
+ foreach ($options_default as $key => $option)
90
+ {
91
+ if (!in_array($key, $options))
92
+ unset($options_default[$key]);
93
+ }
94
+ return $options_default;
95
+ }
96
+
97
+ function get_db_options($name = '', $options = array())
98
+ {
99
+ $db_options = get_option($name);
100
+ if (!$db_options)
101
+ update_option($name, $options);
102
+ else if (array_keys($options) != array_keys($db_options))
103
+ {
104
+ foreach ($db_options as $key => $data)
105
+ if (isset($options[$key]) && !in_array($key, $this->site_options))
106
+ $options[$key] = $data;
107
+ update_option($name, $options);
108
+ }
109
+ else
110
+ {
111
+ foreach ($db_options as $key => $data)
112
+ if (!in_array($key, $this->site_options))
113
+ $options[$key] = $data;
114
+ }
115
+
116
+ return $options;
117
+ }
118
+
119
+ function format_field($key, $option_formats)
120
+ {
121
+ if (!empty($option_formats[$key]))
122
+ {
123
+ if ('int' == $option_formats[$key])
124
+ $_POST[$key] = (int) $_POST[$key];
125
+ else if ('float' == $option_formats[$key])
126
+ $_POST[$key] = (float) $_POST[$key];
127
+ else if ('html' == $option_formats[$key])
128
+ $_POST[$key] = wp_filter_post_kses($_POST[$key]);
129
+ }
130
+ else
131
+ $_POST[$key] = strip_tags($_POST[$key]);
132
+ }
133
+
134
+ function kill_html_fields(&$form = array(), $ids)
135
+ {
136
+ $ids = (array) $ids;
137
+ $in_keys = array('items', 'item_labels', 'item_names');
138
+ foreach ($ids as $id)
139
+ {
140
+ foreach ($in_keys as $key)
141
+ unset($form[$key][$id]);
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Generate HTML field
147
+ *
148
+ * @params they explain themselves
149
+ */
150
+ function generate_html_field($type = '', $data = array(), $name = '', $in_section = false)
151
+ {
152
+ $pre_html_field = '';
153
+ $post_html_field = '';
154
+ $checked = 'checked="checked" ';
155
+ $selected = 'selected="selected" ';
156
+ $value = (isset($this->form_options[$name])) ? $this->form_options[$name] : '';
157
+ $value = ('textarea' == $type) ? esc_html($value) : esc_attr($value);
158
+ $array_replace = array();
159
+ $array_search = array('size', 'name', 'value', 'cols', 'rows', 'label', 'disabled', 'pre', 'post');
160
+ $return_html = '';
161
+ $br = (isset($this->form['inline_fields'][$name]) && is_array($this->form['inline_fields'][$name])) ? '' : "<br />\n";
162
+ $pre = (!empty($data['pre'])) ? $data['pre'] : '';
163
+ $post = (!empty($data['post'])) ? $data['post'] : '';
164
+
165
+ switch ($type)
166
+ {
167
+ case 'heading':
168
+ $html_field = '%s';
169
+ break;
170
+
171
+ case 'input':
172
+ $html_field = (!$in_section) ? '%pre%<input%disabled% size="%size%" type="text" id="' . $name . '" name="' . $name . '" value="' . $value . '" /> <em>%label%</em>' : '<label for="' . $name . '">%pre%<input%disabled% size="%size%" type="text" id="' . $name . '" name="' . $name . '" value="' . $value . '" /> <em>%label%</em></label>';
173
+ break;
174
+
175
+ case 'select':
176
+ $pre_html_field = '%pre%<select id="' . $name . '" name="' . $name . '">' . "\n";
177
+ $html_field = '<option %selected%value="%value%" />%option%</option>';
178
+ $post_html_field = '</select>%post%' . $br;
179
+ break;
180
+
181
+ case 'checkbox':
182
+ $html_field = '<label for="%name%">' . '<input %checked%type="checkbox" id="%name%" name="%name%" value="yes" /> %label%</label>';
183
+ break;
184
+
185
+ case 'radio':
186
+ $html_field = '<label>' . '<input %checked%type="radio" name="' . $name . '" value="%value%" /> %label%</label>';
187
+ break;
188
+
189
+ case 'textarea':
190
+ $html_field = '%pre%<textarea%disabled% id="' . $name . '" name="' . $name . '" cols="%cols%" rows="%rows%">' . $value . '</textarea>%post%';
191
+ break;
192
+ }
193
+
194
+ if (!isset($data))
195
+ return;
196
+
197
+ if ($type == 'heading' && !is_array($data))
198
+ {
199
+ $return_html .= sprintf($html_field, $data) . $br;
200
+ }
201
+ else if ($type == 'radio' || $type == 'checkbox' || $type == 'select')
202
+ {
203
+ foreach ($data as $key => $value)
204
+ {
205
+ // handle checkbox a little bit differently
206
+ if ($type == 'checkbox')
207
+ {
208
+ if ($this->form_options[$value] == 'yes')
209
+ $return_html .= str_replace(array('%value%', '%name%', '%label%', '%checked%'), array($value, $value, $key, $checked), $html_field) . $br;
210
+ else
211
+ $return_html .= str_replace(array('%value%', '%name%', '%label%', '%checked%'), array($value, $value, $key, ''), $html_field) . $br;
212
+ }
213
+ else if (isset($this->form_options[$name]) && $this->form_options[$name] == $value)
214
+ $return_html .= str_replace(array('%value%', '%name%', '%label%', '%option%', '%checked%', '%selected%', '%pre%', '%post%'), array($value, $value, $key, $key, $checked, $selected, $pre, $post), $html_field) . $br;
215
+ else
216
+ $return_html .= str_replace(array('%value%', '%name%', '%label%', '%option%', '%checked%', '%selected%', '%pre%', '%post%'), array($value, $value, $key, $key, '', '', $pre, $post), $html_field) . $br;
217
+ }
218
+ }
219
+ else
220
+ {
221
+ foreach ($array_search as &$keyword)
222
+ {
223
+ $array_replace[$keyword] = '';
224
+ if (!empty($data[$keyword]))
225
+ {
226
+ $array_replace[$keyword] = $data[$keyword];
227
+ }
228
+ $keyword = '%' . $keyword . '%';
229
+ }
230
+ $return_html = str_replace($array_search, $array_replace, $html_field) . $br;
231
+ }
232
+
233
+ // inline fields
234
+ $inline_html = '';
235
+ if (isset($this->form['inline_fields'][$name]) && is_array($this->form['inline_fields'][$name]))
236
+ {
237
+ foreach ($this->form['inline_fields'][$name] as $field => $field_type)
238
+ {
239
+ if (isset($this->form[$field_type][$field]))
240
+ $inline_html = ' ' . $this->generate_html_field($field_type, $this->form[$field_type][$field], $field, $in_section);
241
+ }
242
+ }
243
+
244
+ // Post
245
+ $post = (!empty($this->form['post'][$name])) ? ' ' . $this->form['post'][$name] : $post;
246
+
247
+ return str_replace('%pre%', $pre, $pre_html_field) . $return_html . str_replace('%post%', $post, $post_html_field) . $inline_html;
248
+ }
249
+
250
+ /**
251
+ * Generate HTML fields
252
+ *
253
+ * @params they explain themselves
254
+ */
255
+ function generate_html_fields($type, $name)
256
+ {
257
+ $item_label = '';
258
+ $return_html = '';
259
+
260
+ $item_key = array_keys($this->form_item_names, $name);
261
+
262
+ $input_class = ($type == 'heading') ? 'bwp-option-page-heading-desc' : 'bwp-option-page-inputs';
263
+
264
+ // An inline item can hold any HTML markup
265
+ // An example is to display some kinds of button right be low the label
266
+ $inline = '';
267
+ if (isset($this->form['inline']) && is_array($this->form['inline']) && array_key_exists($name, $this->form['inline']))
268
+ {
269
+ $inline = (empty($this->form['inline'][$name])) ? '' : $this->form['inline'][$name];
270
+ }
271
+ $inline .= "\n";
272
+
273
+ switch ($type)
274
+ {
275
+ case 'section':
276
+
277
+ if (!isset($this->form[$name]) || !is_array($this->form[$name]))
278
+ return;
279
+
280
+ $item_label = '<span class="bwp-opton-page-label">' . $this->form_item_labels[$item_key[0]] . $inline . '</span>';
281
+
282
+ foreach ($this->form[$name] as $section_field)
283
+ {
284
+ $type = $section_field[0];
285
+ $name = $section_field['name'];
286
+
287
+ if (isset($this->form[$section_field[0]]))
288
+ {
289
+ $return_html .= $this->generate_html_field($section_field[0], $this->form[$type][$name], $name, true);
290
+ }
291
+ }
292
+ break;
293
+
294
+ default:
295
+
296
+ if (!isset($this->form[$type][$name]) || ($type != 'heading' && !is_array($this->form[$type][$name])))
297
+ return;
298
+
299
+ /*$item_label = (empty($this->form[$type][$name]['label'])) ? '<label class="bwp-opton-page-label" for="' . $name . '">' . $this->form_item_labels[$item_key[0]] . '</label>' : '<span class="bwp-opton-page-label">' . $this->form_item_labels[$item_key[0]] . '</span>';*/
300
+ $item_label = ($type != 'checkbox' && $type != 'radio') ? '<label class="bwp-opton-page-label" for="' . $name . '">' . $this->form_item_labels[$item_key[0]] . $inline . '</label>' : '<span class="bwp-opton-page-label type-' . $type . '">' . $this->form_item_labels[$item_key[0]] . $inline . '</span>';
301
+ $item_label = ($type == 'heading') ? '<h3>' . $this->form_item_labels[$item_key[0]] . '</h3>' . $inline : $item_label;
302
+
303
+ if (isset($this->form[$type]))
304
+ {
305
+ $return_html = $this->generate_html_field($type, $this->form[$type][$name], $name);
306
+ }
307
+ break;
308
+ }
309
+
310
+ // A container can hold some result executed by customized script,
311
+ // such as displaying something when user press the submit button
312
+ $containers = '';
313
+ if (isset($this->form['container']) && is_array($this->form['container']) && array_key_exists($name, $this->form['container']))
314
+ {
315
+ $container_array = (array) $this->form['container'][$name];
316
+ foreach ($container_array as $container)
317
+ {
318
+ $containers .= (empty($container)) ? '<div style="display: none;"><!-- --></div>' : '<div class="clear">' . $container . '</div>' . "\n";
319
+ }
320
+ }
321
+
322
+ $pure_return = trim(strip_tags($return_html));
323
+ if (empty($pure_return) && $type == 'heading')
324
+ return $item_label . $containers;
325
+ else
326
+ return $item_label . '<p class="' . $input_class . '">' . $return_html . '</p>' . $containers;
327
+ }
328
+
329
+ /**
330
+ * Generate HTML form
331
+ *
332
+ * @see Constructor
333
+ */
334
+ function generate_html_form()
335
+ {
336
+ $return_str = '<div class="wrap">' . "\n";
337
+ if (sizeof($this->form_tabs) >= 2)
338
+ $return_str .= apply_filters('bwp-admin-form-icon', '<div class="icon32" id="icon-options-general"><br></div>' . "\n");
339
+ else
340
+ $return_str .= '<div class="icon32" id="icon-options-general"><br></div>';
341
+
342
+ if (sizeof($this->form_tabs) >= 2)
343
+ {
344
+ $count = 0;
345
+ $return_str .= '<h2 class="bwp-option-page-tabs">' . "\n";
346
+ $return_str .= apply_filters('bwp-admin-plugin-version', '') . "\n";
347
+ foreach ($this->form_tabs as $title => $link)
348
+ {
349
+ $count++;
350
+ $active = ($count == $this->current_tab) ? ' nav-tab-active' : '';
351
+ $return_str .= '<a class="nav-tab' . $active . '" href="' . $link . '">' . $title . '</a>' . "\n";
352
+ }
353
+ $return_str .= '</h2>' . "\n";
354
+ }
355
+ else if (!isset($this->form_tabs[0]))
356
+ {
357
+ $title = array_keys($this->form_tabs);
358
+ $return_str .= '<h2>' . $title[0] . '</h2>' . "\n";
359
+ }
360
+ else
361
+ $return_str .= '<h2>' . $this->form_tabs[0] . '</h2>' . "\n";
362
+
363
+ $return_str .= apply_filters('bwp_option_before_form', '');
364
+ echo $return_str;
365
+ do_action('bwp_option_action_before_form');
366
+ $return_str = '';
367
+ $return_str .= '<form class="bwp-option-page" name="' . $this->form_name . '" method="post" action="">' . "\n";
368
+ if (function_exists('wp_nonce_field'))
369
+ {
370
+ echo $return_str;
371
+ wp_nonce_field($this->form_name);
372
+ $return_str = '';
373
+ }
374
+ $return_str .= '<ul>' . "\n";
375
+
376
+ // generate filled form
377
+ if (isset($this->form_items) && is_array($this->form_items))
378
+ foreach ($this->form_items as $key => $type)
379
+ {
380
+ if (!empty($this->form_item_names[$key]) && !empty($this->form_item_labels[$key]))
381
+ {
382
+ $return_str .= '<li class="clear">' . $this->generate_html_fields($type, $this->form_item_names[$key]) . '</li>' . "\n";
383
+ }
384
+ }
385
+
386
+ $return_str .= '</ul>' . "\n";
387
+ $return_str .= apply_filters('bwp_option_before_submit_button', '');
388
+ echo $return_str;
389
+ do_action('bwp_option_action_before_submit_button');
390
+ $return_str = '';
391
+ $return_str .= apply_filters('bwp_option_submit_button', '<p class="submit"><input type="submit" class="button-primary" name="submit_' . $this->form_name . '" value="' . __('Save Changes') . '" /></p>') . "\n";
392
+ $return_str .= '</form>' . "\n";
393
+ $return_str .= '</div>' . "\n";
394
+
395
+ echo $return_str;
396
+ }
397
+ }
398
+ ?>
includes/class-bwp-framework.php ADDED
@@ -0,0 +1,425 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE VERSION 3.0 OR LATER
5
+ */
6
+
7
+ define('BWP_FRAMEWORK_VERSION', '1.0.0');
8
+
9
+ class BWP_FRAMEWORK {
10
+
11
+ /**
12
+ * Database related data
13
+ */
14
+ var $options = array();
15
+
16
+ /**
17
+ * Default data
18
+ */
19
+ var $options_default = array(), $site_options = array();
20
+
21
+ /**
22
+ * Hold db option keys
23
+ */
24
+ var $option_keys = array();
25
+
26
+ /**
27
+ * Hold extra option keys
28
+ */
29
+ var $extra_option_keys = array();
30
+
31
+ /**
32
+ * Hold old option pages
33
+ */
34
+ var $option_pages = array();
35
+
36
+ /**
37
+ * Key to identify plugin
38
+ */
39
+ var $plugin_key;
40
+
41
+ /**
42
+ * Constant Key to identify plugin
43
+ */
44
+ var $plugin_ckey;
45
+
46
+ /**
47
+ * Domain Key to identify plugin
48
+ */
49
+ var $plugin_dkey;
50
+
51
+ /**
52
+ * Title of the plugin
53
+ */
54
+ var $plugin_title;
55
+
56
+ /**
57
+ * Homepage of the plugin
58
+ */
59
+ var $plugin_url;
60
+
61
+ /**
62
+ * Plugin file
63
+ */
64
+ var $plugin_file;
65
+
66
+ /**
67
+ * Version of the plugin
68
+ */
69
+ var $plugin_ver = '';
70
+
71
+ /**
72
+ * Message shown to user (Warning, Notes, etc.)
73
+ */
74
+ var $notices = array(), $notice_shown = false;
75
+
76
+ /**
77
+ * Capabilities to manage this plugin
78
+ */
79
+ var $plugin_cap = 'manage_options';
80
+
81
+ /**
82
+ * Whether or not to create filter for media paths
83
+ */
84
+ var $need_media_filters;
85
+
86
+ /**
87
+ * Form tabs to build
88
+ */
89
+ var $form_tabs = array();
90
+
91
+ /**
92
+ * Other things
93
+ */
94
+ var $wp_ver = '2.8';
95
+ var $php_ver = '5';
96
+
97
+ /**
98
+ * Build base properties
99
+ */
100
+ function build_properties($key, $dkey, $options, $plugin_title = '', $plugin_file = '', $plugin_url = '', $need_media_filters = true)
101
+ {
102
+ $this->plugin_key = strtolower($key);
103
+ $this->plugin_ckey = strtoupper($key);
104
+ $this->plugin_dkey = $dkey;
105
+ $this->plugin_title = $plugin_title;
106
+ $this->plugin_url = $plugin_url;
107
+ // The default options
108
+ $this->options_default = $options;
109
+ $this->need_media_filters = (boolean) $need_media_filters;
110
+ $this->plugin_file = $plugin_file;
111
+ // Load locale
112
+ load_plugin_textdomain($dkey, false, basename(dirname($plugin_file)) . '/languages');
113
+ }
114
+
115
+ function add_option_key($key, $option, $title)
116
+ {
117
+ $this->option_keys[$key] = $option;
118
+ $this->option_pages[$key] = $title;
119
+ }
120
+
121
+ function add_extra_option_key($key, $option, $title)
122
+ {
123
+ $this->extra_option_keys[$key] = $option;
124
+ $this->option_pages[$key] = $title;
125
+ }
126
+
127
+ function add_icon()
128
+ {
129
+ return '<div class="icon32" id="icon-bwp-plugin" style=\'background-image: url("' . constant($this->plugin_ckey . '_IMAGES') . '/icon_menu_32.png");\'><br></div>' . "\n";
130
+ }
131
+
132
+ function set_version($ver = '', $type = '')
133
+ {
134
+ switch ($type)
135
+ {
136
+ case '': $this->plugin_ver = $ver;
137
+ break;
138
+ case 'php': $this->php_ver = $ver;
139
+ break;
140
+ case 'wp': $this->wp_ver = $ver;
141
+ break;
142
+ }
143
+ }
144
+
145
+ function get_version($type = '')
146
+ {
147
+ switch ($type)
148
+ {
149
+ case '': return $this->plugin_ver;
150
+ break;
151
+ case 'php': return $this->php_ver;
152
+ break;
153
+ case 'wp': return $this->wp_ver;
154
+ break;
155
+ }
156
+ }
157
+
158
+ function check_required_versions()
159
+ {
160
+ if (version_compare(PHP_VERSION, $this->php_ver, '<') || version_compare(get_bloginfo('version'), $this->wp_ver, '<'))
161
+ {
162
+ add_action('admin_notices', array($this, 'warn_required_versions'));
163
+ add_action('network_admin_notices', array($this, 'warn_required_versions'));
164
+ return false;
165
+ }
166
+ else
167
+ return true;
168
+ }
169
+
170
+ function warn_required_versions()
171
+ {
172
+ echo '<div class="error"><p>' . sprintf(__('%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</strong> or higher. The plugin will not function until you update your software. Please deactivate this plugin.', $this->plugin_dkey), $this->plugin_title, $this->wp_ver, $this->php_ver) . '</p></div>';
173
+ }
174
+
175
+ function show_donation()
176
+ {
177
+ $showable = apply_filters('bwp_donation_showable', true);
178
+ ?>
179
+ <div id="bwp-donation">
180
+ <a href="<?php echo $this->plugin_url; ?>"><?php echo $this->plugin_title; ?></a>
181
+ <small>(<a href="<?php echo str_replace('/wordpress-plugins/', '/topic/', $this->plugin_url); ?>"><?php _e('log', $this->plugin_dkey); ?></a>)</small><br />
182
+ <?php
183
+ if (true == $showable || ($this->is_multisite() && is_super_admin()))
184
+ {
185
+ ?>
186
+ <small><?php _e('You can buy me some coffees if you appreciate my work, thank you!', $this->plugin_dkey); ?></small>
187
+ <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
188
+ <p>
189
+ <input type="hidden" name="cmd" value="_s-xclick">
190
+ <input type="hidden" name="hosted_button_id" value="B65WHYLRWWCGE">
191
+ <select name="os0" style="margin: 0px;">
192
+ <option value="One cup">One cup $5.00</option>
193
+ <option value="Two cups">Two cups $10.00</option>
194
+ <option value="Five cups!">Five cups! $25.00</option>
195
+ </select>
196
+ <input class="paypal-submit" type="image" src="<?php echo plugin_dir_url($this->plugin_file) . 'includes/bwp-option-page/images/icon-paypal.gif'; ?>" border="0" name="submit" alt="Via PayPal!">
197
+ <input type="hidden" name="currency_code" value="USD">
198
+ <img alt="" border="0" src="https://www.paypalobjects.com/WEBSCR-640-20110306-1/en_US/i/scr/pixel.gif" width="1" height="1">
199
+ </p>
200
+ </form>
201
+ <?php
202
+ }
203
+ ?>
204
+ </div>
205
+ <?php
206
+ }
207
+
208
+ function show_version()
209
+ {
210
+ if (empty($this->plugin_ver)) return '';
211
+ return '<a class="nav-tab version" title="' . sprintf(esc_attr(__('You are using version %s!', $this->plugin_dkey)), $this->plugin_ver) . '">' . $this->plugin_ver . '</a>';
212
+ }
213
+
214
+ function init()
215
+ {
216
+ // Build constants
217
+ $this->build_constants();
218
+ // Build tabs
219
+ $this->build_tabs();
220
+ // Build options
221
+ $this->build_options();
222
+ // Load libraries
223
+ $this->load_libraries();
224
+ // Add actions and filters
225
+ $this->add_hooks();
226
+ // Enqueue needed media, conditionally
227
+ $this->enqueue_media();
228
+ // Load other properties
229
+ $this->init_properties();
230
+ // Loaded everything for this plugin, now you can add other things to it, such as stylesheet, etc.
231
+ do_action($this->plugin_key . '_loaded');
232
+ // Support installation and uninstallation
233
+ register_activation_hook($this->plugin_file, array($this, 'install'));
234
+ register_deactivation_hook($this->plugin_file, array($this, 'uninstall'));
235
+ // icon 32px
236
+ if ($this->is_admin_page())
237
+ {
238
+ add_filter('bwp-admin-form-icon', array($this, 'add_icon'));
239
+ add_filter('bwp-admin-plugin-version', array($this, 'show_version'));
240
+ add_action('bwp_option_action_before_form', array($this, 'show_donation'), 12);
241
+ }
242
+ }
243
+
244
+ function add_cap($cap)
245
+ {
246
+ $this->plugin_cap = $cap;
247
+ }
248
+
249
+ function build_constants()
250
+ {
251
+ define($this->plugin_ckey . '_PLUGIN_URL', $this->plugin_url);
252
+ // Path
253
+ if (true == $this->need_media_filters)
254
+ {
255
+ define($this->plugin_ckey . '_IMAGES', apply_filters($this->plugin_key . '_image_path', plugin_dir_url($this->plugin_file) . 'images'));
256
+ define($this->plugin_ckey . '_CSS', apply_filters($this->plugin_key . '_css_path', plugin_dir_url($this->plugin_file) . 'css'));
257
+ define($this->plugin_ckey . '_JS', apply_filters($this->plugin_key . '_js_path', plugin_dir_url($this->plugin_file) . 'js'));
258
+ }
259
+ else
260
+ {
261
+ define($this->plugin_ckey . '_IMAGES', plugin_dir_url($this->plugin_file) . 'images');
262
+ define($this->plugin_ckey . '_CSS', plugin_dir_url($this->plugin_file) . 'css');
263
+ define($this->plugin_ckey . '_JS', plugin_dir_url($this->plugin_file) . 'js');
264
+ }
265
+ // Option page related
266
+ define($this->plugin_ckey . '_CAPABILITY', $this->plugin_cap); // the capability needed to configure this plugin
267
+
268
+ foreach ($this->option_keys as $key => $option)
269
+ {
270
+ define(strtoupper($key), $option);
271
+ }
272
+
273
+ foreach ($this->extra_option_keys as $key => $option)
274
+ {
275
+ define(strtoupper($key), $option);
276
+ }
277
+ }
278
+
279
+ function build_options()
280
+ {
281
+ // Get all options and merge them
282
+ $options = $this->options_default;
283
+ foreach ($this->option_keys as $option)
284
+ {
285
+ $db_option = get_option($option);
286
+ if ($db_option && is_array($db_option))
287
+ $options = array_merge($options, $db_option);
288
+ // Also check for global options
289
+ $db_option = get_site_option($option);
290
+ if ($db_option && is_array($db_option))
291
+ {
292
+ foreach ($db_option as $key => $option)
293
+ {
294
+ if (in_array($key, $this->site_options))
295
+ $this->site_options[$key] = $option;
296
+ }
297
+ $options = array_merge($options, $this->site_options);
298
+ }
299
+ }
300
+ $this->options = $options;
301
+ }
302
+
303
+ function init_properties()
304
+ {
305
+ /* intentionally left blank */
306
+ }
307
+
308
+ function load_libraries()
309
+ {
310
+ /* intentionally left blank */
311
+ }
312
+
313
+ function add_hooks()
314
+ {
315
+ /* intentionally left blank */
316
+ }
317
+
318
+ function enqueue_media()
319
+ {
320
+ /* intentionally left blank */
321
+ }
322
+
323
+ function install()
324
+ {
325
+ /* intentionally left blank */
326
+ }
327
+
328
+ function uninstall()
329
+ {
330
+ /* intentionally left blank */
331
+ }
332
+
333
+ function is_admin_page()
334
+ {
335
+ if (is_admin() && !empty($_GET['page']) && (in_array($_GET['page'], $this->option_keys) || in_array($_GET['page'], $this->extra_option_keys)))
336
+ return true;
337
+ }
338
+
339
+ function plugin_action_links($links, $file)
340
+ {
341
+ $option_keys = array_values($this->option_keys);
342
+ if ($file == plugin_basename($this->plugin_file))
343
+ $links[] = '<a href="admin.php?page=' . $option_keys[0] . '">' . __('Settings') . '</a>';
344
+
345
+ return $links;
346
+ }
347
+
348
+ function init_admin()
349
+ {
350
+ add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
351
+
352
+ if ($this->is_admin_page())
353
+ {
354
+ // Load option page builder
355
+ if (!class_exists('BWP_OPTION_PAGE'))
356
+ require_once(dirname(__FILE__) . '/bwp-option-page/bwp-option-page.php');
357
+ // Enqueue style for the option page
358
+ wp_enqueue_style('bwp-option-page', plugin_dir_url($this->plugin_file) . 'includes/bwp-option-page/css/bwp-option-page.css');
359
+ }
360
+ $this->build_menus();
361
+ }
362
+
363
+ /**
364
+ * Build the Menus
365
+ */
366
+ function build_menus()
367
+ {
368
+ /* intentionally left blank */
369
+ }
370
+
371
+ function build_tabs()
372
+ {
373
+ foreach ($this->option_pages as $key => $page)
374
+ {
375
+ $pagelink = (!empty($this->option_keys[$key])) ? $this->option_keys[$key] : $this->extra_option_keys[$key];
376
+ $this->form_tabs[$page] = get_option('siteurl') . '/wp-admin/admin.php?page=' . $pagelink;
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Build the option pages
382
+ *
383
+ * Utilizes BWP Option Page Builder (@see BWP_OPTION_PAGE)
384
+ */
385
+ function build_option_pages()
386
+ {
387
+ /* intentionally left blank */
388
+ }
389
+
390
+ function add_notice($notice)
391
+ {
392
+ if (!in_array($notice, $this->notices))
393
+ {
394
+ $this->notices[] = $notice;
395
+ add_action('bwp_option_action_before_form', array($this, 'show_notices'));
396
+ }
397
+ }
398
+
399
+ function show_notices()
400
+ {
401
+ if (false == $this->notice_shown)
402
+ {
403
+ foreach ($this->notices as $notice)
404
+ {
405
+ echo '<div class="updated fade"><p>' . $notice . '</p></div>';
406
+ }
407
+ $this->notice_shown = true;
408
+ }
409
+ }
410
+
411
+ function is_multisite()
412
+ {
413
+ if (function_exists('is_multisite') && is_multisite())
414
+ return true;
415
+ return false;
416
+ }
417
+
418
+ function is_normal_admin()
419
+ {
420
+ if ($this->is_multisite() && !is_super_admin())
421
+ return true;
422
+ return false;
423
+ }
424
+ }
425
+ ?>
includes/class-bwp-gxs-cache.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE
5
+ */
6
+
7
+ class BWP_GXS_CACHE {
8
+
9
+ var $module = '';
10
+ var $cache_dir = '';
11
+ var $cache_file = '';
12
+ var $cache_time = 0;
13
+ var $gzip = false;
14
+ var $has_cache = false;
15
+ var $options;
16
+ var $now;
17
+ var $cache_header = array();
18
+ var $cache_ok = false;
19
+
20
+ function __construct($config = array())
21
+ {
22
+ global $bwp_gxs;
23
+
24
+ // Init necessary config to work with the cache
25
+ $this->options = $bwp_gxs->get_options();
26
+ $this->module = $config['module'];
27
+ $this->module_name = $config['module_name'];
28
+ $this->cache_dir = $this->options['input_cache_dir'];
29
+ $this->gzip = ('yes' == $this->options['enable_gzip']) ? true : false;
30
+ $this->cache_time = (int) $this->options['input_cache_age'] * (int) $this->options['select_time_type'];
31
+ $this->now = time();
32
+
33
+ if (empty($this->cache_dir) || !@is_writable($this->cache_dir))
34
+ $bwp_gxs->elog(sprintf(__('Cache directory ("%s") does not exist or is not writable.', 'bwp-simple-gxs'), $this->cache_dir));
35
+ else
36
+ $this->setup_cache();
37
+ }
38
+
39
+ function get_header()
40
+ {
41
+ return $this->cache_header;
42
+ }
43
+
44
+ function get_cache_file()
45
+ {
46
+ return $this->cache_file;
47
+ }
48
+
49
+ function check_cache()
50
+ {
51
+ global $bwp_gxs;
52
+
53
+ // If the cache file is not found
54
+ if (!@file_exists($this->cache_file))
55
+ {
56
+ $bwp_gxs->nlog(sprintf(__('Cache file for module <em>%s</em> is not found and will be built right away.', 'bwp-simple-gxs'), $this->module));
57
+ return false;
58
+ }
59
+ $this->has_cache = true;
60
+
61
+ return true;
62
+ }
63
+
64
+ function setup_cache()
65
+ {
66
+ global $bwp_gxs;
67
+ // Build cache file name, WPMS compatible
68
+ $file_name = 'gxs_' . md5($this->module . '_' . get_option('home'));
69
+ $file_name .= (true == $this->gzip) ? '.xml.gz' : '.xml';
70
+ $this->cache_file = trailingslashit($this->cache_dir) . $file_name;
71
+ $this->cache_ok = true;
72
+
73
+ if ($this->check_cache())
74
+ {
75
+ // So cache is found, check if we can still use it
76
+ $filemtime = @filemtime($this->cache_file);
77
+ if ($filemtime + $this->cache_time <= $this->now && 'yes' == $this->options['enable_cache_auto_gen'])
78
+ {
79
+ @unlink($this->cache_file);
80
+ $this->has_cache = false;
81
+ }
82
+
83
+ if (!$this->has_cache)
84
+ {
85
+ $header['lastmod'] = $bwp_gxs->format_header_time($this->now);
86
+ $header['expires'] = $bwp_gxs->format_header_time($this->now + $this->cache_time);
87
+ $header['etag'] = md5($header['expires'] . $this->cache_file);
88
+ }
89
+ else
90
+ {
91
+ $header['lastmod'] = $bwp_gxs->format_header_time($filemtime);
92
+ $header['expires'] = $bwp_gxs->format_header_time($filemtime + $this->cache_time);
93
+ $header['etag'] = md5($header['expires'] . $this->cache_file);
94
+ }
95
+
96
+ $this->cache_header = $header;
97
+
98
+ if ('yes' == $this->options['enable_debug'])
99
+ return;
100
+
101
+ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH']))
102
+ {
103
+ if ((isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $header['lastmod']) ||
104
+ (isset($_SERVER['HTTP_IF_NONE_MATCH']) && str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == $header['etag']))
105
+ {
106
+ $bwp_gxs->slog(sprintf(__('Successfully served a cached version of <em>%s.xml</em>.', 'bwp-simple-gxs'), $this->module_name), true);
107
+ $bwp_gxs->commit_logs();
108
+ header('HTTP/1.1 304 Not Modified');
109
+ ob_end_clean();
110
+ exit();
111
+ }
112
+ }
113
+ }
114
+ }
115
+
116
+ function write_cache()
117
+ {
118
+ global $bwp_gxs;
119
+
120
+ $file = $this->cache_file;
121
+
122
+ if (true == $this->gzip)
123
+ {
124
+ $handle = @gzopen($file, 'wb');
125
+ @flock($handle, LOCK_EX);
126
+ @gzwrite($handle, $bwp_gxs->output);
127
+ @flock($handle, LOCK_UN);
128
+ @gzclose($handle);
129
+ }
130
+ else
131
+ {
132
+ $handle = @fopen($file, 'wb');
133
+ @flock($handle, LOCK_EX);
134
+ @fwrite($handle, $bwp_gxs->output);
135
+ @flock($handle, LOCK_UN);
136
+ @fclose($handle);
137
+ }
138
+
139
+ @umask(0000);
140
+ @chmod($file, 0666);
141
+
142
+ return true;
143
+ }
144
+ }
145
+
146
+ ?>
includes/class-bwp-gxs-module.php ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE VERSION 3.0 OR LATER
5
+ */
6
+
7
+ class BWP_GXS_MODULE {
8
+
9
+ /**
10
+ * Data used to build a sitemap
11
+ */
12
+ var $data = array();
13
+
14
+ /**
15
+ * Is this a sitemapindex or a url set?
16
+ */
17
+ var $type = 'url';
18
+
19
+ /**
20
+ * Priority mapping
21
+ */
22
+ var $freq_to_pri = array('always' => 1.0, 'hourly' => 0.8, 'daily' => 0.7, 'weekly' => 0.6, 'monthly' => 0.4, 'yearly' => 0.3, 'never' => 0.2);
23
+
24
+ var $comment_count = 0, $now, $url_sofar = 0, $circle = 0;
25
+
26
+ function __contruct()
27
+ {
28
+ /*$this->comment_count = wp_count_comments();*/
29
+ }
30
+
31
+ function set_current_time()
32
+ {
33
+ $this->now = (int) time();
34
+ }
35
+
36
+ function init_data($pre_data = array())
37
+ {
38
+ global $bwp_gxs;
39
+
40
+ if (empty($pre_data) || sizeof($pre_data) == 0)
41
+ return array();
42
+
43
+ if (empty($this->now))
44
+ $this->set_current_time();
45
+
46
+ $data['location'] = '';
47
+ $data['lastmod'] = (!empty($pre_data['lastmod'])) ? strtotime($pre_data['lastmod']) - $bwp_gxs->oldest_time : $this->now - $bwp_gxs->oldest_time;
48
+ $data['lastmod'] = $this->format_lastmod($data['lastmod']);
49
+ if (isset($pre_data['freq'])) $data['freq'] = $pre_data['freq'];
50
+ if (isset($pre_data['priority'])) $data['priority'] = $pre_data['priority'];
51
+
52
+ return $data;
53
+ }
54
+
55
+ function get_xml_link($slug)
56
+ {
57
+ global $bwp_gxs;
58
+
59
+ if (!$bwp_gxs->use_permalink)
60
+ return get_option('home') . '/?' . $bwp_gxs->query_var_non_perma . '=' . $slug;
61
+ else
62
+ return get_option('home') . '/' . $slug . '.xml';
63
+ }
64
+
65
+ /**
66
+ * Calculate the change frequency for a specific item.
67
+ *
68
+ * @copyright (c) 2006 - 2009 www.phpbb-seo.com
69
+ */
70
+ function cal_frequency($item = '')
71
+ {
72
+ global $bwp_gxs;
73
+
74
+ if (empty($this->now))
75
+ $this->now = $this->set_current_time();
76
+
77
+ if (!is_object($item))
78
+ $freq = $bwp_gxs->options['select_default_freq'];
79
+ else
80
+ {
81
+ $time = $this->now - (int) strtotime($item->post_modified);
82
+ $freq = $time > 30000000 ? 'yearly' : ($time > 2592000 ? 'monthly' : ($time > 604800 ? 'weekly' : ($time > 86400 ? 'daily' : ($time > 43200 ? 'hourly' : 'always'))));
83
+ }
84
+ return apply_filters('bwp_gxs_freq', $freq, $item);
85
+ }
86
+
87
+ /**
88
+ * Calculate the priority for a specific item.
89
+ *
90
+ * This is just a basic way to calculate priority and module should use its own function instead.
91
+ * Search engines don't really care about priority and change frequency much, do they ;)?
92
+ */
93
+ function cal_priority($item, $freq = 'daily')
94
+ {
95
+ global $bwp_gxs;
96
+
97
+ if (empty($this->now))
98
+ $this->now = $this->set_current_time();
99
+
100
+ if (!is_object($item)) // determine score by change frequency
101
+ $score = $this->freq_to_pri[$freq];
102
+ else
103
+ {
104
+ $comment = (!empty($item->comment_count)) ? $item->comment_count : 1;
105
+ // There is no magic behind this, number of comments and freshness define priority
106
+ // yes, 164 is a lucky (and random) number :). Actually this number works well with current Unix Timestamp,
107
+ // which is larger than 13m.
108
+ $score = $this->now + ($this->now - (int) strtotime($item->post_modified)) / $comment * 164;
109
+ $score = $this->now / $score;
110
+ }
111
+
112
+ $score = ($score < $bwp_gxs->options['select_min_pri']) ? $bwp_gxs->options['select_min_pri'] : $score;
113
+
114
+ // For people who doesn't like using module
115
+ return apply_filters('bwp_gxs_priority_score', $score, $item, $freq);
116
+ }
117
+
118
+ function format_lastmod($lastmod)
119
+ {
120
+ return gmdate('Y-m-d\TH:i:s' . '+00:00', (int) $lastmod);
121
+ }
122
+
123
+ function post_type_uses($post_type, $taxonomy_object)
124
+ {
125
+ if (isset($taxonomy_object->object_type) && is_array($taxonomy_object->object_type) && in_array($post_type, $taxonomy_object->object_type))
126
+ return true;
127
+ return false;
128
+ }
129
+
130
+ function get_post_by_post_type($post_type, $result)
131
+ {
132
+ if (!isset($result) || !is_array($result))
133
+ return false;
134
+
135
+ foreach ($result as $post)
136
+ {
137
+ if ($post_type == $post->post_type)
138
+ return $post;
139
+ }
140
+
141
+ return false;
142
+ }
143
+
144
+ function sort_data_by($column = 'lastmod')
145
+ {
146
+ if (!isset($this->data[0][$column]))
147
+ return false;
148
+ // Obtain a list of columns
149
+ $lastmod = array();
150
+ foreach ($this->data as $key => $row)
151
+ $lastmod[$key] = $row[$column];
152
+ // Sort the data with volume descending, edition ascending
153
+ // Add $data as the last parameter, to sort by the common key
154
+ array_multisort($lastmod, SORT_DESC, $this->data);
155
+ }
156
+
157
+ /**
158
+ * Always call this function when you query for something.
159
+ *
160
+ * $query_str should be already escaped using either $wpdb->escape() or $wpdb->prepare().
161
+ */
162
+ function get_results($query_str)
163
+ {
164
+ global $bwp_gxs, $wpdb;
165
+
166
+ $start = (!empty($this->url_sofar)) ? (int) $this->url_sofar + $this->circle : (int) $this->url_sofar;
167
+ $end = (int) $bwp_gxs->options['input_sql_limit'];
168
+ $query_str = trim($query_str);
169
+ $query_str .= ' LIMIT ' . $start . ',' . $end;
170
+ $this->circle += 1;
171
+
172
+ return $wpdb->get_results($query_str);
173
+ }
174
+
175
+ /**
176
+ * Always call this function when you query for something.
177
+ *
178
+ * $query_str should be similar to what WP_Query accepts.
179
+ */
180
+ function query_posts($query_str)
181
+ {
182
+ $this->circle += 1;
183
+ if (is_array($query_str))
184
+ {
185
+ $query_str['posts_per_page'] = (int) $bwp_gxs->options['input_sql_limit'];
186
+ $query_str['paged'] = $this->circle;
187
+ }
188
+ else if (is_string($query_str))
189
+ {
190
+ $query_str = trim($query_str);
191
+ $query_str .= '&posts_per_page=' . (int) $bwp_gxs->options['input_sql_limit'];
192
+ $query_str .= '&paged=' . $this->circle;
193
+ }
194
+ $query = new WP_Query($query_str);
195
+ return $query;
196
+ }
197
+
198
+ function generate_data()
199
+ {
200
+ return false;
201
+ }
202
+
203
+ function build_data()
204
+ {
205
+ global $bwp_gxs;
206
+
207
+ while (false != $this->generate_data() && $this->url_sofar < $bwp_gxs->options['input_item_limit'])
208
+ $this->url_sofar = sizeof($this->data);
209
+
210
+ // Sort the data by lastmod
211
+ //$this->sort_data_by();
212
+ }
213
+ }
214
+ ?>
includes/class-bwp-simple-gxs.php ADDED
@@ -0,0 +1,1307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ if (!class_exists('BWP_FRAMEWORK'))
20
+ require_once(dirname(__FILE__) . '/class-bwp-framework.php');
21
+
22
+ class BWP_SIMPLE_GXS extends BWP_FRAMEWORK {
23
+
24
+ /**
25
+ * Debugging the plugin
26
+ */
27
+ var $debug = true, $logs = array('log' => array(), 'sitemap' => array());
28
+
29
+ /**
30
+ * Modules to load when generating sitemapindex
31
+ */
32
+ var $allowed_modules = array(), $requested_modules = array();
33
+
34
+ /**
35
+ * Directory to load modules from
36
+ */
37
+ var $module_directory = '';
38
+
39
+ /**
40
+ * The permalink structure for sitemap files
41
+ */
42
+ var $module_url = array();
43
+
44
+ /**
45
+ * Frequency & priority
46
+ */
47
+ var $frequency = array('always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never');
48
+ var $priority = array('0.1' => 0.1, '0.2' => 0.2, '0.3' => 0.3, '0.4' => 0.4, '0.5' => 0.5, '0.6' => 0.6, '0.7' => 0.7, '0.8' => 0.8, '0.9' => 0.9, '1.0' => 1.0);
49
+
50
+ /**
51
+ * Other properties
52
+ */
53
+ var $post_types, $taxonomies, $terms, $cache_time, $module_data, $output, $num_log = 25;
54
+ var $templates = array(), $module_map = array();
55
+ var $sitemap_alias = array(), $use_permalink = true, $query_var_non_perma = '';
56
+ var $ping_per_day = 100, $timeout = 3;
57
+ var $xslt = '', $xslt_index = '';
58
+ // @since 1.0.1
59
+ var $build_data = array('time', 'mem', 'query');
60
+
61
+ /**
62
+ * Constructor
63
+ */
64
+ function __construct($version = '1.0.5')
65
+ {
66
+ // Plugin's title
67
+ $this->plugin_title = 'BWP Google XML Sitemaps';
68
+ // Plugin's version
69
+ $this->set_version($version);
70
+ $this->set_version('3.0', 'wp');
71
+ // Basic version checking
72
+ if (!$this->check_required_versions())
73
+ return;
74
+
75
+ // Default options
76
+ $options = array(
77
+ 'enable_cache' => 'yes',
78
+ 'enable_cache_auto_gen' => 'yes',
79
+ 'enable_gzip' => 'yes',
80
+ 'enable_xslt' => 'yes',
81
+ 'enable_sitemap_page' => 'yes',
82
+ 'enable_sitemap_date' => '',
83
+ 'enable_sitemap_taxonomy' => 'yes',
84
+ 'enable_sitemap_tag' => 'yes',
85
+ 'enable_stats' => 'yes',
86
+ 'enable_credit' => 'yes',
87
+ 'enable_ping' => 'yes',
88
+ 'enable_ping_google' => 'yes',
89
+ 'enable_ping_yahoo' => 'yes',
90
+ 'enable_ping_bing' => 'yes',
91
+ 'enable_ping_ask' => '',
92
+ 'enable_log' => 'yes',
93
+ 'enable_debug' => '',
94
+ 'enable_robots' => 'yes',
95
+ 'input_cache_age' => 1,
96
+ 'input_item_limit' => 10000,
97
+ 'input_alt_module_dir' => $this->uni_path_sep(ABSPATH),
98
+ 'input_oldest' => 30,
99
+ 'input_sql_limit' => 1000,
100
+ 'input_custom_xslt' => '',
101
+ 'select_output_type' => 'concise',
102
+ 'select_time_type' => 3600,
103
+ 'select_oldest_type' => 86400,
104
+ 'select_default_freq' => 'daily',
105
+ 'select_default_pri' => 1.0,
106
+ 'select_min_pri' => 0.1,
107
+ 'input_cache_dir' => '',
108
+ 'input_ping' => array(
109
+ 'google' => 'http://www.google.com/webmasters/sitemaps/ping?sitemap=%s',
110
+ 'yahoo' => 'http://search.yahooapis.com/SiteExplorerService/V1/ping?sitemap=%s',
111
+ 'bing' => 'http://www.bing.com/webmaster/ping.aspx?siteMap=%s',
112
+ 'ask' => 'http://submissions.ask.com/ping?sitemap=%s'),
113
+ 'input_sitemap_url' => '',
114
+ 'input_sitemap_struct' => ''
115
+ );
116
+ // Super admin only options
117
+ $this->site_options = array('enable_robots', 'enable_log', 'enable_debug', 'enable_ping', 'enable_ping_google', 'enable_ping_yahoo', 'enable_ping_bing', 'enable_ping_ask', 'enable_gzip', 'enable_cache', 'enable_cache_auto_gen', 'input_cache_age', 'input_alt_module_dir', 'input_sql_limit', 'input_cache_dir', 'select_time_type');
118
+
119
+ $this->build_properties('BWP_GXS', 'bwp-simple-gxs', $options, 'BWP Google XML Sitemaps', dirname(dirname(__FILE__)) . '/bwp-simple-gxs.php', 'http://betterwp.net/wordpress-plugins/google-xml-sitemaps/', false);
120
+
121
+ $this->add_option_key('BWP_GXS_STATS', 'bwp_gxs_stats', __('Sitemap Statistics', 'bwp-simple-gxs'));
122
+ $this->add_option_key('BWP_GXS_OPTION_GENERATOR', 'bwp_gxs_generator', __('Sitemap Generator', 'bwp-simple-gxs'));
123
+
124
+ define('BWP_GXS_LOG', 'bwp_gxs_log');
125
+ define('BWP_GXS_PING', 'bwp_gxs_ping_data');
126
+
127
+ $this->init();
128
+ }
129
+
130
+ function init_properties()
131
+ {
132
+ // Try to surpress all errors so we don't have an encoding error page, don't do this when debug is on
133
+ if ('yes' != $this->options['enable_debug'])
134
+ error_reporting(0);
135
+
136
+ $this->module_directory = plugin_dir_path($this->plugin_file) . 'includes/modules/';
137
+
138
+ $this->templates = array(
139
+ 'sitemap' => "\n\t" . '<sitemap>' . "\n\t\t" . '<loc>%s</loc>%s' . "\n\t" . '</sitemap>',
140
+ 'url' => "\n\t" . '<url>' . "\n\t\t" . '<loc>%1$s</loc>%2$s%3$s%4$s' . "\n\t" . '</url>',
141
+ 'lastmod' => "\n\t\t" . '<lastmod>%s</lastmod>',
142
+ 'changefreq' => "\n\t\t" . '<changefreq>%s</changefreq>',
143
+ 'priority' => "\n\t\t" . '<priority>%.1f</priority>',
144
+ 'xslt_style' => '',
145
+ 'stats' => "\n" . '<!-- ' . __('This sitemap was originally generated in %s second(s) (Memory usage: %s) - %s queries - %s URL(s) listed', 'bwp-simple-gxs') . ' -->'
146
+ /*'stats_cached' => "\n" . '<!-- ' . __('Served from cache in %s second(s) (Memory usage: %s) - %s queries - %s URL(s) listed', 'bwp-simple-gxs') . ' -->'*/
147
+ );
148
+
149
+ $this->init_gzip();
150
+
151
+ $this->cache_time = (int) $this->options['input_cache_age'] * (int) $this->options['select_time_type'];
152
+ $this->oldest_time = (int) $this->options['input_oldest'] * (int) $this->options['select_oldest_type'];
153
+ $this->options['input_cache_dir'] = plugin_dir_path($this->plugin_file) . 'cache/';
154
+ $this->options['input_cache_dir'] = $this->uni_path_sep($this->options['input_cache_dir']);
155
+
156
+ $module_map = apply_filters('bwp_gxs_module_mapping', array());
157
+ $this->module_map = wp_parse_args($module_map, array('post_format' => 'post_tag'));
158
+
159
+ // Logs
160
+ $this->logs = get_option(BWP_GXS_LOG);
161
+ if (!$this->logs)
162
+ $this->logs = array('log' => array(), 'sitemap' => array());
163
+ foreach ($this->logs as $key => $log)
164
+ if (is_array($log) && $this->num_log < sizeof($log))
165
+ {
166
+ $log = array_slice($log, (-1) * $this->num_log);
167
+ $this->logs[$key] = $log;
168
+ }
169
+
170
+ // Sitemap based on permastruct
171
+ if (!get_option('permalink_structure'))
172
+ {
173
+ $this->use_permalink = false;
174
+ $this->query_var_non_perma = apply_filters('bwp_gxs_query_var_non_perma', 'bwpsitemap');
175
+ $this->options['input_sitemap_url'] = get_option('home') . '/?' . $this->query_var_non_perma . '=sitemapindex';
176
+ $this->options['input_sitemap_struct'] = get_option('home') . '/?' . $this->query_var_non_perma . '=%s';
177
+ }
178
+ else
179
+ {
180
+ $this->options['input_sitemap_url'] = get_option('home') . '/sitemapindex.xml';
181
+ $this->options['input_sitemap_struct'] = get_option('home') . '/%s.xml';
182
+ }
183
+
184
+ // No more than 50000 URL per sitemap
185
+ if (50000 < (int) $this->options['input_item_limit'])
186
+ $this->options['input_item_limit'] = 50000;
187
+
188
+ // XSLT style sheet
189
+ if ('yes' == $this->options['enable_xslt'])
190
+ {
191
+ $this->xslt = (!empty($this->options['input_custom_xslt'])) ? $this->options['input_custom_xslt'] : trailingslashit(plugins_url('', $this->plugin_file)) . 'xsl/bwp-sitemap.xsl';
192
+ $this->xslt = apply_filters('bwp_gxs_xslt', $this->xslt);
193
+ $this->xslt_index = (empty($this->xslt)) ? '' : str_replace('.xsl', 'index.xsl', $this->xslt);
194
+ }
195
+
196
+ // Some stats
197
+ $this->build_stats['mem'] = memory_get_usage();
198
+ }
199
+
200
+ function enqueue_media()
201
+ {
202
+ if (is_admin())
203
+ wp_enqueue_style('bwp-gxs-admin', BWP_GXS_CSS . '/bwp-simple-gxs.css');
204
+ }
205
+
206
+ function insert_query_vars($vars)
207
+ {
208
+ if (!$this->use_permalink)
209
+ array_push($vars, $this->query_var_non_perma);
210
+ else
211
+ {
212
+ array_push($vars, 'gxs_module');
213
+ array_push($vars, 'gxs_sub_module');
214
+ }
215
+ return $vars;
216
+ }
217
+
218
+ function check_rewrite_rules()
219
+ {
220
+ global $wp_rewrite;
221
+ // Check rewrite rules - @since 1.0.3
222
+ $rules = get_option('rewrite_rules');
223
+ if (!empty($rules) && is_array($rules) && (!isset($rules['sitemapindex\.xml$']) || !isset($rules['post\.xml$'])))
224
+ {
225
+ add_filter('rewrite_rules_array', array($this, 'insert_rewrite_rules'));
226
+ $wp_rewrite->flush_rules();
227
+ }
228
+ }
229
+
230
+ function insert_rewrite_rules($rules)
231
+ {
232
+ // More compatible with blogs that are set up with sitemap.xml - @since 1.0.1
233
+ $rewrite_rules = array(
234
+ 'sitemap\.xml$' => 'index.php?gxs_module=sitemapindex',
235
+ 'sitemapindex\.xml$' => 'index.php?gxs_module=sitemapindex',
236
+ 'page\.xml$' => 'index.php?gxs_module=page',
237
+ 'post\.xml$' => 'index.php?gxs_module=post',
238
+ '([a-z0-9]+)_([a-z0-9_-]+)\.xml$' => 'index.php?gxs_module=$matches[1]&gxs_sub_module=$matches[2]'
239
+ );
240
+ // @since 1.0.3
241
+ $custom_rules = apply_filters('bwp_gxs_rewrite_rules', array());
242
+ $rules = array_merge($custom_rules, $rewrite_rules, $rules);
243
+ return $rules;
244
+ }
245
+
246
+ function add_hooks()
247
+ {
248
+ add_action('init', array($this, 'check_rewrite_rules'));
249
+ add_filter('query_vars', array($this, 'insert_query_vars'));
250
+ add_action('parse_request', array($this, 'request_sitemap'));
251
+ if ('yes' == $this->options['enable_ping'])
252
+ {
253
+ add_action('draft_to_publish', array($this, 'ping'), 1000);
254
+ add_action('new_to_publish', array($this, 'ping'), 1000);
255
+ add_action('pending_to_publish', array($this, 'ping'), 1000);
256
+ add_action('future_to_publish', array($this, 'ping'), 1000);
257
+ }
258
+ if ('yes' == $this->options['enable_robots'])
259
+ {
260
+ add_filter('robots_txt', array($this, 'do_robots'), 1000, 2);
261
+ }
262
+ }
263
+
264
+ function install()
265
+ {
266
+ global $wp_rewrite;
267
+ add_filter('rewrite_rules_array', array($this, 'insert_rewrite_rules'));
268
+ $wp_rewrite->flush_rules();
269
+ }
270
+
271
+ function uninstall()
272
+ {
273
+ global $wp_rewrite;
274
+ $this->logs = array('log' => array(), 'sitemap' => array());
275
+ $this->commit_logs();
276
+ $wp_rewrite->flush_rules();
277
+ }
278
+
279
+ /**
280
+ * Build the Menus
281
+ */
282
+ function build_menus()
283
+ {
284
+ add_menu_page(__('BWP Google XML Sitemaps', 'bwp-simple-gxs'), 'BWP GXS', BWP_GXS_CAPABILITY, BWP_GXS_STATS, array($this, 'build_option_pages'), BWP_GXS_IMAGES . '/icon_menu.png');
285
+ // Sub menus
286
+ add_submenu_page(BWP_GXS_STATS, __('BWP Google XML Sitemaps Statistics', 'bwp-simple-gxs'), __('Sitemap Statistics', 'bwp-simple-gxs'), BWP_GXS_CAPABILITY, BWP_GXS_STATS, array($this, 'build_option_pages'));
287
+ add_submenu_page(BWP_GXS_STATS, __('BWP Google XML Sitemaps Generator', 'bwp-simple-gxs'), __('Sitemap Generator', 'bwp-simple-gxs'), BWP_GXS_CAPABILITY, BWP_GXS_OPTION_GENERATOR, array($this, 'build_option_pages'));
288
+ }
289
+
290
+ /**
291
+ * Build the option pages
292
+ *
293
+ * Utilizes BWP Option Page Builder (@see BWP_OPTION_PAGE)
294
+ */
295
+ function build_option_pages()
296
+ {
297
+ if (!current_user_can(BWP_GXS_CAPABILITY))
298
+ wp_die(__('You do not have sufficient permissions to access this page.'));
299
+
300
+ // Init the class
301
+ $page = $_GET['page'];
302
+ $bwp_option_page = new BWP_OPTION_PAGE($page, $this->site_options);
303
+
304
+ $options = array();
305
+
306
+ if (!empty($page))
307
+ {
308
+ if ($page == BWP_GXS_STATS)
309
+ {
310
+ $bwp_option_page->set_current_tab(1);
311
+
312
+ $form = array(
313
+ 'items' => array('heading', 'heading', 'heading', 'heading', 'checkbox', 'section', 'heading', 'checkbox', 'checkbox'),
314
+ 'item_labels' => array
315
+ (
316
+ __('What are Sitemaps?', 'bwp-simple-gxs'),
317
+ __('Your sitemaps', 'bwp-simple-gxs'),
318
+ __('Submit your sitemaps', 'bwp-simple-gxs'),
319
+ __('Pinging search engines', 'bwp-simple-gxs'),
320
+ __('Enable pinging functionality?', 'bwp-simple-gxs'),
321
+ __('Enable pinging individual SE', 'bwp-simple-gxs'),
322
+ __('Sitemap Generator\'s Log', 'bwp-simple-gxs'),
323
+ __('Enable logging?', 'bwp-simple-gxs'),
324
+ __('Enable debugging?', 'bwp-simple-gxs')
325
+ ),
326
+ 'item_names' => array('h1', 'h2', 'h4', 'h5', 'cb1', 'sec1', 'h3', 'cb2', 'cb3'),
327
+ 'sec1' => array(
328
+ array('checkbox', 'name' => 'cb4'),
329
+ array('checkbox', 'name' => 'cb5'),
330
+ array('checkbox', 'name' => 'cb6'),
331
+ array('checkbox', 'name' => 'cb7')
332
+ ),
333
+ 'heading' => array(
334
+ 'h1' => __('In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional metadata about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site &mdash; <em>http://www.sitemaps.org/</em>', 'bwp-simple-gxs'),
335
+ 'h2' => __('<em>Basic information about all your sitemaps.</em>', 'bwp-simple-gxs'),
336
+ 'h3' => __('<em>More detailed information about how your sitemaps are generated including <span style="color: #999999;">notices</span>, <span style="color: #FF0000;">errors</span> and <span style="color: #009900;">success messages</span>.</em>', 'bwp-simple-gxs'),
337
+ 'h4' => sprintf(__('<em>Submit your sitemapindex to major search engines like <a href="%s" target="_blank">Google</a>, <a href="%s" target="_blank">Yahoo</a>, <a href="%s" target="_blank">Bing</a> or <a href="%s" target="_blank">Ask</a>.</em>', 'bwp-simple-gxs'), 'https://www.google.com/webmasters/tools/home?hl=en', 'https://siteexplorer.search.yahoo.com/mysites', 'http://www.bing.com/toolbox/webmasters/', 'http://about.ask.com/en/docs/about/webmasters.shtml#22'),
338
+ 'h5' => __('<em>Now when you post something new to your blog, you can <em>ping</em> those search engines to tell them your blog just got updated. Pinging could be less effective than you think it is but you should enable such feature anyway.</em>', 'bwp-simple-gxs')
339
+ ),
340
+ 'input' => array(
341
+ ),
342
+ 'checkbox' => array(
343
+ 'cb1' => array(__('Selected SE below will be pinged when you publish new posts.', 'bwp-simple-gxs') => 'enable_ping'),
344
+ 'cb2' => array(__('No additional load is needed so enabling this is recommended.', 'bwp-simple-gxs') => 'enable_log'),
345
+ 'cb3' => array(__('Minor errors will be printed on screen. Also, when debug is on, no caching is used, useful when you develop new modules.', 'bwp-simple-gxs') => 'enable_debug'),
346
+ 'cb4' => array(__('Google', 'bwp-simple-gxs') => 'enable_ping_google'),
347
+ 'cb5' => array(sprintf(__('Yahoo &mdash; <a href="%s" target="_blank">important</a>', 'bwp-simple-gxs'), 'http://developer.yahoo.com/blogs/ydn/posts/2010/08/api_updates_and_changes/') => 'enable_ping_yahoo'),
348
+ 'cb6' => array(__('Bing', 'bwp-simple-gxs') => 'enable_ping_bing'),
349
+ 'cb7' => array(__('Ask.com', 'bwp-simple-gxs') => 'enable_ping_ask')
350
+ ),
351
+ 'container' => array(
352
+ 'h4' => sprintf(__('After you activate this plugin, all sitemaps should be available right away. The next step is to submit the sitemapindex to major search engines. You only need the <strong>sitemapindex</strong> and nothing else, those search engines will automatically recognize other included sitemaps. You can read a small <a href="%s">How-to</a> if you are interested.', 'bwp-simple-gxs'), 'http://help.yahoo.com/l/us/yahoo/smallbusiness/store/promote/sitemap/sitemap-06.html'),
353
+ 'h3' => $this->get_logs(),
354
+ 'h2' => $this->get_logs(true)
355
+ )
356
+ );
357
+
358
+ // Get the options
359
+ $options = $bwp_option_page->get_options(array('enable_ping', 'enable_ping_google', 'enable_ping_yahoo', 'enable_ping_bing', 'enable_ping_ask', 'enable_log', 'enable_debug'), $this->options);
360
+
361
+ // Get option from the database
362
+ $options = $bwp_option_page->get_db_options($page, $options);
363
+ $option_ignore = array('input_update_services');
364
+ $option_formats = array();
365
+ // [WPMS Compatible]
366
+ $option_super_admin = $this->site_options;
367
+ }
368
+ else if ($page == BWP_GXS_OPTION_GENERATOR)
369
+ {
370
+ $bwp_option_page->set_current_tab(2);
371
+
372
+ $form = array(
373
+ 'items' => array('input', 'select', 'select', 'select', 'checkbox', 'section', 'checkbox', 'input', 'checkbox', 'checkbox', 'checkbox', 'heading', 'input', 'input', 'heading', 'checkbox', 'checkbox', 'input', 'input'),
374
+ 'item_labels' => array
375
+ (
376
+ __('Output no more than', 'bwp-simple-gxs'),
377
+ __('Default change frequency', 'bwp-simple-gxs'),
378
+ __('Default priority', 'bwp-simple-gxs'),
379
+ __('Minimum priority', 'bwp-simple-gxs'),
380
+ __('Add sitemapindex to WordPress\'s virtual robots.txt?', 'bwp-simple-gxs'),
381
+ __('In sitemapindex, include', 'bwp-simple-gxs'),
382
+ __('Style your sitemaps with an XSLT stylesheet?', 'bwp-simple-gxs'),
383
+ __('Custom XSLT stylesheet URL', 'bwp-simple-gxs'),
384
+ __('Show build stats in sitemaps?', 'bwp-simple-gxs'),
385
+ __('Enable credit?', 'bwp-simple-gxs'),
386
+ __('Enable Gzip?', 'bwp-simple-gxs'),
387
+ __('Module Options', 'bwp-simple-gxs'),
388
+ __('Alternate module directory', 'bwp-simple-gxs'),
389
+ __('Get no more than', 'bwp-simple-gxs'),
390
+ __('Caching Options', 'bwp-simple-gxs'),
391
+ __('Enable caching?', 'bwp-simple-gxs'),
392
+ __('Enable auto cache re-generation?', 'bwp-simple-gxs'),
393
+ __('Cached sitemaps will last for', 'bwp-simple-gxs'),
394
+ __('Cached sitemaps are stored in (auto detected)', 'bwp-simple-gxs')
395
+ ),
396
+ 'item_names' => array('input_item_limit', 'select_default_freq', 'select_default_pri', 'select_min_pri', 'cb11', 'sec1', 'cb10', 'input_custom_xslt', 'cb3', 'cb6', 'cb4', 'h4', 'input_alt_module_dir', 'input_sql_limit', 'h3', 'cb1', 'cb2', 'input_cache_age', 'input_cache_dir'),
397
+ 'heading' => array(
398
+ 'h3' => __('<em>Cache your sitemaps for better performance.</em>', 'bwp-simple-gxs'),
399
+ 'h4' => sprintf(__('<em>This plugin uses modules to build sitemap data so it is recommended that you extend this plugin using modules rather than hooks. Some of the settings below only affect modules extending the base module class. Read more about using modules <a href="%s#using-modules">here</a>.</em>', 'bwp-simple-gxs'), $this->plugin_url)
400
+ ),
401
+ 'sec1' => array(
402
+ array('checkbox', 'name' => 'cb5'),
403
+ array('checkbox', 'name' => 'cb7'),
404
+ array('checkbox', 'name' => 'cb8'),
405
+ array('checkbox', 'name' => 'cb9')
406
+ ),
407
+ 'select' => array(
408
+ 'select_time_type' => array(
409
+ __('second(s)', 'bwp-simple-gxs') => 1,
410
+ __('minute(s)', 'bwp-simple-gxs') => 60,
411
+ __('hour(s)', 'bwp-simple-gxs') => 3600,
412
+ __('day(s)', 'bwp-simple-gxs') => 86400
413
+ ),
414
+ 'select_oldest_type' => array(
415
+ __('second(s)', 'bwp-simple-gxs') => 1,
416
+ __('minute(s)', 'bwp-simple-gxs') => 60,
417
+ __('hour(s)', 'bwp-simple-gxs') => 3600,
418
+ __('day(s)', 'bwp-simple-gxs') => 86400
419
+ ),
420
+ 'select_default_freq' => array(),
421
+ 'select_default_pri' => $this->priority,
422
+ 'select_min_pri' => $this->priority
423
+ ),
424
+ 'post' => array(
425
+ 'select_default_freq' => sprintf('<a href="%s" target="_blank">' . __('read more', 'bwp-simple-gxs') . '</a>', 'http://sitemaps.org/protocol.php#xmlTagDefinitions'),
426
+ 'select_default_pri' => sprintf('<a href="%s" target="_blank">' . __('read more', 'bwp-simple-gxs') . '</a>', 'http://sitemaps.org/protocol.php#xmlTagDefinitions'),
427
+ 'select_min_pri' => sprintf('<a href="%s" target="_blank">' . __('read more', 'bwp-simple-gxs') . '</a>', 'http://sitemaps.org/protocol.php#xmlTagDefinitions')
428
+ ),
429
+ 'checkbox' => array(
430
+ 'cb1' => array(__('your sitemaps are generated and then cached to reduce unnecessary work.', 'bwp-simple-gxs') => 'enable_cache'),
431
+ 'cb2' => array(__('when a cached sitemap expires, this plugin will try to generate the cache again. If you disable this, remember to manually flush the cache once in a while.', 'bwp-simple-gxs') . ' <input type="submit" class="button-secondary action" name="flush_cache" value="' . __('Flush the cache', 'bwp-simple-gxs') . '" />' => 'enable_cache_auto_gen'),
432
+ 'cb3' => array(__('tell you useful information such as build time, memory usage, SQL queries, etc.', 'bwp-simple-gxs') => 'enable_stats'),
433
+ 'cb4' => array(__('make your sitemaps ~ 70% smaller.', 'bwp-simple-gxs') => 'enable_gzip'),
434
+ 'cb5' => array(__("static pages' sitemap.", 'bwp-simple-gxs') => 'enable_sitemap_page'),
435
+ 'cb7' => array(__("taxonomy archives' sitemaps, including custom taxonomies.", 'bwp-simple-gxs') => 'enable_sitemap_taxonomy'),
436
+ 'cb8' => array(__("tag archives' sitemaps.", 'bwp-simple-gxs') => 'enable_sitemap_tag'),
437
+ 'cb9' => array(__("date archives' sitemaps.", 'bwp-simple-gxs') => 'enable_sitemap_date'),
438
+ 'cb6' => array(__('some copyrighted info is also added to your sitemaps. Thanks!', 'bwp-simple-gxs') => 'enable_credit'),
439
+ 'cb10' => array(__('This will load the default stylesheet provided by this plugin. You can set a custom stylesheet below or filter the <code>bwp_gxs_xslt</code> hook.', 'bwp-simple-gxs') => 'enable_xslt'),
440
+ 'cb11' => array(sprintf(__('If you\'re on a Multi-site installation with Sub-domain enabled, each site will have its own robots.txt, sites in sub-directory will not. Please read the <a href="%s#toc-robots" target="_blank">documentation</a> for more info.', 'bwp-simple-gxs'), $this->plugin_url) => 'enable_robots')
441
+ ),
442
+ 'input' => array(
443
+ 'input_item_limit' => array('size' => 5, 'label' => __('item(s) in one sitemap. Actually, 5000 would be more ideal. You can not go over 50,000, though.', 'bwp-simple-gxs')),
444
+ 'input_alt_module_dir' => array('size' => 91, 'label' => __('Input a full path to the directory where you put your own modules (e.g. <code>/home/mysite/public_html/gxs-modules/</code>), you can also override a built-in module by having a module with the same filename in this directory. A filter is also available if you would like to use PHP instead.', 'bwp-simple-gxs')),
445
+ 'input_cache_dir' => array('size' => 91, 'disabled' => ' disabled="disabled"', 'label' => __('The cache directory must be writable (i.e. CHMOD to 755 or 777).', 'bwp-simple-gxs')),
446
+ 'input_sql_limit' => array('size' => 5, 'label' => __('item(s) in one SQL query. This helps you avoid running too heavy queries.', 'bwp-simple-gxs')),
447
+ 'input_oldest' => array('size' => 3, 'label' => '&mdash;'),
448
+ 'input_cache_age' => array('size' => 5, 'label' => '&mdash;'),
449
+ 'input_custom_xslt' => array('size' => 90, 'label' => __('expected to be an absolute URL, e.g. <code>http://example.com/my-stylesheet.xsl</code>. You must also have a style sheet for the sitemapindex that can be accessed through the above URL, e.g. <code>my-stylesheet.xsl</code> and <code>my-stylesheetindex.xsl</code>). Please leave blank if you do not wish to use.', 'bwp-simple-gxs'))
450
+ ),
451
+ 'inline_fields' => array(
452
+ 'input_cache_age' => array('select_time_type' => 'select')
453
+ )
454
+ );
455
+
456
+ foreach ($this->frequency as $freq)
457
+ $changefreq[ucfirst($freq)] = $freq;
458
+ $form['select']['select_default_freq'] = $changefreq;
459
+
460
+ // Get the options
461
+ $options = $bwp_option_page->get_options(array('input_item_limit', 'input_alt_module_dir', 'input_cache_dir', 'input_sql_limit', 'input_cache_age', 'input_custom_xslt', 'enable_robots', 'enable_xslt', 'enable_cache', 'enable_cache_auto_gen', 'enable_stats', 'enable_credit', 'enable_sitemap_page', 'enable_sitemap_date', 'enable_sitemap_taxonomy', 'enable_sitemap_tag', 'enable_sitemap_format', 'enable_gzip', 'select_time_type', 'select_default_freq', 'select_default_pri', 'select_min_pri'), $this->options);
462
+
463
+ // Get option from the database
464
+ $options = $bwp_option_page->get_db_options($page, $options);
465
+
466
+ $option_formats = array('input_item_limit' => 'int', 'input_sql_limit' => 'int', 'input_cache_age' => 'int', 'select_time_type' => 'int');
467
+ $option_ignore = array('input_cache_dir');
468
+ // [WPMS Compatible]
469
+ $option_super_admin = $this->site_options;
470
+ }
471
+ }
472
+ // Flush the cache
473
+ if (isset($_POST['flush_cache']) && !$this->is_normal_admin())
474
+ {
475
+ if ($deleted = $this->flush_cache())
476
+ $this->add_notice('<strong>' . __('Notice', 'bwp-simple-gxs') . ':</strong> ' . sprintf(__("<strong>%d</strong> cached sitemaps have been flushed successfully!", 'bwp-simple-gxs'), $deleted));
477
+ else
478
+ $this->add_notice('<strong>' . __('Notice', 'bwp-simple-gxs') . ':</strong> ' . __("Could not delete any cached sitemaps. Please manually check the cache directory.", 'bwp-simple-gxs'));
479
+ }
480
+ // Get option from user input
481
+ if (isset($_POST['submit_' . $bwp_option_page->get_form_name()]) && isset($options) && is_array($options))
482
+ {
483
+ check_admin_referer($page);
484
+ foreach ($options as $key => &$option)
485
+ {
486
+ // [WPMS Compatible]
487
+ if ($this->is_normal_admin() && in_array($key, $option_super_admin))
488
+ {}
489
+ else if (in_array($key, $option_ignore))
490
+ {}
491
+ else
492
+ {
493
+ if (isset($_POST[$key]))
494
+ $bwp_option_page->format_field($key, $option_formats);
495
+ if (!isset($_POST[$key]))
496
+ $option = '';
497
+ else if (isset($option_formats[$key]) && 0 == $_POST[$key] && 'int' == $option_formats[$key])
498
+ $option = 0;
499
+ else if (isset($option_formats[$key]) && empty($_POST[$key]) && 'int' == $option_formats[$key])
500
+ $option = $this->options_default[$key];
501
+ else if (!empty($_POST[$key]))
502
+ $option = trim(stripslashes($_POST[$key]));
503
+ else
504
+ $option = $this->options_default[$key];
505
+ }
506
+ }
507
+ update_option($page, $options);
508
+ // [WPMS Compatible]
509
+ if (!$this->is_normal_admin())
510
+ update_site_option($page, $options);
511
+ }
512
+
513
+ // [WPMS Compatible]
514
+ if ($this->is_normal_admin())
515
+ {
516
+ switch ($page)
517
+ {
518
+ case BWP_GXS_OPTION_GENERATOR:
519
+ $bwp_option_page->kill_html_fields($form, array(4,10,11,12,13,14,15,16,17,18));
520
+ break;
521
+
522
+ case BWP_GXS_STATS:
523
+ $bwp_option_page->kill_html_fields($form, array(3,4,5,6,7,8));
524
+ add_filter('bwp_option_submit_button', create_function('', 'return "";'));
525
+ break;
526
+ }
527
+ }
528
+
529
+ if (!@file_exists($this->options['input_cache_dir']) || !@is_writable($this->options['input_cache_dir']))
530
+ $this->add_notice('<strong>' . __('Warning') . ':</strong> ' . __("Cache directory does not exist or is not writable. Please read more about directory permission <a href='http://www.zzee.com/solutions/unix-permissions.shtml'>here</a> (Unix).", 'bwp-simple-gxs'));
531
+
532
+ // Assign the form and option array
533
+ $bwp_option_page->init($form, $options, $this->form_tabs);
534
+
535
+ // Build the option page
536
+ echo $bwp_option_page->generate_html_form();
537
+ }
538
+
539
+ function flush_cache()
540
+ {
541
+ $dir = trailingslashit($this->options['input_cache_dir']);
542
+ $deleted = 0;
543
+ if (is_dir($dir))
544
+ {
545
+ if ($dh = opendir($dir))
546
+ {
547
+ while (($file = readdir($dh)) !== false)
548
+ {
549
+ if (preg_match('/^gxs_[a-z0-9]+\.(xml|xml\.gz)$/i', $file))
550
+ {
551
+ @unlink($dir . $file);
552
+ $deleted++;
553
+ }
554
+ }
555
+ closedir($dh);
556
+ }
557
+ }
558
+ return $deleted;
559
+ }
560
+
561
+ function get_options()
562
+ {
563
+ return $this->options;
564
+ }
565
+
566
+ function get_current_time()
567
+ {
568
+ return current_time('timestamp');
569
+ }
570
+
571
+ function format_header_time($time)
572
+ {
573
+ return gmdate('D, d M Y H:i:s \G\M\T', (int) $time);
574
+ }
575
+
576
+ function uni_path_sep($path = '')
577
+ {
578
+ return str_replace('\\', '/', $path);
579
+ }
580
+
581
+ function commit_logs()
582
+ {
583
+ update_option(BWP_GXS_LOG, $this->logs);
584
+ }
585
+
586
+ function do_log($message, $error = true, $sitemap = false)
587
+ {
588
+ $time = $this->get_current_time();
589
+ $debug = ('yes' == $this->options['enable_debug']) ? __('(Debug is on)', 'bwp-simple-gxs') : '';
590
+ if (!$sitemap && 'yes' == $this->options['enable_log'] && !empty($message))
591
+ $this->logs['log'][] = array('log' => $message . ' ' . $debug, 'time' => $time, 'error' => $error);
592
+ else if (!is_bool($sitemap))
593
+ $this->logs['sitemap'][$sitemap] = array('time' => $time, 'url' => $sitemap);
594
+ }
595
+
596
+ function elog($message, $die = false, $errorCode = 503)
597
+ {
598
+ $this->do_log($message);
599
+ if (true == $die && true == $this->debug)
600
+ {
601
+ $this->commit_logs();
602
+ wp_die(__('<strong>BWP Google XML Sitemaps Error:</strong> ', 'bwp-simple-gxs') . $message, __('BWP Google XML Sitemaps Error', 'bwp-simple-gxs'), array('response' => $errorCode));
603
+ }
604
+ }
605
+
606
+ function slog($message)
607
+ {
608
+ $this->do_log($message, false);
609
+ }
610
+
611
+ function nlog($message)
612
+ {
613
+ $this->do_log($message, 'notice');
614
+ }
615
+
616
+ function smlog($url)
617
+ {
618
+ $this->do_log('', false, $url);
619
+ }
620
+
621
+ function get_logs($sitemap = false)
622
+ {
623
+ $logs = (!$sitemap) ? $this->logs['log'] : $this->logs['sitemap'];
624
+ if (!$logs || !is_array($logs) || 0 == sizeof($logs))
625
+ return ($sitemap) ? sprintf(__('Nothing here... yet! Try submitting your <a href="%s">sitemapindex</a> first!', 'bwp-simple-gxs'), $this->options['input_sitemap_url']) : __('No log yet!', 'bwp-simple-gxs');
626
+ if (!$sitemap)
627
+ krsort($logs);
628
+ else
629
+ {
630
+ $log_time = array();
631
+ foreach ($logs as $key => $row)
632
+ $log_time[$key] = $row['time'];
633
+ array_multisort($log_time, SORT_DESC, $logs);
634
+ }
635
+ $log_str = (!$sitemap) ? '<li class="clear" style="margin-top: 5px; line-height: 1.7;"><span style="float: left; margin-right: 5px;">%s &mdash;</span> <span style="color: #%s;">' . __('%s', 'bwp-simple-gxs') . '</span></li>' : '<span style="margin-top: 5px; display: inline-block;">' . __('<a href="%s" target="_blank">%s</a> has been successfully built on <strong>%s</strong>.', 'bwp-simple-gxs') . '</span><br />';
636
+ $output = '<ul class="bwp-gxs-log">' . "\n";
637
+ foreach ($logs as $log)
638
+ {
639
+ if (isset($log['error']))
640
+ {
641
+ $color = (!is_bool($log['error']) && 'notice' == $log['error']) ? '999999' : '';
642
+ if ('' == $color)
643
+ $color = (!$log['error']) ? '009900' : 'FF0000';
644
+ /* translators: date format, see http://php.net/date */
645
+ $output .= sprintf($log_str, date(__('M j, Y : H:i:s', 'bwp-simple-gxs'), $log['time']), $color, $log['log']) . "\n";
646
+ }
647
+ else
648
+ $output .= sprintf($log_str, sprintf($this->options['input_sitemap_struct'], $log['url']), $log['url'], date(__('M j, Y : H:i:s', 'bwp-simple-gxs'), $log['time'])) . "\n";
649
+ }
650
+
651
+ return $output . '</ul>' . "\n";
652
+ }
653
+
654
+ function format_label($label)
655
+ {
656
+ return str_replace(' ', '_', strtolower($label));
657
+ }
658
+
659
+ function do_robots($output, $public)
660
+ {
661
+ global $blog_id;
662
+ if ('0' == $public)
663
+ return $output;
664
+ if ((defined('SUBDOMAIN_INSTALL') && true == SUBDOMAIN_INSTALL) || (isset($blog_id) && 1 == $blog_id))
665
+ {
666
+ $output .= "\n";
667
+ $output .= 'Sitemap: ' . $this->options['input_sitemap_url'];
668
+ $output .= "\n";
669
+ }
670
+ return $output;
671
+ }
672
+
673
+ /**
674
+ * Redirect to correct domain
675
+ *
676
+ * This plugin generates sitemaps dynamically and exits before WordPress does any canonical redirection.
677
+ * This function makes sure non-www domain is redirected and vice versa.
678
+ * @since 1.0.1
679
+ */
680
+ function canonical_redirect($xml_slug)
681
+ {
682
+ $requested_url = is_ssl() ? 'https://' : 'http://';
683
+ $requested_url .= $_SERVER['HTTP_HOST'];
684
+ $requested_url .= $_SERVER['REQUEST_URI'];
685
+ $original = @parse_url($requested_url);
686
+ if (false === $original)
687
+ return;
688
+ // www.example.com vs example.com
689
+ $user_home = @parse_url(home_url());
690
+ if (!empty($user_home['host']))
691
+ $host = $user_home['host'];
692
+ if (strtolower($original['host']) == strtolower($host) ||
693
+ (strtolower($original['host']) != 'www.' . strtolower($host) && 'www.' . strtolower($original['host']) != strtolower($host)))
694
+ $host = $original['host'];
695
+ else
696
+ {
697
+ $xml_slug = ('post' == $xml_slug) ? $xml_slug = 'posts' : $xml_slug;
698
+ $xml_slug = ('page' == $xml_slug) ? $xml_slug = 'pages' : $xml_slug;
699
+ wp_redirect(sprintf($this->options['input_sitemap_struct'], $xml_slug), 301);
700
+ exit;
701
+ }
702
+ }
703
+
704
+ /**
705
+ * A convenient function to add wanted modules or sub modules
706
+ *
707
+ * When you filter the 'bwp_gxs_modules' hook it is recommended that you use this function.
708
+ */
709
+ function add_module($module = '', $sub_module = '')
710
+ {
711
+ if (empty($module))
712
+ return false;
713
+ // Make sure the names are well-formed
714
+ $module = preg_replace('/[^a-z0-9-_\s]/ui', '', $module);
715
+ $module = trim(str_replace(' ', '_', $module));
716
+ $sub_module = preg_replace('/[^a-z0-9-_\s]/ui', '', $sub_module);
717
+ $sub_module = trim(str_replace(' ', '_', $sub_module));
718
+ if (empty($sub_module))
719
+ $this->allowed_modules[$module] = array();
720
+ if (!isset($this->allowed_modules[$module]) || !is_array($this->allowed_modules[$module]))
721
+ $this->allowed_modules[$module] = array($sub_module);
722
+ else if (!in_array($sub_module, $this->allowed_modules[$module]))
723
+ $this->allowed_modules[$module][] = $sub_module;
724
+ }
725
+
726
+ /**
727
+ * A convenient function to remove unwanted modules or sub modules
728
+ *
729
+ * When you filter the 'bwp_gxs_modules' hook it is recommended that you use this function.
730
+ */
731
+ function remove_module($module = '', $sub_module = '')
732
+ {
733
+ if (empty($module) || !isset($this->allowed_modules[$module]))
734
+ return false;
735
+ if (empty($sub_module))
736
+ unset($this->allowed_modules[$module]);
737
+ else
738
+ {
739
+ $module = trim($module);
740
+ $sub_module = trim($sub_module);
741
+ $temp = $this->allowed_modules[$module];
742
+ foreach ($temp as $key => $subm)
743
+ if ($sub_module == $subm)
744
+ {
745
+ unset($this->allowed_modules[$module][$key]);
746
+ return false;
747
+ }
748
+ }
749
+ }
750
+
751
+ function allowed_modules()
752
+ {
753
+ $allowed_modules = array();
754
+ // Add public post types to module list
755
+ $post_types = $this->post_types = get_post_types(array('public' => true), 'objects');
756
+ foreach ($this->post_types as $post_type)
757
+ {
758
+ // Page will have its own
759
+ if ('page' != $post_type->name)
760
+ $allowed_modules['post'][] = $post_type->name;
761
+ }
762
+ // Add pages to module list
763
+ if ('yes' == $this->options['enable_sitemap_page'])
764
+ $allowed_modules['page'] = array('page');
765
+ // Add archive pages to module list
766
+ if ('yes' == $this->options['enable_sitemap_date'])
767
+ $allowed_modules['archive'] = array('monthly', 'yearly');
768
+ // Add taxonomies to module list
769
+ $this->taxonomies = get_taxonomies(array('public' => true), '');
770
+ if ('yes' == $this->options['enable_sitemap_taxonomy'])
771
+ {
772
+ foreach ($this->taxonomies as $taxonomy)
773
+ $allowed_modules['taxonomy'][] = $taxonomy->name;
774
+ $this->terms = get_terms($allowed_modules['taxonomy'], array('hierarchical' => false));
775
+ // Save this for future versions
776
+ /*foreach ($this->terms as $term)
777
+ $allowed_modules['term'][] = $term->slug;*/
778
+ }
779
+ // Our global module list
780
+ $this->allowed_modules = $allowed_modules;
781
+ // Remove some unnecessary sitemap
782
+ $this->remove_module('post', 'attachment');
783
+ $this->remove_module('taxonomy', 'post_format');
784
+ $this->remove_module('taxonomy', 'nav_menu');
785
+ // Hook for a custom module list
786
+ do_action('bwp_gxs_modules_built', $this->allowed_modules, $this->post_types, $this->taxonomies, $this->terms);
787
+ return $this->allowed_modules;
788
+ }
789
+
790
+ function build_requested_modules($allowed)
791
+ {
792
+ $this->requested_modules = array();
793
+ foreach ($allowed as $module_name => $module)
794
+ {
795
+ foreach ($module as $sub_module)
796
+ {
797
+ if (isset($this->post_types[$sub_module])) // Module is a post type
798
+ {
799
+ // @since 1.0.4 - do not use label anymore, ugh
800
+ // $label = $this->format_label($this->post_types[$sub_module]->label);
801
+ $label = $this->format_label($this->post_types[$sub_module]->name);
802
+ if ('post' == $sub_module || 'page' == $sub_module || 'attachment' == $sub_module)
803
+ $data = array($label, array('post' => $this->post_types[$sub_module]->name));
804
+ else
805
+ $data = array($module_name . '_' . $label, array('post' => $this->post_types[$sub_module]->name));
806
+ $this->requested_modules[] = $data;
807
+ }
808
+ else if ('yes' == $this->options['enable_sitemap_taxonomy'] && isset($this->taxonomies[$sub_module])) // Module is a taxonomy
809
+ {
810
+ // $label = $this->format_label($this->taxonomies[$sub_module]->label);
811
+ $label = $this->format_label($this->taxonomies[$sub_module]->name);
812
+ $this->requested_modules[] = array($module_name . '_' . $label, array('taxonomy' => $sub_module));
813
+ }
814
+ /*else if ('term' == $module_name) // Module is a term {} */
815
+ else if (!empty($sub_module))
816
+ $this->requested_modules[] = array($module_name . '_' . $sub_module, array('archive' => $sub_module));
817
+ else
818
+ $this->requested_modules[] = array($module_name);
819
+ }
820
+ }
821
+ }
822
+
823
+ function convert_label(&$sub_module, $module)
824
+ {
825
+ if ('taxonomy' == $module)
826
+ {
827
+ foreach ($this->taxonomies as $taxonomy)
828
+ if ($this->format_label($taxonomy->label) == $sub_module)
829
+ $sub_module = $taxonomy->name;
830
+ }
831
+ else if ('post' == $module)
832
+ {
833
+ foreach ($this->post_types as $post_type)
834
+ if ($this->format_label($post_type->label) == $sub_module)
835
+ $sub_module = $post_type->name;
836
+ }
837
+ }
838
+
839
+ function convert_module($module)
840
+ {
841
+ preg_match('/([a-z0-9]+)_([a-z0-9_-]+)$/iu', $module, $matches);
842
+ if (0 == sizeof($matches))
843
+ return false;
844
+ else
845
+ return $matches;
846
+ }
847
+
848
+ function request_sitemap($wpquery)
849
+ {
850
+ // Currently requested module
851
+ if (isset($wpquery->query_vars['gxs_module']))
852
+ {
853
+ $module = $wpquery->query_vars['gxs_module'];
854
+ $sub_module = (isset($wpquery->query_vars['gxs_sub_module'])) ? $wpquery->query_vars['gxs_sub_module'] : '';
855
+ if (!empty($module))
856
+ $this->load_module($module, $sub_module);
857
+ }
858
+ else if (isset($wpquery->query_vars[$this->query_var_non_perma]))
859
+ {
860
+ $module = $wpquery->query_vars[$this->query_var_non_perma];
861
+ $parsed_module = $this->convert_module($module);
862
+ if ($parsed_module && is_array($parsed_module))
863
+ $this->load_module($parsed_module[1], $parsed_module[2]);
864
+ else
865
+ $this->load_module($module, '');
866
+ }
867
+ }
868
+
869
+ function load_module($module, $sub_module)
870
+ {
871
+ // Assuming we fail, ugh!
872
+ $success = false;
873
+ // Remember to use $wpdb->prepare or $wpdb->escape when developing module
874
+ $module = stripslashes($module);
875
+ $sub_module = stripslashes($sub_module);
876
+ $true_sub_module = $sub_module;
877
+ $pre_module = $module;
878
+ $pre_module .= (!empty($sub_module)) ? '_' . $sub_module : '';
879
+ // @since 1.0.1 - Redirect to correct domain, with or without www
880
+ $this->canonical_redirect($pre_module);
881
+ // Begin building module key
882
+ /*if (!get_option('permalink_structure') && ('post' == $module || 'page' == $module) && empty($sub_module)) $module = '';
883
+ $module = ('pages' == $module) ? 'page' : $module;
884
+ $module = ('posts' == $module) ? 'post' : $module;*/
885
+ // Allowed modules
886
+ $allowed_modules = $this->allowed_modules();
887
+ $this->build_requested_modules($allowed_modules);
888
+ // $this->convert_label($sub_module, $module);
889
+ if ('sitemapindex' != $module && isset($allowed_modules[$module]))
890
+ {
891
+ if (!empty($sub_module))
892
+ {
893
+ if (in_array($sub_module, $allowed_modules[$module]))
894
+ $module_key = $module . '_' . $sub_module;
895
+ else
896
+ $module_key = '';
897
+ }
898
+ else
899
+ $module_key = $module;
900
+ $module_name = str_replace($sub_module, $true_sub_module, $module_key);
901
+ /*$module_name = ('page' == $module && empty($sub_module)) ? 'pages' : $module_name;
902
+ $module_name = ('post' == $module && empty($sub_module)) ? 'posts' : $module_name;*/
903
+ }
904
+ else if ('sitemapindex' == $module)
905
+ {
906
+ $module_key = 'sitemapindex';
907
+ $module_name = 'sitemapindex';
908
+ }
909
+
910
+ if (empty($module_key))
911
+ {
912
+ $this->elog(sprintf(__('Requested module (<em>%s</em>) not found or not allowed.', 'bwp-simple-gxs'), $pre_module), true, 404);
913
+ $this->commit_logs();
914
+ // If debugging is not enabled, redirect to homepage
915
+ wp_redirect(get_option('home'));
916
+ exit;
917
+ }
918
+
919
+ // @since 1.0.1 - Start counting correct build time and queries
920
+ timer_start();
921
+ $this->build_stats['query'] = get_num_queries();
922
+
923
+ // If cache is enabled, we check the cache first
924
+ if ('yes' == $this->options['enable_cache'])
925
+ {
926
+ require_once(dirname(__FILE__) . '/class-bwp-gxs-cache.php');
927
+ $bwp_gxs_cache = new BWP_GXS_CACHE(array('module' => $module_key, 'module_name' => $module_name));
928
+ // If cache is ok, output the cached sitemap, only if debug is off
929
+ if ('yes' != $this->options['enable_debug'] && true == $bwp_gxs_cache->has_cache)
930
+ {
931
+ $this->send_header($bwp_gxs_cache->get_header());
932
+ $file = $bwp_gxs_cache->get_cache_file();
933
+ // decompress the gz file if the server or script is already gzipping
934
+ // this is to avoid double compression
935
+ if ($this->is_gzipped())
936
+ readgzfile($file);
937
+ else
938
+ readfile($file);
939
+ $this->slog(sprintf(__('Successfully served a cached version of <em>%s.xml</em>.', 'bwp-simple-gxs'), $module_name), true);
940
+ $this->commit_logs();
941
+ exit;
942
+ }
943
+ }
944
+
945
+ // If the user uses a custom module dir, also check that dir for usable module files
946
+ $custom_module_dir = (!empty($this->options['input_alt_module_dir']) && $this->options_default['input_alt_module_dir'] != $this->options['input_alt_module_dir']) ? trailingslashit($this->options['input_alt_module_dir']) : false;
947
+ $custom_module_dir = trailingslashit(apply_filters('bwp_gxs_module_dir', $custom_module_dir));
948
+ // Begin loading modules
949
+ require_once(dirname(__FILE__) . '/class-bwp-gxs-module.php');
950
+ if ('sitemapindex' != $module && isset($allowed_modules[$module]))
951
+ {
952
+ $sub_loaded = $mapped_sub_loaded = false;
953
+ if (!empty($sub_module) && in_array($sub_module, $allowed_modules[$module]))
954
+ {
955
+ // Try to load the mapped sub-module first
956
+ if (!empty($this->module_map[$sub_module]))
957
+ {
958
+ $module_file = $module . '_' . $this->module_map[$sub_module] . '.php';
959
+ $path_custom = ($custom_module_dir) ? $this->uni_path_sep($custom_module_dir . $module_file) : '';
960
+ $path = $this->uni_path_sep($this->module_directory . $module_file);
961
+ if (!empty($path_custom) && @file_exists($path_custom))
962
+ {
963
+ $module_key = $module . '_' . $this->module_map[$sub_module];
964
+ include_once($path_custom);
965
+ $mapped_sub_loaded = true;
966
+ $this->nlog(sprintf(__('Loaded a custom sub-module file: <strong>%s</strong>.', 'bwp-simple-gxs'), $module_file));
967
+ }
968
+ else if (@file_exists($path))
969
+ {
970
+ $module_key = $module . '_' . $this->module_map[$sub_module];
971
+ include_once($path);
972
+ $mapped_sub_loaded = true;
973
+ }
974
+ else // Don't fire a wp_die
975
+ $this->nlog(sprintf(__('Mapped sub-module file: <strong>%s</strong> is not available in both default and custom module directory. The plugin will now try loading the requested sub-module instead.', 'bwp-simple-gxs'), $module_file));
976
+ }
977
+ if (false == $mapped_sub_loaded)
978
+ {
979
+ $module_file = $module . '_' . $sub_module . '.php';
980
+ $path_custom = ($custom_module_dir) ? $this->uni_path_sep($custom_module_dir . $module_file) : '';
981
+ $path = $this->uni_path_sep($this->module_directory . $module_file);
982
+ if (!empty($path_custom) && @file_exists($path_custom))
983
+ {
984
+ include_once($path_custom);
985
+ $sub_loaded = true;
986
+ $this->nlog(sprintf(__('Loaded a custom sub-module file: <strong>%s</strong>.', 'bwp-simple-gxs'), $module_file));
987
+ }
988
+ else if (@file_exists($path))
989
+ {
990
+ include_once($path);
991
+ $sub_loaded = true;
992
+ }
993
+ else // Don't fire a wp_die
994
+ $this->nlog(sprintf(__('Sub-module file: <strong>%s</strong> is not available in both default and custom module directory. The plugin will now try loading the parent module instead.', 'bwp-simple-gxs'), $module_file));
995
+ }
996
+ }
997
+ if (false == $sub_loaded && false == $mapped_sub_loaded)
998
+ {
999
+ // Try loading the module
1000
+ $module_file = $module . '.php';
1001
+ $module_key = $module;
1002
+ $path_custom = ($custom_module_dir) ? $this->uni_path_sep($custom_module_dir . $module_file) : '';
1003
+ $path = $this->uni_path_sep($this->module_directory . $module_file);
1004
+ if (!empty($path_custom) && @file_exists($path_custom))
1005
+ {
1006
+ include_once($path_custom);
1007
+ $this->nlog(sprintf(__('Loaded a custom module file: <strong>%s</strong>.', 'bwp-simple-gxs'), $module_file));
1008
+ }
1009
+ else if (@file_exists($path))
1010
+ include_once($path);
1011
+ else
1012
+ {
1013
+ $error_log = sprintf(__('Could not load module file: <strong>%s</strong> in both default and custom module directory. Please recheck if that module file exists.', 'bwp-simple-gxs'), $module_file);
1014
+ $this->elog($error_log, true);
1015
+ }
1016
+ }
1017
+
1018
+ $this->module_data = array('module' => $module, 'sub_module' => $sub_module, 'module_key' => $module_key, 'module_name' => $module_name);
1019
+
1020
+ if (class_exists('BWP_GXS_MODULE_' . $module_key))
1021
+ {
1022
+ $class_name = 'BWP_GXS_MODULE_' . $module_key;
1023
+ $the_module = new $class_name();
1024
+ if ('url' == $the_module->type)
1025
+ $success = $this->generate_sitemap($the_module->data);
1026
+ else
1027
+ $success = $this->generate_sitemap_index($the_module->data);
1028
+ unset($the_module);
1029
+ }
1030
+ else
1031
+ $this->elog(sprintf(__('There is no class named <strong>%s</strong> in the module file <strong>%s</strong>.', 'bwp-simple-gxs'), 'BWP_GXS_MODULE_' . strtoupper($module_key), $module_file), true);
1032
+ }
1033
+ else if ('sitemapindex' == $module)
1034
+ {
1035
+ $module_file = 'sitemapindex.php';
1036
+ $path_custom = ($custom_module_dir) ? $this->uni_path_sep($custom_module_dir . $module_file) : '';
1037
+ if (!empty($path_custom) && @file_exists($path_custom))
1038
+ {
1039
+ include_once($path_custom);
1040
+ $this->nlog(sprintf(__('Loaded a custom sitemapindex module file: <strong>%s</strong>.', 'bwp-simple-gxs'), $module_file));
1041
+ }
1042
+ else
1043
+ include_once(dirname(__FILE__) . '/modules/sitemapindex.php');
1044
+ if (class_exists('BWP_GXS_MODULE_INDEX'))
1045
+ {
1046
+ $the_module = new BWP_GXS_MODULE_INDEX($this->requested_modules);
1047
+ $success = $this->generate_sitemap_index($the_module->data);
1048
+ unset($the_module);
1049
+ }
1050
+ }
1051
+
1052
+ // Output succeeded
1053
+ if (true == $success)
1054
+ {
1055
+ if ('yes' == $this->options['enable_cache'] && true == $bwp_gxs_cache->cache_ok)
1056
+ // Now cache the sitemap if we have to
1057
+ $bwp_gxs_cache->write_cache();
1058
+ // Output the requested sitemap
1059
+ $this->output_sitemap();
1060
+ $this->slog(sprintf(__('Successfully generated <em>%s.xml</em> using module <em>%s</em>.', 'bwp-simple-gxs'), $module_name, $module_file), true);
1061
+ $this->smlog($module_name);
1062
+ $this->commit_logs();
1063
+ exit;
1064
+ }
1065
+ else
1066
+ $this->commit_logs();
1067
+ }
1068
+
1069
+ function send_header($header = array())
1070
+ {
1071
+ if (!empty($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache/2'))
1072
+ header ('Cache-Control: no-cache, pre-check=0, post-check=0, max-age=0');
1073
+ else
1074
+ header ('Cache-Control: private, pre-check=0, post-check=0, max-age=0');
1075
+
1076
+ $content_types = array('google' => 'text/xml', 'yahoo' => 'text/plain');
1077
+
1078
+ $time = time();
1079
+ $expires = $this->format_header_time($time + $this->cache_time);
1080
+
1081
+ $default_headers = array(
1082
+ 'lastmod' => $this->format_header_time($time),
1083
+ 'expires' => $expires,
1084
+ 'etag' => ''
1085
+ );
1086
+
1087
+ $header = wp_parse_args($header, $default_headers);
1088
+
1089
+ header('Expires: ' . $header['expires']);
1090
+ header('Last-Modified: ' . $header['lastmod']);
1091
+ if (!empty($header['etag']))
1092
+ header('Etag: ' . $header['etag']);
1093
+ header('Accept-Ranges: bytes');
1094
+ header('Content-Type: ' . $content_types['google'] . '; charset=UTF-8');
1095
+ if ('yes' == $this->options['enable_gzip'])
1096
+ header('Content-Encoding: ' . $this->check_gzip_type());
1097
+
1098
+ return;
1099
+ }
1100
+
1101
+ function is_gzipped()
1102
+ {
1103
+ if (ini_get('zlib.output_compression') || ini_get('output_handler') == 'ob_gzhandler' || in_array('ob_gzhandler', ob_list_handlers()))
1104
+ return true;
1105
+ }
1106
+
1107
+ function init_gzip()
1108
+ {
1109
+ if (!$this->check_gzip() && 'yes' == $this->options['enable_gzip'])
1110
+ $this->options['enable_gzip'] = 'no';
1111
+ return;
1112
+ }
1113
+
1114
+ function check_gzip()
1115
+ {
1116
+ if (headers_sent())
1117
+ return false;
1118
+
1119
+ if (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && ((strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false)
1120
+ || strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false))
1121
+ return true;
1122
+ else
1123
+ return false;
1124
+ }
1125
+
1126
+ function check_gzip_type()
1127
+ {
1128
+ if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false)
1129
+ return 'gzip';
1130
+ else if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false)
1131
+ return 'x-gzip';
1132
+
1133
+ return 'gzip';
1134
+ }
1135
+
1136
+ function ping()
1137
+ {
1138
+ $time = time();
1139
+ $ping_data = get_option(BWP_GXS_PING);
1140
+ if (!$ping_data || !is_array($ping_data))
1141
+ $ping_data = array(
1142
+ 'data_pinged' => array('google' => 0, 'yahoo' => 0, 'bing' => 0, 'ask' => 0),
1143
+ 'data_last_pinged' => array('google' => 0, 'yahoo' => 0, 'bing' => 0, 'ask' => 0)
1144
+ );
1145
+ foreach ($this->options['input_ping'] as $key => $service)
1146
+ {
1147
+ if ('yes' == $this->options['enable_ping_' . $key])
1148
+ {
1149
+ // A day has gone, reset the count
1150
+ if ($time - $ping_data['data_last_pinged'][$key] > 86400)
1151
+ {
1152
+ $ping_data['data_pinged'][$key] = 0;
1153
+ $ping_data['data_last_pinged'][$key] = $time;
1154
+ }
1155
+ // Ping limit has not been reached
1156
+ if ($this->ping_per_day > $ping_data['data_pinged'][$key])
1157
+ {
1158
+ $ping_data['data_pinged'][$key]++;
1159
+ $url = sprintf($service, urlencode(str_replace('&', '&amp;', $this->options['input_sitemap_url'])));
1160
+ $response = wp_remote_post($url, array('timeout' => $this->timeout));
1161
+ if (is_wp_error($response))
1162
+ {
1163
+ $errno = $response->get_error_code();
1164
+ $errorstr = $response->get_error_message();
1165
+ $this->elog($errorstr);
1166
+ $this->commit_logs();
1167
+ }
1168
+ else
1169
+ {
1170
+ $this->slog(sprintf(__('Pinged %s successfully!', 'bwp-simple-gxs'), ucfirst($key)));
1171
+ $this->commit_logs();
1172
+ }
1173
+ }
1174
+ else
1175
+ {
1176
+ $this->elog(sprintf(__('Ping limit for today to %s has been reached, sorry!', 'bwp-simple-gxs'), ucfirst($key)));
1177
+ $this->commit_logs();
1178
+ }
1179
+ }
1180
+ }
1181
+ update_option(BWP_GXS_PING, $ping_data);
1182
+ }
1183
+
1184
+ function output_sitemap()
1185
+ {
1186
+ if ('yes' == $this->options['enable_gzip'])
1187
+ {
1188
+ $this->output = (!$this->is_gzipped()) ? gzencode($this->output, 6) : $this->output;
1189
+ $this->send_header();
1190
+ echo $this->output;
1191
+ }
1192
+ else
1193
+ {
1194
+ $this->send_header();
1195
+ echo $this->output;
1196
+ }
1197
+ }
1198
+
1199
+ function check_output($output)
1200
+ {
1201
+ // If output is empty we log it so the user knows what's going on, but let the page load normally
1202
+ if (empty($output) || 0 == sizeof($output))
1203
+ {
1204
+ $this->elog(sprintf(__('<em>%s.xml</em> does not have any item. The plugin has fired a 404 header to the search engine that requests it. You should check the module that generates that sitemap (<em>%s.php</em>).', 'bwp-simple-gxs'), $this->module_data['module_name'], $this->module_data['module_key']), true, 404);
1205
+ return false;
1206
+ }
1207
+ else
1208
+ return true;
1209
+ }
1210
+
1211
+ function sitemap_stats($output = array(), $type = '')
1212
+ {
1213
+ $time = timer_stop(0, 3);
1214
+ $sql = get_num_queries() - $this->build_stats['query'];
1215
+ $memory = size_format(memory_get_usage() - $this->build_stats['mem'], 2);
1216
+ if (empty($type))
1217
+ $this->output .= "\n" . sprintf($this->templates['stats'], $time, $memory, $sql, sizeof($output));
1218
+ else
1219
+ echo "\n" . sprintf($this->templates['stats_cached'], $time, $memory, $sql);
1220
+ }
1221
+
1222
+ function generate_url_item($url = '', $priority = 1.0, $freq = 'always', $lastmod = 0)
1223
+ {
1224
+ $freq = sprintf($this->templates['changefreq'], $freq);
1225
+ $priority = str_replace(',', '.', sprintf($this->templates['priority'], $priority));
1226
+ $lastmod = (!empty($lastmod)) ? sprintf($this->templates['lastmod'], $lastmod) : '';
1227
+ if (!empty($url))
1228
+ return sprintf($this->templates['url'], $url, $lastmod, $freq, $priority);
1229
+ else
1230
+ return '';
1231
+ }
1232
+
1233
+ function generate_sitemap_item($url = '', $lastmod = 0)
1234
+ {
1235
+ $lastmod = (!empty($lastmod)) ? sprintf($this->templates['lastmod'], $lastmod) : '';
1236
+ if (!empty($url))
1237
+ return sprintf($this->templates['sitemap'], $url, $lastmod);
1238
+ else
1239
+ return '';
1240
+ }
1241
+
1242
+ function credit()
1243
+ {
1244
+ $xml = '<!-- Generated by BWP Google XML Sitemaps ' . $this->get_version() . ' (c) 2011 Khang Minh - betterwp.net' . "\n";
1245
+ $xml .=' Plugin homepage: ' . $this->plugin_url . ' -->' . "\n";
1246
+ return $xml;
1247
+ }
1248
+
1249
+ function generate_sitemap($output = array())
1250
+ {
1251
+ $xml = '<' . '?xml version="1.0" encoding="UTF-8"?'.'>' . "\n";
1252
+ $xml .= (!empty($this->xslt)) ? '<?xml-stylesheet type="text/xsl" href="' . $this->xslt . '"?>' . "\n\n" : '';
1253
+ $xml .= '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n\t" . 'xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9' . "\n\t" . 'http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"' . "\n\t" . 'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
1254
+ if ('yes' != $this->options['enable_xslt'] && 'yes' == $this->options['enable_credit'])
1255
+ $xml .= $this->credit();
1256
+
1257
+ if (!$this->check_output($output))
1258
+ return false;
1259
+
1260
+ foreach ($output as $url)
1261
+ {
1262
+ $url['location'] = (!empty($url['location'])) ? $url['location'] : '';
1263
+ $url['lastmod'] = (!empty($url['lastmod'])) ? $url['lastmod'] : '';
1264
+ $url['freq'] = in_array($url['freq'], $this->frequency) ? $url['freq'] : $this->options['select_default_freq'];
1265
+ $url['priority'] = ($url['priority'] <= 1 && $url['priority'] > 0) ? $url['priority'] : $this->options['select_default_pri'];
1266
+ $xml .= $this->generate_url_item(htmlspecialchars($url['location']), $url['priority'], $url['freq'], $url['lastmod']);
1267
+ unset($url);
1268
+ }
1269
+
1270
+ $xml .= "\n" . '</urlset>';
1271
+ $this->output = $xml;
1272
+
1273
+ if ('yes' == $this->options['enable_stats'])
1274
+ $this->sitemap_stats($output);
1275
+
1276
+ return true;
1277
+ }
1278
+
1279
+ function generate_sitemap_index($output = array())
1280
+ {
1281
+ $xml = '<' . '?xml version="1.0" encoding="UTF-8"?'.'>' . "\n";
1282
+ $xml .= (!empty($this->xslt_index)) ? '<?xml-stylesheet type="text/xsl" href="' . $this->xslt_index . '"?>' . "\n\n" : '';
1283
+ $xml .= '<sitemapindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n\t" . 'xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9' . "\n\t" . 'http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd"' . "\n\t" . 'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
1284
+ if ('yes' != $this->options['enable_xslt'] && 'yes' == $this->options['enable_credit'])
1285
+ $xml .= $this->credit();
1286
+
1287
+ if (!$this->check_output($output))
1288
+ return false;
1289
+
1290
+ foreach ($output as $sitemap)
1291
+ {
1292
+ $sitemap['location'] = (!empty($sitemap['location'])) ? $sitemap['location'] : '';
1293
+ $sitemap['lastmod'] = (!empty($sitemap['lastmod'])) ? $sitemap['lastmod'] : '';
1294
+ $xml .= $this->generate_sitemap_item(htmlspecialchars($sitemap['location']), $sitemap['lastmod']);
1295
+ unset($sitemap);
1296
+ }
1297
+
1298
+ $xml .= "\n" . '</sitemapindex>';
1299
+ $this->output = $xml;
1300
+
1301
+ if ('yes' == $this->options['enable_stats'])
1302
+ $this->sitemap_stats($output);
1303
+
1304
+ return true;
1305
+ }
1306
+ }
1307
+ ?>
includes/modules/archive.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE
5
+ */
6
+
7
+ class BWP_GXS_MODULE_ARCHIVE extends BWP_GXS_MODULE {
8
+
9
+ function __construct()
10
+ {
11
+ $this->set_current_time();
12
+ $this->build_data();
13
+ }
14
+
15
+ function build_data()
16
+ {
17
+ global $wpdb, $bwp_gxs;
18
+
19
+ // There's no easy way getting the date archive
20
+ // We will just call wp_get_archives and get the cache it creates
21
+ $requested = $bwp_gxs->module_data['sub_module'];
22
+ wp_get_archives(array('echo' => 0, 'type' => $requested));
23
+ $archives = current(wp_cache_get('wp_get_archives' , 'general'));
24
+
25
+ $top_date = $archives[0]->year . '-12-31 12:00:00';
26
+ $bottom_date = $archives[count($archives)-1]->year . '-01-01 00:00:00';
27
+ $latest_post_query = '
28
+ SELECT * FROM ' . $wpdb->posts . "
29
+ WHERE post_status = 'publish' AND post_type <> 'page'
30
+ AND post_modified >= '$bottom_date' AND post_modified <= '$top_date'" . '
31
+ ORDER BY post_modified DESC';
32
+ $latest_posts = $wpdb->get_results($latest_post_query);
33
+
34
+ if ('monthly' == $requested)
35
+ {
36
+ foreach ($archives as $archive)
37
+ {
38
+ $data = array();
39
+ $data['location'] = get_month_link($archive->year, $archive->month);
40
+ foreach ($latest_posts as $post)
41
+ {
42
+ if ($archive->month == (int) date('n', strtotime($post->post_modified)))
43
+ {
44
+ $data['lastmod'] = $this->format_lastmod(strtotime($post->post_modified));
45
+ $data['freq'] = $this->cal_frequency($post);
46
+ $data['priority'] = $this->cal_priority($post, $data['freq']);
47
+ break;
48
+ }
49
+ }
50
+ $this->data[] = $data;
51
+ }
52
+ }
53
+ else if ('yearly' == $requested)
54
+ {
55
+ foreach ($archives as $archive)
56
+ {
57
+ $data = array();
58
+ $data['location'] = get_year_link($archive->year);
59
+ foreach ($latest_posts as $post)
60
+ {
61
+ if ($archive->year == (int) date('Y', strtotime($post->post_modified)))
62
+ {
63
+ $data['lastmod'] = $this->format_lastmod(strtotime($post->post_modified));
64
+ $data['freq'] = $this->cal_frequency($post);
65
+ $data['priority'] = $this->cal_priority($post, $data['freq']);
66
+ break;
67
+ }
68
+ }
69
+ $this->data[] = $data;
70
+ }
71
+ }
72
+ }
73
+ }
74
+ ?>
includes/modules/page.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE
5
+ */
6
+
7
+ class BWP_GXS_MODULE_PAGE extends BWP_GXS_MODULE {
8
+
9
+ function __construct()
10
+ {
11
+ $this->set_current_time();
12
+ $this->build_data();
13
+ }
14
+
15
+ function generate_data()
16
+ {
17
+ global $wpdb, $bwp_gxs, $post;
18
+
19
+ $latest_post_query = '
20
+ SELECT * FROM ' . $wpdb->posts . "
21
+ WHERE post_status = 'publish' AND post_type = 'page'" . '
22
+ ORDER BY post_modified DESC';
23
+
24
+ $latest_posts = $this->get_results($latest_post_query);
25
+
26
+ if (!isset($latest_posts) || 0 == sizeof($latest_posts))
27
+ return false;
28
+
29
+ $data = array();
30
+ foreach ($latest_posts as $item)
31
+ {
32
+ $post = $item;
33
+ $data = $this->init_data($data);
34
+ // Benefit from WP Caching
35
+ wp_cache_add($post->ID, $post, 'posts');
36
+ $data['location'] = get_permalink();
37
+ $data['lastmod'] = $this->format_lastmod(strtotime($post->post_modified));
38
+ $data['freq'] = $this->cal_frequency($post);
39
+ $data['priority'] = $this->cal_priority($post, $data['freq']);
40
+ $this->data[] = $data;
41
+ unset($item);
42
+ }
43
+
44
+ // Some memory saver ;)
45
+ unset($latest_posts);
46
+
47
+ // Always return true if we can get here, otherwise you're stuck at the SQL cycling limit
48
+ return true;
49
+ }
50
+ }
51
+ ?>
includes/modules/post.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE
5
+ *
6
+ * You can take this as a sample module, it is documented rather well ;)
7
+ */
8
+
9
+ class BWP_GXS_MODULE_POST extends BWP_GXS_MODULE {
10
+
11
+ // Declare all properties you need for your modules here
12
+ var $requested;
13
+
14
+ function __construct()
15
+ {
16
+ global $bwp_gxs;
17
+ // Give your properties value here
18
+ // $this->set_current_time() should always be called, it will allow you to use $this->now (the current Unix Timestamp).
19
+ $this->set_current_time();
20
+ // $bwp_gxs->module_data hold four things, but you only need to take note of 'sub_module' and 'module_key'
21
+ // For example when you are browsing to http://example.com/taxonomy_categories.xml
22
+ // $bwp_gxs->module_data['sub_module'] is 'category' (the singular name) and $bwp_gxs->module_data['module_key'] is
23
+ // 'taxonomy_category' (also singular). If you have a custom module for taxonomy_category, you must name your class
24
+ // BWP_GXS_MODULE_TAXONOMY_CATEGORY and save the file as taxonomy_category.php (similar to taxonomy_post_tag.php).
25
+ $this->requested = $bwp_gxs->module_data['sub_module'];
26
+ // Always call this to start building data
27
+ // If you want to make use of SQL cycling (a method to reduce heavy queries), don't use build_data() like other modules.
28
+ // Just call it here and use function generate_data() to build actual data, just like below. Use SQL cycling when
29
+ // you are dealing with post-based sitemaps.
30
+ $this->build_data();
31
+ }
32
+
33
+ /**
34
+ * This is the main function that generates our data.
35
+ *
36
+ * Since we are dealing with heavy queries here, it's better that you use
37
+ * generate_data() which will get called by build_data(). This way you will query for no more than
38
+ * the SQL limit configurable in this plugin's option page.
39
+ * If you happen to use LIMIT in your SQL statement for other reasons then use build_data() instead.
40
+ */
41
+ function generate_data()
42
+ {
43
+ global $wpdb, $bwp_gxs, $post;
44
+
45
+ $requested = $this->requested;
46
+
47
+ // If no custom post type is requested, use the default post type
48
+ if (empty($requested))
49
+ $requested = 'post';
50
+
51
+ // A standard custom query to fetch posts from database, sorted by their lastmod
52
+ // You can use any type of queries for your modules
53
+ $latest_post_query = '
54
+ SELECT * FROM ' . $wpdb->posts . "
55
+ WHERE post_status = 'publish' AND post_type = %s" . '
56
+ ORDER BY post_modified DESC';
57
+ // Use $this->get_results instead of $wpdb->get_results, remember to escape your query
58
+ // using $wpdb->prepare or $wpdb->escape, @see http://codex.wordpress.org/Function_Reference/wpdb_Class
59
+ $latest_posts = $this->get_results($wpdb->prepare($latest_post_query, $requested));
60
+
61
+ // This check helps you stop the cycling sooner
62
+ // It basically means if there is nothing to loop through anymore we return false so the cycling can stop.
63
+ if (!isset($latest_posts) || 0 == sizeof($latest_posts))
64
+ return false;
65
+
66
+ // Always init your $data
67
+ $data = array();
68
+ foreach ($latest_posts as $item)
69
+ {
70
+ $post = $item;
71
+ // Init your $data with the previous item's data. This makes sure no item is mal-formed.
72
+ $data = $this->init_data($data);
73
+ // Make use of WP's cache @see http://betterwp.net/9-latest-posts-from-each-post-type/
74
+ wp_cache_add($post->ID, $post, 'posts');
75
+ $data['location'] = get_permalink();
76
+ $data['lastmod'] = $this->format_lastmod(strtotime($post->post_modified));
77
+ $data['freq'] = $this->cal_frequency($post);
78
+ $data['priority'] = $this->cal_priority($post, $data['freq']);
79
+ $this->data[] = $data;
80
+ unset($item);
81
+ }
82
+
83
+ // Some memory saver ;)
84
+ unset($latest_posts);
85
+
86
+ // Always return true if we can get here, otherwise you're stuck at the SQL cycling limit
87
+ return true;
88
+ }
89
+ }
90
+ ?>
includes/modules/post_most_popular.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE
5
+ *
6
+ * This is a sample custom module
7
+ */
8
+
9
+ class BWP_GXS_MODULE_POST_MOST_POPULAR extends BWP_GXS_MODULE {
10
+
11
+ function __construct()
12
+ {
13
+ // Give your properties value here
14
+ // $this->set_current_time() should always be called, it will allow you to use $this->now (the current Unix Timestamp).
15
+ $this->set_current_time();
16
+ // Always call this to start building data
17
+ // If you want to make use of SQL cycling (a method to reduce heavy queries), don't use build_data() like other modules.
18
+ // Just call it here and use function generate_data() to build actual data, just like below. Use SQL cycling when
19
+ // you are dealing with post-based sitemaps.
20
+ $this->build_data();
21
+ }
22
+
23
+ /**
24
+ * This is the main function that generates our data.
25
+ *
26
+ * Since we are dealing with heavy queries here, it's better that you use
27
+ * generate_data() which will get called by build_data(). This way you will query for no more than
28
+ * the SQL limit configurable in this plugin's option page.
29
+ * If you happen to use LIMIT in your SQL statement for other reasons then use build_data() instead.
30
+ */
31
+ function generate_data()
32
+ {
33
+ global $wpdb, $bwp_gxs, $post;
34
+
35
+ // A query for posts with most comments
36
+ $latest_post_query = '
37
+ SELECT * FROM ' . $wpdb->posts . "
38
+ WHERE post_status = 'publish' AND post_type = 'post' AND comment_count > 2" . '
39
+ ORDER BY comment_count, post_modified DESC';
40
+ // Use $this->get_results instead of $wpdb->get_results, remember to escape your query
41
+ // using $wpdb->prepare or $wpdb->escape, @see http://codex.wordpress.org/Function_Reference/wpdb_Class
42
+ $latest_posts = $this->get_results($latest_post_query);
43
+
44
+ // This check helps you stop the cycling sooner
45
+ // It basically means if there is nothing to loop through anymore we return false so the cycling can stop.
46
+ if (!isset($latest_posts) || 0 == sizeof($latest_posts))
47
+ return false;
48
+
49
+ $data = array();
50
+ foreach ($latest_posts as $item)
51
+ {
52
+ $post = $item;
53
+ $data = $this->init_data($data);
54
+ // Make use of WP's cache
55
+ wp_cache_add($post->ID, $post, 'posts');
56
+ $data['location'] = get_permalink();
57
+ $data['lastmod'] = $this->format_lastmod(strtotime($post->post_modified));
58
+ $data['freq'] = $this->cal_frequency($post);
59
+ $data['priority'] = $this->cal_priority($post, $data['freq']);
60
+ $this->data[] = $data;
61
+ unset($item);
62
+ }
63
+
64
+ // Some memory saver ;)
65
+ unset($latest_posts);
66
+
67
+ // Always return true if we can get here, otherwise you're stuck at the SQL cycling limit
68
+ return true;
69
+ }
70
+ }
71
+ ?>
includes/modules/sitemapindex.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE
5
+ */
6
+
7
+ class BWP_GXS_MODULE_INDEX extends BWP_GXS_MODULE {
8
+
9
+ // Declare all properties you need for your modules here
10
+ var $requested_modules = array();
11
+
12
+ function __construct($requested)
13
+ {
14
+ // Give your properties value here
15
+ $this->set_current_time();
16
+ $this->requested_modules = $requested;
17
+ // Always call this to start building data
18
+ $this->build_data();
19
+ }
20
+
21
+ /**
22
+ * This is the main function that generates our data.
23
+ *
24
+ * If your module deals with heavy queries, for example selecting all posts from the database,
25
+ * you should not use build_data() directly but rather use generate_data(). Open term.php for more details.
26
+ */
27
+ function build_data()
28
+ {
29
+ global $wpdb, $bwp_gxs;
30
+
31
+ // A better limit for sites that have posts with same last modified date - @since 1.0.2
32
+ $limit = sizeof(get_post_types(array('public' => true))) + 1000;
33
+
34
+ $latest_post_query = '
35
+ SELECT *
36
+ FROM
37
+ (
38
+ SELECT post_type, max(post_modified) AS mpmd
39
+ FROM ' . $wpdb->posts . "
40
+ WHERE post_status = 'publish'" . '
41
+ GROUP BY post_type
42
+ ) AS f
43
+ INNER JOIN ' . $wpdb->posts . ' AS s ON s.post_type = f.post_type
44
+ AND s.post_modified = f.mpmd
45
+ LIMIT ' . (int) $limit;
46
+
47
+ $latest_posts = $wpdb->get_results($latest_post_query);
48
+
49
+ // Build a temporary array holding post type and their latest modified date, sorted by post_modified
50
+ foreach ($latest_posts as $a_post)
51
+ {
52
+ $temp_posts[$a_post->post_type] = $this->format_lastmod(strtotime($a_post->post_modified));
53
+ }
54
+ arsort($temp_posts);
55
+ $prime_lastmod = current($temp_posts);
56
+
57
+ $taxonomies = $bwp_gxs->taxonomies;
58
+
59
+ $data = array();
60
+ foreach ($this->requested_modules as $item)
61
+ {
62
+ $data = $this->init_data($data);
63
+ $data['location'] = $this->get_xml_link($item[0]);
64
+ if (isset($item[1]))
65
+ {
66
+ if (isset($item[1]['post']))
67
+ {
68
+ $the_post = $this->get_post_by_post_type($item[1]['post'], $latest_posts);
69
+ if ($the_post)
70
+ $data['lastmod'] = $this->format_lastmod(strtotime($the_post->post_modified));
71
+ }
72
+ else if (isset($item[1]['taxonomy']))
73
+ {
74
+ foreach ($temp_posts as $post_type => $modified_time)
75
+ {
76
+ if ($this->post_type_uses($post_type, $taxonomies[$item[1]['taxonomy']]))
77
+ $data['lastmod'] = $this->format_lastmod(strtotime($modified_time));
78
+ }
79
+ }
80
+ else if (isset($item[1]['archive']))
81
+ $data['lastmod'] = $prime_lastmod;
82
+ }
83
+ // Just in case something went wrong - @since 1.0.2
84
+ if (empty($data['lastmod']))
85
+ $data['lastmod'] = $prime_lastmod;
86
+ // Pass data back to the plugin
87
+ $this->data[] = $data;
88
+ }
89
+ }
90
+ }
91
+ ?>
includes/modules/taxonomy.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
4
+ * @license http://www.gnu.org/licenses/gpl.html GNU GENERAL PUBLIC LICENSE
5
+ * Taxonomy Linear Mode
6
+ */
7
+
8
+ class BWP_GXS_MODULE_TAXONOMY extends BWP_GXS_MODULE {
9
+
10
+ function __construct()
11
+ {
12
+ $this->set_current_time();
13
+ $this->build_data();
14
+ }
15
+
16
+ function build_data()
17
+ {
18
+ global $wpdb, $bwp_gxs;
19
+
20
+ $requested = $bwp_gxs->module_data['sub_module'];
21
+ $the_taxonomy = $bwp_gxs->taxonomies[$requested];
22
+ $object_types = $the_taxonomy->object_type;
23
+ $post_type_in = array();
24
+ foreach ($object_types as $post_type)
25
+ $post_type_in[] = "wpost.post_type = '$post_type'";
26
+ $post_type_in = implode(' OR ', $post_type_in);
27
+
28
+ $latest_post_query = '
29
+ SELECT * FROM ' . $wpdb->term_relationships . ' wprel
30
+ INNER JOIN ' . $wpdb->posts . ' wpost
31
+ ON wprel.object_id = wpost.ID
32
+ INNER JOIN ' . $wpdb->term_taxonomy . ' wptax
33
+ ON wprel.term_taxonomy_id = wptax.term_taxonomy_id' . "
34
+ WHERE wpost.post_status = 'publish' AND wptax.taxonomy = %s" . '
35
+ AND (' . $post_type_in . ')
36
+ ORDER BY wpost.post_modified DESC
37
+ LIMIT 5000'; // 5000, a rough assumption ;)
38
+ $latest_posts = $wpdb->get_results($wpdb->prepare($latest_post_query, $requested));
39
+
40
+ $terms = get_terms($requested, array('hierarchical' => false));
41
+
42
+ $data = array();
43
+ foreach ($terms as $term)
44
+ {
45
+ $count = 1;
46
+ $data = $this->init_data($data);
47
+ while (isset($latest_posts[$count - 1]) && $term->term_id != $latest_posts[$count - 1]->term_id)
48
+ $count++;
49
+ $data['location'] = get_term_link($term, $requested);
50
+ if (isset($latest_posts[$count - 1]))
51
+ {
52
+ $post = $latest_posts[$count - 1];
53
+ $data['lastmod'] = $this->format_lastmod(strtotime($post->post_modified));
54
+ $data['freq'] = $this->cal_frequency($post);
55
+ $data['priority'] = $this->cal_priority($post, $data['freq']);
56
+ }
57
+ $this->data[] = $data;
58
+ }
59
+
60
+ // Sort the data by lastmod
61
+ $this->sort_data_by();
62
+ }
63
+ }
64
+ ?>
languages/bwp-simple-gxs-ms_MY.mo ADDED
Binary file
languages/bwp-simple-gxs-ms_MY.po ADDED
@@ -0,0 +1,487 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: BWP Google XML Sitemaps(Malay Translation)\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2011-04-15 03:56+0700\n"
6
+ "PO-Revision-Date: 2011-04-19 10:00+0700\n"
7
+ "Last-Translator: \n"
8
+ "Language-Team: <darkcry3r@gmail.com>\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=utf-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
13
+ "X-Poedit-Basepath: .\n"
14
+ "X-Poedit-SourceCharset: utf-8\n"
15
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
+ "X-Poedit-Language: Malay\n"
17
+ "X-Poedit-Country: MALAYSIA\n"
18
+ "X-Poedit-SearchPath-0: .\n"
19
+
20
+ #: includes/class-bwp-framework.php:172
21
+ #, php-format
22
+ msgid "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</strong> or higher. The plugin will not function until you update your software. Please deactivate this plugin."
23
+ msgstr "%s memerlukan WordPress <strong>%s</strong> atau yang terbaharu dan PHP <strong>%s</strong> atau yang terbaharu . Plugin ini tidak akan berfungsi sehingga anda menaiktaraf perisian. Sila nyahaktifkan plugin ini."
24
+
25
+ #: includes/class-bwp-framework.php:181
26
+ msgid "log"
27
+ msgstr "log"
28
+
29
+ #: includes/class-bwp-framework.php:186
30
+ msgid "You can buy me some coffees if you appreciate my work, thank you!"
31
+ msgstr "Anda boleh menderma jika anda hargai kerja saya, terima kasih!"
32
+
33
+ #: includes/class-bwp-framework.php:211
34
+ #, php-format
35
+ msgid "You are using version %s!"
36
+ msgstr "Anda menggunakan versi %s!"
37
+
38
+ #: includes/class-bwp-framework.php:343
39
+ msgid "Settings"
40
+ msgstr "Tetapan"
41
+
42
+ #: includes/class-bwp-gxs-cache.php:34
43
+ #, php-format
44
+ msgid "Cache directory (\"%s\") does not exist or is not writable."
45
+ msgstr "Direktori cache (\"%s\") tidak wujud atau tidak boleh dibaca."
46
+
47
+ #: includes/class-bwp-gxs-cache.php:56
48
+ #, php-format
49
+ msgid "Cache file for module <em>%s</em> is not found and will be built right away."
50
+ msgstr "Fail cache untuk modul <em>%s</em> tidak dijumpai dan akan dibina segera."
51
+
52
+ #: includes/class-bwp-gxs-cache.php:106
53
+ #: includes/class-bwp-simple-gxs.php:859
54
+ #, php-format
55
+ msgid "Successfully served a cached version of <em>%s.xml</em>."
56
+ msgstr "Berjaya melayan versi cache untuk <em>%s.xml</em>."
57
+
58
+ #: includes/class-bwp-simple-gxs.php:119
59
+ #: includes/class-bwp-simple-gxs.php:259
60
+ msgid "Sitemap Statistics"
61
+ msgstr "Statistik Pelan Tapak"
62
+
63
+ #: includes/class-bwp-simple-gxs.php:120
64
+ #: includes/class-bwp-simple-gxs.php:260
65
+ msgid "Sitemap Generator"
66
+ msgstr "Penghasilan Pelan Tapak"
67
+
68
+ #: includes/class-bwp-simple-gxs.php:139
69
+ #, php-format
70
+ msgid "This sitemap was originally generated in %s second(s) (Memory usage: %s) - %s queries - %s URL(s) listed"
71
+ msgstr "Peta tapak ini asalnya telah dihasilkan selama %s saat (Penggunaan memori: %s) - %s maklumat - %s URL(s) telah disenaraikan"
72
+
73
+ #: includes/class-bwp-simple-gxs.php:257
74
+ msgid "BWP Google XML Sitemaps"
75
+ msgstr "Pelan Tapak Google XML BWP "
76
+
77
+ #: includes/class-bwp-simple-gxs.php:259
78
+ msgid "BWP Google XML Sitemaps Statistics"
79
+ msgstr "Statistik Pelan Tapak Google XML BWP "
80
+
81
+ #: includes/class-bwp-simple-gxs.php:260
82
+ msgid "BWP Google XML Sitemaps Generator"
83
+ msgstr "Penghasilan Pelan Tapak Google XML BWP"
84
+
85
+ #: includes/class-bwp-simple-gxs.php:271
86
+ msgid "You do not have sufficient permissions to access this page."
87
+ msgstr "Anda tidak mempunyai cukup kebenaran untuk mengakses muka ini."
88
+
89
+ #: includes/class-bwp-simple-gxs.php:289
90
+ msgid "What are Sitemaps?"
91
+ msgstr "Apa itu Pelan tapak?"
92
+
93
+ #: includes/class-bwp-simple-gxs.php:290
94
+ msgid "Your sitemaps"
95
+ msgstr "Pelan tapak anda"
96
+
97
+ #: includes/class-bwp-simple-gxs.php:291
98
+ msgid "Submit your sitemaps"
99
+ msgstr "Serah pelan tapak anda"
100
+
101
+ #: includes/class-bwp-simple-gxs.php:292
102
+ msgid "Pinging search engines"
103
+ msgstr "Penghantaran ke enjin carian"
104
+
105
+ #: includes/class-bwp-simple-gxs.php:293
106
+ msgid "Enable pinging functionality?"
107
+ msgstr "Benarkan keberkesanan penghantaran? "
108
+
109
+ #: includes/class-bwp-simple-gxs.php:294
110
+ msgid "Enable pinging individual SE"
111
+ msgstr "Benarkan penghantaran SE individu"
112
+
113
+ #: includes/class-bwp-simple-gxs.php:295
114
+ msgid "Sitemap Generator's Log"
115
+ msgstr "Log Penghasilan Pelan Tapak"
116
+
117
+ #: includes/class-bwp-simple-gxs.php:296
118
+ msgid "Enable logging?"
119
+ msgstr "Benarkan log?"
120
+
121
+ #: includes/class-bwp-simple-gxs.php:297
122
+ msgid "Enable debugging?"
123
+ msgstr "Benarkan debugging?"
124
+
125
+ #: includes/class-bwp-simple-gxs.php:307
126
+ msgid "In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional metadata about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site &mdash; http://www.sitemaps.org/"
127
+ msgstr "Dalam erti kata mudah, sebuah pelan tapak adalah fail XML yang mengandungi senarai URL untuk halaman bersama-sama dengan metadata tambahan tentang setiap URL (saat terakhir dikemaskinikan, seberapa kerap perubahan biasanya, dan betapa pentingnya, berkait rapat dengan URL lain di tapak ) jadi enjin carian akan lebih berkesan mencari tapak tersebut - http://www.sitemaps.org/"
128
+
129
+ #: includes/class-bwp-simple-gxs.php:308
130
+ msgid "<em>Basic information about all your sitemaps.</em>"
131
+ msgstr "<em>Maklumat asas tentang keseluruhan pelan tapak anda.</em>"
132
+
133
+ #: includes/class-bwp-simple-gxs.php:309
134
+ msgid "<em>More detailed information about how your sitemaps are generated including <span style=\"color: #999999;\">notices</span>, <span style=\"color: #FF0000;\">errors</span> and <span style=\"color: #009900;\">success messages</span>.</em>"
135
+ msgstr "<em>Maklumat lebih lanjut tentang bagaimana pelan tapak anda telah dihasilkan termasuk <span style=\"color: #999999;\">notices</span>, <span style=\"color: #FF0000;\">ralat</span> dan juga <span style=\"color: #009900;\">mesej berjaya</span>.</em>"
136
+
137
+ #: includes/class-bwp-simple-gxs.php:310
138
+ #, php-format
139
+ msgid "<em>Submit your sitemapindex to major search engines like <a href=\"%s\" target=\"_blank\">Google</a>, <a href=\"%s\" target=\"_blank\">Yahoo</a>, <a href=\"%s\" target=\"_blank\">Bing</a> or <a href=\"%s\" target=\"_blank\">Ask</a>.</em>"
140
+ msgstr "<em>Hantar indeks pelan tapak anda kepada enjin carian biasa seperti <a href=\"%s\" target=\"_blank\">Google</a>, <a href=\"%s\" target=\"_blank\">Yahoo</a>, <a href=\"%s\" target=\"_blank\">Bing</a> atau <a href=\"%s\" target=\"_blank\">Ask</a>.</em>"
141
+
142
+ #: includes/class-bwp-simple-gxs.php:311
143
+ msgid "<em>Now when you post something new to your blog, you can <em>ping</em> those search engines to tell them your blog just got updated. Pinging could be less effective than you think it is but you should enable such feature anyway.</em>"
144
+ msgstr "<em>Sekarang apabila anda menghantar sesuatu yang baru pada blog anda, anda boleh <em>menguji</em> enjin carian untuk memberitahu mereka bahawa blog anda baru dikemaskinikan. Penghantaran mungkin kurang efektif dari yang anda fikir tetapi anda harus juga benarkan fungsi ini.</em>"
145
+
146
+ #: includes/class-bwp-simple-gxs.php:316
147
+ msgid "Selected SE below will be pinged when you publish new posts."
148
+ msgstr "SE yang dipilih dibawah akan dihantar apabila anda menerbitkan pos baharu."
149
+
150
+ #: includes/class-bwp-simple-gxs.php:317
151
+ msgid "No additional load is needed so enabling this is recommended."
152
+ msgstr "Tiada beban tambahan diperlukan jadi membenarkan ini adalah digalakkan."
153
+
154
+ #: includes/class-bwp-simple-gxs.php:318
155
+ msgid "Minor errors will be printed on screen. Also, when debug is on, no caching is used, useful when you develop new modules."
156
+ msgstr "Ralat kecil akan dicetak pada skrin. Juga, apabila debug diaktifkan, tiada caching akan digunakan, berguna apabila anda mengembangkan modul baharu."
157
+
158
+ #: includes/class-bwp-simple-gxs.php:319
159
+ msgid "Google"
160
+ msgstr "Google"
161
+
162
+ #: includes/class-bwp-simple-gxs.php:320
163
+ #, php-format
164
+ msgid "Yahoo &mdash; <a href=\"%s\" target=\"_blank\">important</a>"
165
+ msgstr "Yahoo &mdash; <a href=\"%s\" target=\"_blank\">penting</a>"
166
+
167
+ #: includes/class-bwp-simple-gxs.php:321
168
+ msgid "Bing"
169
+ msgstr "Bing"
170
+
171
+ #: includes/class-bwp-simple-gxs.php:322
172
+ msgid "Ask.com"
173
+ msgstr "Ask.com"
174
+
175
+ #: includes/class-bwp-simple-gxs.php:325
176
+ #, php-format
177
+ msgid "After you activate this plugin, all sitemaps should be available right away. The next step is to submit the sitemapindex to major search engines. You only need the <strong>sitemapindex</strong> and nothing else, those search engines will automatically recognize other included sitemaps. You can read a small <a href=\"%s\">How-to</a> if you are interested."
178
+ msgstr "Apabila anda aktifkan plugin ini, semua pelan tapak sepatutnya sudah berada. Langkah seterusnya ialah dengan menghantar indeks pelan tapak kepada enjin carian. Anda cuma perlu <strong>indeks pelan tapak</strong> dan selain itu, enjin carian secara automatik mengenalpasti pelan tapak yang lain. Anda boleh merujuk <a href=\"%s\">Langkah-langkah</a> jika anda berminat."
179
+
180
+ #: includes/class-bwp-simple-gxs.php:349
181
+ msgid "Output no more than"
182
+ msgstr "Output tidak lebih dari"
183
+
184
+ #: includes/class-bwp-simple-gxs.php:350
185
+ msgid "Default change frequency"
186
+ msgstr "Ubah frekuensi lalai"
187
+
188
+ #: includes/class-bwp-simple-gxs.php:351
189
+ msgid "Default priority"
190
+ msgstr "Keutamaan lalai"
191
+
192
+ #: includes/class-bwp-simple-gxs.php:352
193
+ msgid "Minimum priority"
194
+ msgstr "Keutamaan minimum"
195
+
196
+ #: includes/class-bwp-simple-gxs.php:353
197
+ msgid "Add sitemapindex to WordPress's virtual robots.txt?"
198
+ msgstr "Tambah indeks pelan tapak kepada WordPress's robots.txt?"
199
+
200
+ #: includes/class-bwp-simple-gxs.php:354
201
+ msgid "In sitemapindex, include"
202
+ msgstr "Di dalam indeks pelan tapak, termasuk"
203
+
204
+ #: includes/class-bwp-simple-gxs.php:355
205
+ msgid "Style your sitemaps with an XSLT stylesheet?"
206
+ msgstr "Ubah pelan tapak anda dengan gaya lembar XSLT?"
207
+
208
+ #: includes/class-bwp-simple-gxs.php:356
209
+ msgid "Custom XSLT stylesheet URL"
210
+ msgstr "URL gaya lembar XSLT yang diubah"
211
+
212
+ #: includes/class-bwp-simple-gxs.php:357
213
+ msgid "Show build stats in sitemaps?"
214
+ msgstr "Papar status bina dalam pelan tapak?"
215
+
216
+ #: includes/class-bwp-simple-gxs.php:358
217
+ msgid "Enable credit?"
218
+ msgstr "Paparkan penghargaan?"
219
+
220
+ #: includes/class-bwp-simple-gxs.php:359
221
+ msgid "Enable Gzip?"
222
+ msgstr "Benarkan Gzip?"
223
+
224
+ #: includes/class-bwp-simple-gxs.php:360
225
+ msgid "Module Options"
226
+ msgstr "Tetapan modul"
227
+
228
+ #: includes/class-bwp-simple-gxs.php:361
229
+ msgid "Alternate module directory"
230
+ msgstr "Direktori pengganti modul"
231
+
232
+ #: includes/class-bwp-simple-gxs.php:362
233
+ msgid "Get no more than"
234
+ msgstr "Dapat tidak lebih daripada"
235
+
236
+ #: includes/class-bwp-simple-gxs.php:363
237
+ msgid "Caching Options"
238
+ msgstr "Tetapan Caching"
239
+
240
+ #: includes/class-bwp-simple-gxs.php:364
241
+ msgid "Enable caching?"
242
+ msgstr "Benarkan caching?"
243
+
244
+ #: includes/class-bwp-simple-gxs.php:365
245
+ msgid "Enable auto cache re-generation?"
246
+ msgstr "Benarkan auto cache di-generasi?"
247
+
248
+ #: includes/class-bwp-simple-gxs.php:366
249
+ msgid "Cached sitemaps will last for"
250
+ msgstr "Pelan tapak yang di-cache-kan akan bertahan selama"
251
+
252
+ #: includes/class-bwp-simple-gxs.php:367
253
+ msgid "Cached sitemaps are stored in (auto detected)"
254
+ msgstr "Pelan tapak yang di-cache-kan akan disimpan di dalam (auto carian)"
255
+
256
+ #: includes/class-bwp-simple-gxs.php:371
257
+ msgid "<em>Cache your sitemaps for better performance.</em>"
258
+ msgstr "<em>Cache pelan tapak anda untuk prestasi yang memberangsangkan.</em>"
259
+
260
+ #: includes/class-bwp-simple-gxs.php:372
261
+ #, php-format
262
+ msgid "<em>This plugin uses modules to build sitemap data so it is recommended that you extend this plugin using modules rather than hooks. Some of the settings below only affect modules extending the base module class. Read more about using modules <a href=\"%s#using-modules\">here</a>.</em>"
263
+ msgstr "<em>Plugin ini menggunakan modul untuk membina data pelan tapak jadi digalakkan untuk anda mengembangkan plugin ini menggunakan modul-modul berbanding dikait. Salah satu daripada tetapan dibawah hanya mempengaruhi dalam memperluas kelas modul asas.Lebih lanjut tentang penggunaan modul <a href=\"%s#using-modules\">disini</a>.</em>"
264
+
265
+ #: includes/class-bwp-simple-gxs.php:382
266
+ #: includes/class-bwp-simple-gxs.php:388
267
+ msgid "second(s)"
268
+ msgstr "saat"
269
+
270
+ #: includes/class-bwp-simple-gxs.php:383
271
+ #: includes/class-bwp-simple-gxs.php:389
272
+ msgid "minute(s)"
273
+ msgstr "minit"
274
+
275
+ #: includes/class-bwp-simple-gxs.php:384
276
+ #: includes/class-bwp-simple-gxs.php:390
277
+ msgid "hour(s)"
278
+ msgstr "jam"
279
+
280
+ #: includes/class-bwp-simple-gxs.php:385
281
+ #: includes/class-bwp-simple-gxs.php:391
282
+ msgid "day(s)"
283
+ msgstr "hari"
284
+
285
+ #: includes/class-bwp-simple-gxs.php:398
286
+ #: includes/class-bwp-simple-gxs.php:399
287
+ #: includes/class-bwp-simple-gxs.php:400
288
+ msgid "read more"
289
+ msgstr "lebih lanjut"
290
+
291
+ #: includes/class-bwp-simple-gxs.php:403
292
+ msgid "your sitemaps are generated and then cached to reduce unnecessary work."
293
+ msgstr "pelan tapak anda telah dihasilkan dan kemudian di-cache-kan untuk mengurangkan kerja yang diperlukan."
294
+
295
+ #: includes/class-bwp-simple-gxs.php:404
296
+ msgid "when a cached sitemap expires, this plugin will try to generate the cache again. If you disable this, remember to manually flush the cache once in a while."
297
+ msgstr "apabila cache pelan tapak luput, plugin ini akan cuba untuk menghasilkan cache lagi. Jika anda tidak membenarkan ini, waspada untuk membuang cache secara manual sekali sekala."
298
+
299
+ #: includes/class-bwp-simple-gxs.php:404
300
+ msgid "Flush the cache"
301
+ msgstr "Buang cache"
302
+
303
+ #: includes/class-bwp-simple-gxs.php:405
304
+ msgid "tell you useful information such as build time, memory usage, SQL queries, etc."
305
+ msgstr "beritahu anda maklumat seperti masa bina, pengunaan memori, maklumat SQL dan lain-lain."
306
+
307
+ #: includes/class-bwp-simple-gxs.php:406
308
+ #, php-format
309
+ msgid "make your sitemaps ~ 70% smaller."
310
+ msgstr "membuat pelan tapak anda 70% lebih kecil."
311
+
312
+ #: includes/class-bwp-simple-gxs.php:407
313
+ msgid "static pages' sitemap."
314
+ msgstr "pelan tapak muka statik."
315
+
316
+ #: includes/class-bwp-simple-gxs.php:408
317
+ msgid "taxonomy archives' sitemaps, including custom taxonomies."
318
+ msgstr "menamakan arkib pelan tapak, termasuk yang diubahsuai."
319
+
320
+ #: includes/class-bwp-simple-gxs.php:409
321
+ msgid "tag archives' sitemaps."
322
+ msgstr "Lekat arkib pelan tapak."
323
+
324
+ #: includes/class-bwp-simple-gxs.php:410
325
+ msgid "date archives' sitemaps."
326
+ msgstr "tarikh arkib pelan tapak."
327
+
328
+ #: includes/class-bwp-simple-gxs.php:411
329
+ msgid "some copyrighted info is also added to your sitemaps. Thanks!"
330
+ msgstr "sedikit maklumat hakcipta juga akan ditambah pada pelan tapak anda. Terima kasih! "
331
+
332
+ #: includes/class-bwp-simple-gxs.php:412
333
+ msgid "This will load the default stylesheet provided by this plugin. You can set a custom stylesheet below or filter the <code>bwp_gxs_xslt</code> hook."
334
+ msgstr "Ini akan menambah gaya lembar lalai yang dibekalkan dengan plugin ini. Anda boleh menetapkan gaya lembar yang diubahsuai di bawah atau dengan menapis <code>bwp_gxs_xslt</code>."
335
+
336
+ #: includes/class-bwp-simple-gxs.php:413
337
+ #, php-format
338
+ msgid "If you're on a Multi-site installation with Sub-domain enabled, each site will have its own robots.txt, sites in sub-directory will not. Please read the <a href=\"%s#toc-robots\" target=\"_blank\">documentation</a> for more info."
339
+ msgstr "Jika anda di dalam Multi-tapak pemasangan dengan Sub-domain digunakan, setiap tapak akan ada setiap robot.txt sendiri, manakala tapak di dalam sub- direktori adalah sebaliknya. Sila rujuk <a href=\"%s#toc-robots\" target=\"_blank\">dokumentasi</a> untuk maklumat terperinci."
340
+
341
+ #: includes/class-bwp-simple-gxs.php:416
342
+ msgid "item(s) in one sitemap. Actually, 5000 would be more ideal. You can not go over 50,000, though."
343
+ msgstr "item di dalam satu pelan tapak. Akan tetapi, 5000 adalah lebih sesuai. Anda tidak boleh melebihi 50,000, walaubagaimanapun."
344
+
345
+ #: includes/class-bwp-simple-gxs.php:417
346
+ msgid "Input a full path to the directory where you put your own modules (e.g. <code>/home/mysite/public_html/gxs-modules/</code>), you can also override a built-in module by having a module with the same filename in this directory. A filter is also available if you would like to use PHP instead."
347
+ msgstr "Masuk ruang penuh untuk direktori dimana anda meletak modul anda sendiri (contoh <code>/home/mysite/public_html/gxs-modules/</code>), anda juga boleh melebih-naik modul yang terbina dengan mendapat nama modul fail yang sama di dalam direktori. Penapis juga tersedia jika anda mahu menggunakan PHP."
348
+
349
+ #: includes/class-bwp-simple-gxs.php:418
350
+ msgid "The cache directory must be writable (i.e. CHMOD to 755 or 777)."
351
+ msgstr "Cache direktori harus boleh ditulis (i.e. CHMOD to 755 or 777)."
352
+
353
+ #: includes/class-bwp-simple-gxs.php:419
354
+ msgid "item(s) in one SQL query. This helps you avoid running too heavy queries."
355
+ msgstr "item-item di dalam satu maklumat SQL. Ini membantu anda untuk menghindar dari menggunakan maklumat terlalu banyak."
356
+
357
+ #: includes/class-bwp-simple-gxs.php:422
358
+ msgid "expected to be an absolute URL, e.g. <code>http://example.com/my-stylesheet.xsl</code>. You must also have a style sheet for the sitemapindex that can be accessed through the above URL, e.g. <code>my-stylesheet.xsl</code> and <code>my-stylesheetindex.xsl</code>). Please leave blank if you do not wish to use."
359
+ msgstr "jangkaan untuk menjadi URL tetap, contohnya <code>http://example.com/my-stylesheet.xsl</code>. Anda juga harus mempunyai gaya lembar untuk indeks pelan tapak yang mana boleh di akses melalui URL di atas, contohnya <code>my-stylesheet.xsl</code> dan <code>my-stylesheetindex.xsl</code>). Sila tinggalkan kosong sekiranya anda tidak berhasrat untuk menggunakannya."
360
+
361
+ #: includes/class-bwp-simple-gxs.php:449
362
+ #: includes/class-bwp-simple-gxs.php:451
363
+ msgid "Notice"
364
+ msgstr "Notis"
365
+
366
+ #: includes/class-bwp-simple-gxs.php:449
367
+ #, php-format
368
+ msgid "<strong>%d</strong> cached sitemaps have been flushed successfully!"
369
+ msgstr "<strong>%d</strong> pelan tapak yang di-cache-kan telah di buang!"
370
+
371
+ #: includes/class-bwp-simple-gxs.php:451
372
+ msgid "Could not delete any cached sitemaps. Please manually check the cache directory."
373
+ msgstr "Tidak boleh buang mana-mana pelan tapak yang telah di-cache-kan. Sila rujuk cache direktori secara manual."
374
+
375
+ #: includes/class-bwp-simple-gxs.php:503
376
+ msgid "Warning"
377
+ msgstr "Amaran"
378
+
379
+ #: includes/class-bwp-simple-gxs.php:503
380
+ msgid "Cache directory does not exist or is not writable. Please read more about directory permission <a href='http://www.zzee.com/solutions/unix-permissions.shtml'>here</a> (Unix)."
381
+ msgstr "Direktori cache tidak wujud atau tidak boleh dibaca. Sila rujuk direktori berkenaan kebenaran <a href='http://www.zzee.com/solutions/unix-permissions.shtml'>disini</a> (Unix)."
382
+
383
+ #: includes/class-bwp-simple-gxs.php:557
384
+ msgid "(Debug is on)"
385
+ msgstr "(Debug dibuka)"
386
+
387
+ #: includes/class-bwp-simple-gxs.php:570
388
+ msgid "<strong>BWP Google XML Sitemaps Error:</strong> "
389
+ msgstr "<strong>Google XML Pelan tapak BWP Ralat:</strong>"
390
+
391
+ #: includes/class-bwp-simple-gxs.php:570
392
+ msgid "BWP Google XML Sitemaps Error"
393
+ msgstr "Google XML Pelan tapak BWP Ralat"
394
+
395
+ #: includes/class-bwp-simple-gxs.php:593
396
+ #, php-format
397
+ msgid "Nothing here... yet! Try submitting your <a href=\"%s\">sitemapindex</a> first!"
398
+ msgstr "Tiada disini...lagi! Cuba hantar <a href=\"%s\">indeks pelan tapak</a> anda dahulu!"
399
+
400
+ #: includes/class-bwp-simple-gxs.php:593
401
+ msgid "No log yet!"
402
+ msgstr "Tiada log lagi!"
403
+
404
+ #: includes/class-bwp-simple-gxs.php:603
405
+ #, php-format
406
+ msgid "%s"
407
+ msgstr "%s"
408
+
409
+ #: includes/class-bwp-simple-gxs.php:603
410
+ #, php-format
411
+ msgid "<a href=\"%s\" target=\"_blank\">%s</a> has been successfully built on <strong>%s</strong>."
412
+ msgstr "<a href=\"%s\" target=\"_blank\">%s</a> telah berjaya dibina <strong>%s</strong>."
413
+
414
+ #: includes/class-bwp-simple-gxs.php:613
415
+ #: includes/class-bwp-simple-gxs.php:616
416
+ msgid "M j, Y : H:i:s"
417
+ msgstr "M j, Y : H:i:s"
418
+
419
+ #: includes/class-bwp-simple-gxs.php:836
420
+ #, php-format
421
+ msgid "Requested module (<em>%s</em>) not found or not allowed."
422
+ msgstr "Modul yang diminta (<em>%s</em>) tidak dijumpai atau tidak dibenarkan."
423
+
424
+ #: includes/class-bwp-simple-gxs.php:886
425
+ #: includes/class-bwp-simple-gxs.php:906
426
+ #, php-format
427
+ msgid "Loaded a custom sub-module file: <strong>%s</strong>."
428
+ msgstr "Lain-lain fail sub-modul telah dibekalkan: <strong>%s</strong>."
429
+
430
+ #: includes/class-bwp-simple-gxs.php:895
431
+ #, php-format
432
+ msgid "Mapped sub-module file: <strong>%s</strong> is not available in both default and custom module directory. The plugin will now try loading the requested sub-module instead."
433
+ msgstr "Fail sub-module yang dikategorikan: <strong>%s</strong> tidak terdapat di dalam kedua-dua lalai dan lain-lain direktori modul. Plugin sekarang akan cuba untuk menggunakan sub-modul."
434
+
435
+ #: includes/class-bwp-simple-gxs.php:914
436
+ #, php-format
437
+ msgid "Sub-module file: <strong>%s</strong> is not available in both default and custom module directory. The plugin will now try loading the parent module instead."
438
+ msgstr "Fail sub-modul: <strong>%s</strong> tidak terdapat di dalam kedua-dua lalai dan juga lain-lain direktori modul. Plugin akan cuba menggunakan modul utama."
439
+
440
+ #: includes/class-bwp-simple-gxs.php:927
441
+ #, php-format
442
+ msgid "Loaded a custom module file: <strong>%s</strong>."
443
+ msgstr "Menggunakan lain-lain fail modul: <strong>%s</strong>."
444
+
445
+ #: includes/class-bwp-simple-gxs.php:933
446
+ #, php-format
447
+ msgid "Could not load module file: <strong>%s</strong> in both default and custom module directory. Please recheck if that module file exists."
448
+ msgstr "Tidak boleh menggunakan fail modul: <strong>%s</strong> di kedua-dua lalai dan juga lain-lain direktori modul. Sila semak semula jika fail modul itu wujud."
449
+
450
+ #: includes/class-bwp-simple-gxs.php:951
451
+ #, php-format
452
+ msgid "There is no class named <strong>%s</strong> in the module file <strong>%s</strong>."
453
+ msgstr "Tiada kelas dinamakan <strong>%s</strong> di dalam fail modul <strong>%s</strong>."
454
+
455
+ #: includes/class-bwp-simple-gxs.php:960
456
+ #, php-format
457
+ msgid "Loaded a custom sitemapindex module file: <strong>%s</strong>."
458
+ msgstr "Menggunakan lain-lain fail modul indeks pelan tapak: <strong>%s</strong>."
459
+
460
+ #: includes/class-bwp-simple-gxs.php:980
461
+ #, php-format
462
+ msgid "Successfully generated <em>%s.xml</em> using module <em>%s</em>."
463
+ msgstr "Berjaya menghasilkan <em>%s.xml</em> menggunakan modul <em>%s</em>."
464
+
465
+ #: includes/class-bwp-simple-gxs.php:1090
466
+ #, php-format
467
+ msgid "Pinged %s successfully!"
468
+ msgstr "Penghantaran berjaya %s !"
469
+
470
+ #: includes/class-bwp-simple-gxs.php:1096
471
+ #, php-format
472
+ msgid "Ping limit for today to %s has been reached, sorry!"
473
+ msgstr "Had menghantar untuk hari ini kepada %s telah dicapai, maaf!"
474
+
475
+ #: includes/class-bwp-simple-gxs.php:1124
476
+ #, php-format
477
+ msgid "<em>%s.xml</em> does not have any item. The plugin has fired a 404 header to the search engine that requests it. You should check the module that generates that sitemap (<em>%s.php</em>)."
478
+ msgstr "<em>%s.xml</em> tiada apa-apa item. Plugin telah membuang permulaan 404 kepada enjian carian yang memintanya. Anda seharusnya meninjau modul yang menghasilkan pelan tapak itu (<em>%s.php</em>)."
479
+
480
+ #: includes/bwp-option-page/includes/class-bwp-option-page.php:74
481
+ msgid "Plugin Configurations"
482
+ msgstr "Tetapan Plugin"
483
+
484
+ #: includes/bwp-option-page/includes/class-bwp-option-page.php:391
485
+ msgid "Save Changes"
486
+ msgstr "Simpan Perubahan"
487
+
readme.txt ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Better WordPress Google XML Sitemaps (with sitemapindex and Multi-site support) ===
2
+ Contributors: OddOneOut
3
+ Donate link: http://betterwp.net/wordpress-plugins/google-xml-sitemaps/#contributions
4
+ Tags: xml sitemaps, google xml sitemaps, sitemapindex, sitemap, bing, google, msn, ask, multi-site, multisite
5
+ Requires at least: 3.0
6
+ Tested up to: 3.1.2
7
+ Stable tag: 1.0.5
8
+
9
+ The first WordPress XML Sitemap plugin that comes with comprehensive support for Sitemapindex and Multi-site.
10
+
11
+ == Description ==
12
+
13
+ Welcome to the first WordPress sitemap plugin that has support for both sitemapindex and Multi-site websites! You will no longer have to worry about the 50,000 URL limit or the time it takes for a sitemap to be generated. This plugin is fast, consumes much fewer resources and can be extended via your very own modules (yes, no hooks needed!). Here's a [demo](http://betterwp.net/sitemapindex.xml) of the sitemapindex if you are interested.
14
+
15
+ **Sitemapindex Support**
16
+
17
+ What's so great about a sitemapindex you might say? Sitemapindex, as its name suggests, is one kind of sitemaps that allows you to group multiple sitemaps files inside it. Sitemapindex, therefore, gives you many benefits, such as: possibility to bypass the 50,000 URL limit (you can have 10 custom sitemaps, each has 10000 URLs), or possibility to make the generation time much faster (because each sitemap is requested separately and is built by its own module), etc.
18
+
19
+ **Multi-site Support**
20
+
21
+ Each website within your network will have its own sitemapindex and sitemaps. For sub-domain installation, your sitemapindex will appear at `http://sub-domain.example.com/sitemapindex.xml`. For sub-folder installation, your sitemapindex will appear at `http://example.com/sub-folder/sitemapindex.xml`. And of course, there's always a sitemapindex for your main site, available at `http://example.com/sitemapindex.xml`. If you choose the sub-domain approach, each sub-domain can also have its own robots.txt.
22
+
23
+ **Custom sitemaps using modules**
24
+
25
+ The unrivaled flexibility this plugin offers is the ability to define your custom sitemaps using modules. Each module is a actually .php file that tell BWP Google XML Sitemap how to build a sitemap file. You can extend default modules or create completely new ones. This plugin also comes with a convenient base class for developing modules with easy to use and thoroughly documented API. Since modules can be defined by you, there's no limitation what a sitemap can have (for example you can bypass the 50,000 URL limit, as stated above). There's one limitation, though: your imagination ;) . Oh, did I mention that you can even use module to create another sitemapindex?
26
+
27
+ **Detailed Log and Debugging mode**
28
+
29
+ Developing modules needs debugging and this plugin makes that so easy for any developers. There are two kinds of logs: sitemap log and build log. Sitemap log tells you what sitemaps you have and when they were last requested/updated while build log tells you what's going on when a particular sitemap is built. The debug mode helps you trace errors in modules conveniently!
30
+
31
+ **For a complete feature list, please visit this [plugin's official page](http://betterwp.net/wordpress-plugins/google-xml-sitemaps/)**
32
+
33
+ **Important Notes**
34
+ If you encounter the 'Content Encoding Error' error page when trying to view a sitemap, please refer to the [FAQ section](http://betterwp.net/wordpress-plugins/google-xml-sitemaps/faq/) to know how to trace the actual error messages.
35
+
36
+ **Languages**
37
+
38
+ * English (default)
39
+ * Malaysian (ms_MY) - Thanks to [d4rkcry3r](http://d4rkcry3r.com)!
40
+
41
+ Please [help translate](http://betterwp.net/wordpress-tips/create-pot-file-using-poedit/) this plugin!
42
+
43
+ **Get in touch**
44
+
45
+ I'm available at [BetterWP.net](http://betterwp.net) and you can also follow me on [Twitter](http://twitter.com/0dd0ne0ut).
46
+
47
+ == Installation ==
48
+
49
+ 1. Upload the `bwp-google-xml-sitemaps` folder to the `/wp-content/plugins/` directory
50
+ 2. Activate the plugin through the Plugins menu in WordPress. After activation, you should see a menu of this plugin on your left. If you can not locate it, click on Settings under the plugin's name.
51
+ 3. Configure the plugin
52
+ 4. Build your sitemap for the first time or just submit the sitemapindex to all major search engines.
53
+ 5. Enjoy!
54
+
55
+ [View instructions with images](http://betterwp.net/wordpress-plugins/google-xml-sitemaps/installation/).
56
+
57
+ == Frequently Asked Questions ==
58
+
59
+ **Q: When I visit `http://example.com/sitemapindex.xml`, WordPress returns a 404 page. What should I do?**
60
+
61
+ This might be caused by unflushed rewrite rules, which should have been flushed when you activate this plugin. You can try flushing them manually by visiting Settings -> Permalinks and then clicking Save Changes.
62
+
63
+ **Q: I choose not to display certain sitemaps but the sitemapindex still displays them?**
64
+
65
+ What you see is actually a cached version of the sitemapindex. You can wait for it to be refreshed automatically or simply choose to 'Flush the Cache'.
66
+
67
+ **Q: Is there anyway to rename sitemapindex.xml to sitemap.xml?**
68
+
69
+ You don't have to. A visit to `http://example.com/sitemap.xml` will show you the same sitemapindex. This is done to make BWP GXS more compatible with blogs that have lots of real `robots.txt`. Please note that you must remove any real `sitemap.xml` file in your website's root for this feature to work.
70
+
71
+ **Q: I got the error 'Content Encoding Error', what should I do?**
72
+
73
+ If you are enabling this plugin's debug mode and/or WP_DEBUG, this error is very normal because the module you use might print errors on pages, thus corrupting your xml sitemaps. To view the actual errors without being greeted with the 'Content Encoding Error', please follow these steps:
74
+
75
+ 1. Enable this plugin's debug mode if you haven't done so.
76
+ 2. Open the file `class-bwp-simple-gxs.php` inside `bwp-google-xml-sitemaps/includes/` and look for this function: `output_sitemap()`.
77
+ 3. Place an `exit;` right after the opening bracket, like so:
78
+ <pre><code>
79
+ function output_sitemap()
80
+ {
81
+ exit;
82
+ </code></pre>
83
+ 4. Refresh the sitemaps with problems.
84
+ 5. Kindly report the errors you see by commenting or through the [contact form](http://betterwp.net/contact/). Thanks!
85
+
86
+ [Check plugin news and ask questions](http://betterwp.net/topic/google-xml-sitemaps/).
87
+
88
+ == Screenshots ==
89
+
90
+ 1. The default sitemapindex
91
+ 2. A custom post type sitemap
92
+ 3. The Configuration page
93
+
94
+ == Changelog ==
95
+
96
+ = 1.0.5 =
97
+ * Unregistered modules (such as redundant modules from 1.0.3) will now have a 404 HTTP status to prevent search engines from requesting them again.
98
+ * Time for each log entry will now make use of your current timezone setting in Settings -> General.
99
+ * And other minor fixes.
100
+
101
+ **Thanks everyone for using this plugin!**
102
+
103
+ = 1.0.4 =
104
+ * Hot fix for WordPress in other languages, such as French, Russian. Prior to this version this plugin tries to use posts' and taxonomies' labels to build sitemaps' URLs in plural forms (e.g. taxonomy_categories). Unfortunately this breaks sitemaps when labels contain UTF8 characters with marks (such as cat�gories). All sitemaps now have singular forms. Hope that we will have a better solution in the future.
105
+
106
+ **This change will make all logs' contents change as well. To remove redundant logs, please deactivate this plugin and then reactivate it.**
107
+
108
+ = 1.0.3 =
109
+ * Fixed incorrect regex for rewrite rules.
110
+ * Added a check to make sure all necessary rewrite rules are added. No need to manually flush rewrite rules anymore.
111
+ * `bwp_gxs_add_rewrite_rules` action now becomes `bwp_gxs_rewrite_rules` filter (the hook used to add your own sitemaps).
112
+
113
+ **For people using a cache plugin, please visit the [FAQ section](http://betterwp.net/wordpress-plugins/google-xml-sitemaps/faq/) for a possible compatibility fix.**
114
+
115
+ = 1.0.2 =
116
+ * Fixed a bug that could produce wrong or empty last modified dates in sitemapindex.
117
+ * Corrected a typo in page.php module.
118
+ * Added Malaysian translation, thanks to d4rkcry3r!
119
+
120
+ = 1.0.1 =
121
+ * Now you can browser to `http://example.com/sitemap.xml` to view your sitemapindex. You can submit it too if you want. **Important**: Make sure you don't have any real sitemap.xml file in your website's root. Also, you will have to flush all rewrite rules, by either deactivating and then reactivating this plugin, or simply go to [Permalink Settings](http://example.com/wp-admin/options-permalink.php) and click on Save Changes.
122
+ * Build stats (build time, number of queries, memory usage) should be more accurate now.
123
+ * Add a canonical redirection for sitemap URL to avoid problems with XSLT style sheet's absolute URL.
124
+ * Fixed a minor error in the base module class.
125
+
126
+ = 1.0.0 =
127
+ * Initial Release.
128
+
129
+ == Upgrade Notice ==
130
+
131
+ = 1.0.0 =
132
+ * Enjoy the plugin!
screenshot-1.gif ADDED
Binary file
screenshot-2.gif ADDED
Binary file
screenshot-3.gif ADDED
Binary file
xsl/bwp-sitemap.xsl ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsl:stylesheet version="1.0" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3
+ <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
4
+ <xsl:template match="/">
5
+ <html xmlns="http://www.w3.org/1999/xhtml">
6
+ <head>
7
+ <title>XML Sitemap</title>
8
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9
+ <style type="text/css">
10
+ body {
11
+ font-family: Verdana, Arial, Helvetica, sans-serif;
12
+ font-size: 12px;
13
+ }
14
+
15
+ #header, #footer {
16
+ background-color: #F0F7FC;
17
+ border: 1px #50A6E0 solid;
18
+ border-right: none; border-left: none;
19
+ padding: 5px 10px;
20
+ margin: 10px 0px;
21
+ line-height: 1.7;
22
+ }
23
+
24
+ #header a, #footer a {
25
+ color: #2266bb;
26
+ }
27
+
28
+ #footer {
29
+ margin-top: 15px;
30
+ }
31
+
32
+ table {
33
+ width: 100%;
34
+ }
35
+
36
+ th {
37
+ text-align: left;
38
+ border-bottom: 1px solid #aaaaaa;
39
+ padding-bottom: 10px; padding-left: 5px;
40
+ }
41
+
42
+ tr.odd {
43
+ background-color: #f7f7f7;
44
+ }
45
+
46
+ td {
47
+ padding: 5px;
48
+ margin: 0px;
49
+ }
50
+ </style>
51
+ </head>
52
+ <body>
53
+ <h1>XML Sitemap</h1>
54
+ <div id="header">
55
+ <p>
56
+ This sitemap was created using <a href="http://betterwp.net/wordpress-plugins/google-xml-sitemaps/" title="Better WordPress Google XML Sitemaps">Better WordPress Google XML Sitemaps</a>, a WordPress plugin that has support for sitemapindex and Multi-site blogs, you can also build custom sitemaps if you want.
57
+ </p>
58
+ </div>
59
+ <div id="content">
60
+ <table cellpadding="0" cellspacing="0">
61
+ <tr>
62
+ <th style="width: 60%;">Location</th>
63
+ <th>Priority</th>
64
+ <th>Change Frequency</th>
65
+ <th>Last Modified (GMT)</th>
66
+ </tr>
67
+ <xsl:for-each select="sitemap:urlset/sitemap:url">
68
+ <tr>
69
+ <xsl:if test="position() mod 2 != 0">
70
+ <xsl:attribute name="class">odd</xsl:attribute>
71
+ </xsl:if>
72
+ <td>
73
+ <xsl:variable name="itemURL">
74
+ <xsl:value-of select="sitemap:loc"/>
75
+ </xsl:variable>
76
+ <a href="{$itemURL}">
77
+ <xsl:value-of select="sitemap:loc"/>
78
+ </a>
79
+ </td>
80
+ <td>
81
+ <xsl:value-of select="sitemap:priority"/>
82
+ </td>
83
+ <td>
84
+ <xsl:value-of select="sitemap:changefreq"/>
85
+ </td>
86
+ <td>
87
+ <xsl:value-of select="concat(substring(sitemap:lastmod, 0, 11),concat(' ', substring(sitemap:lastmod, 12, 5)))"/>
88
+ </td>
89
+ </tr>
90
+ </xsl:for-each>
91
+ </table>
92
+ </div>
93
+ <div id="footer">
94
+ This plugin is (c) 2011 <a href="http://profiles.wordpress.org/users/OddOneOut/">Khang Minh</a> and is licensed under GPLv3.
95
+ </div>
96
+ </body>
97
+ </html>
98
+ </xsl:template>
99
+ </xsl:stylesheet>
xsl/bwp-sitemapindex.xsl ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsl:stylesheet version="1.0" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3
+ <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
4
+ <xsl:template match="/">
5
+ <html xmlns="http://www.w3.org/1999/xhtml">
6
+ <head>
7
+ <title>XML Sitemapindex</title>
8
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9
+ <style type="text/css">
10
+ body {
11
+ font-family: Verdana, Arial, Helvetica, sans-serif;
12
+ font-size: 12px;
13
+ }
14
+
15
+ #header, #footer {
16
+ background-color: #F0F7FC;
17
+ border: 1px #50A6E0 solid;
18
+ border-right: none; border-left: none;
19
+ padding: 5px 10px;
20
+ margin: 10px 0px;
21
+ line-height: 1.7;
22
+ }
23
+
24
+ #header a, #footer a {
25
+ color: #2266bb;
26
+ }
27
+
28
+ #footer {
29
+ margin-top: 15px;
30
+ }
31
+
32
+ table {
33
+ width: 100%;
34
+ }
35
+
36
+ th {
37
+ text-align: left;
38
+ border-bottom: 1px solid #aaaaaa;
39
+ padding-bottom: 10px; padding-left: 5px;
40
+ }
41
+
42
+ tr.odd {
43
+ background-color: #f7f7f7;
44
+ }
45
+
46
+ td {
47
+ padding: 5px;
48
+ }
49
+ </style>
50
+ </head>
51
+ <body>
52
+ <h1>XML Sitemapindex</h1>
53
+ <div id="header">
54
+ <p>
55
+ This sitemapindex was created using <a href="http://betterwp.net/wordpress-plugins/google-xml-sitemaps/" title="Better WordPress Google XML Sitemaps">Better WordPress Google XML Sitemaps</a>, a WordPress plugin that has support for sitemapindex and Multi-site blogs, you can also build custom sitemaps if you want.
56
+ </p>
57
+ </div>
58
+ <div id="content">
59
+ <table cellpadding="0" cellspacing="0">
60
+ <tr>
61
+ <th style="width: 70%;">Location</th>
62
+ <th>Last Modified (GMT)</th>
63
+ </tr>
64
+ <xsl:for-each select="sitemap:sitemapindex/sitemap:sitemap">
65
+ <tr>
66
+ <xsl:if test="position() mod 2 != 0">
67
+ <xsl:attribute name="class">odd</xsl:attribute>
68
+ </xsl:if>
69
+ <td>
70
+ <xsl:variable name="itemURL">
71
+ <xsl:value-of select="sitemap:loc"/>
72
+ </xsl:variable>
73
+ <a href="{$itemURL}">
74
+ <xsl:value-of select="sitemap:loc"/>
75
+ </a>
76
+ </td>
77
+ <td>
78
+ <xsl:value-of select="concat(substring(sitemap:lastmod, 0, 11),concat(' ', substring(sitemap:lastmod, 12, 5)))"/>
79
+ </td>
80
+ </tr>
81
+ </xsl:for-each>
82
+ </table>
83
+ </div>
84
+ <div id="footer">
85
+ This plugin is (c) 2011 <a href="http://profiles.wordpress.org/users/OddOneOut/">Khang Minh</a> and is licensed under GPLv3.
86
+ </div>
87
+ </body>
88
+ </html>
89
+ </xsl:template>
90
+ </xsl:stylesheet>