OSDN Git Service

NP_PubMed v 0.2.1
[nucleus-jp/nucleus-plugins.git] / trunk / NP_GoogleSitemap / NP_GoogleSitemap.php
1 <?php
2
3 /** ============================================================================
4   * GoogleSitemap for Nucleus
5   *
6   * Copyright 2005 by Niels Leenheer
7   * ============================================================================
8   * This program is free software and open source software; you can redistribute
9   * it and/or modify it under the terms of the GNU General Public License as
10   * published by the Free Software Foundation; either version 2 of the License,
11   * or (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful, but WITHOUT
14   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16   * more details.
17   *
18   * You should have received a copy of the GNU General Public License along
19   * with this program; if not, write to the Free Software Foundation, Inc.,
20   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  or visit
21   * http://www.gnu.org/licenses/gpl.html
22   * ============================================================================
23   **/
24
25 /**
26   * History
27   *  0.7    modified release by shizuki
28   *             Generate URL modified from
29   *               'http://example.com/action.php?action=plugin&name=Sitemap' to
30   *               'http://example.com/sitemap.xml' and,or
31   *               'http://example.com/index.php?virtualpath=sitemap.xml'
32   *             Add 'lastmod' attribute
33   *  0.9    SitemapProtocol updated release
34   *             SitemapProtocol ver.0.9 as common for Google, Yahoo! and MSN(Live! Search)
35   *  1.0    Add Sitemap type and chage 'lastmod' generate
36   *             Add 'ROR Sitemap' format
37   *               For details about the ROR format, go to www.rorweb.com
38   *             Modify 'lastmod' attribute
39   *               item posted time or comment posted time or item update time
40   *               item update time generate by NP_UpdateTime
41   **/
42
43 class NP_GoogleSitemap extends NucleusPlugin
44 {
45
46         function getName()
47         {
48                 return 'GoogleSitemap';
49         }
50
51         function getAuthor()
52         {
53                 return 'Niels Leenheer + shizuki';
54         }
55
56         function getURL()
57         {
58                 return 'http://japan.nucleuscms.org/wiki/plugins:googlesitemap';
59         }
60
61         function getVersion()
62         {
63                 return '1.0';
64         }
65
66         function getDescription()
67         {
68                 return _G_SITEMAP_DESC;
69         }
70         
71         function getEventList()
72         {
73                 return array(
74                                          'PostAddItem',
75                                          'PreSendContentType'
76                                         );
77         }
78         
79         function supportsFeature($feature)
80         {
81         switch($feature) {
82                 case 'SqlTablePrefix':
83                         return 1;
84                 default:
85                         return 0;
86                 }
87         }
88
89         function event_PreSendContentType($data)
90         {
91                 global $CONF, $manager, $blogid;
92
93                 $mcategories = $this->pluginCheck('MultipleCategories');
94                 if ($mcategories) {
95                         if (method_exists($mcategories, 'getRequestName')) {
96                                 $subReq = $mcategories->getRequestName();
97                         } else {
98                                 $subReq = 'subcatid';
99                         }
100                 }
101                 $npUpdateTime = $this->pluginCheck('UpdateTime');
102
103                 if (!$blogid) {
104                         $blogid = $CONF['DefaultBlog'];
105                 } else {
106                         if (is_numeric($blogid)) {
107                                 $blogid = intval($blogid);
108                         } else {
109                                 $blogid = intval(getBlogIDFromName($blogid));
110                         }
111                 }
112
113                 $b =& $manager->getBlog($blogid);
114                 $BlogURL = $b->getURL();
115
116                 if ( substr($BlogURL, -1) != '/'
117                   && substr($BlogURL, -4) != '.php') {
118                         $BlogURL .= '/';
119                 }
120
121                 if (getVar('virtualpath')) {
122                         $info = preg_replace('|[^a-zA-Z0-9-~+_.?#=&;,/:@%]|i', '', getVar('virtualpath'));
123                 } elseif (serverVar('PATH_INFO')) {
124                         $info = preg_replace('|[^a-zA-Z0-9-~+_.?#=&;,/:@%]|i', '', serverVar('PATH_INFO'));
125                 } else {
126                         return;
127                 }
128
129                 $path_arr  = explode('/', $info);
130                 $PcMap     = $this->getBlogOption($blogid, 'PcSitemap');
131                 $MobileMap = $this->getBlogOption($blogid, 'MobileSitemap');
132                 if ( end($path_arr) == $PcMap
133                   || end($path_arr) == 'ror.xml'
134                   || (!empty($MobileMap) && end($path_arr) == $MobileMap) ) {
135                         $sitemap = array();
136                         if ( $this->getOption('AllBlogMap') == 'yes'
137                           && $blogid == $CONF['DefaultBlog']) {
138                                 $blogQuery  = 'SELECT * '
139                                                         . 'FROM %s '
140                                                         . 'ORDER BY bnumber';
141                                 $blogQuery  = sprintf($blogQuery, sql_table('blog'));
142                                 $blogResult = sql_query($blogQuery);
143                         } else {
144                                 $blogQuery   = 'SELECT * '
145                                                          . 'FROM %s '
146                                                          . 'WHERE bnumber = %d';
147                                 $blogQuery   = sprintf($blogQuery, sql_table('blog'), $blogid);
148                                 $blogResult  = sql_query($blogQuery);
149                                 $currentBlog = TRUE;
150                         }
151                         while ($blogs = mysql_fetch_array($blogResult)) {
152                                 $blog_id = intval($blogs['bnumber']);
153                                 if (  $this->getBlogOption($blog_id, 'IncludeSitemap') == 'yes'
154                                    || !empty($currentBlog)) {
155                                         $temp_b  =& $manager->getBlog($blog_id);
156                                         $TempURL =  $temp_b->getURL();
157                                         $SelfURL =  $TempURL;
158
159                                         $URLMode = $CONF['URLMode'];
160                                         if (substr($TempURL, -4) == '.php') {
161                                                 $CONF['URLMode'] = 'normal';
162                                         }
163
164                                         $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
165
166                                         if (substr($SelfURL, -1) == '/') {
167
168                                                 if ($usePathInfo) {
169                                                         $SelfURL = substr($SelfURL, 0, -1);
170                                                 } else {
171                                                         $SelfURL = $SelfURL . 'index.php';
172                                                 }
173
174                                         } elseif (substr($SelfURL, -4) != '.php') {
175
176                                                 if ($usePathInfo) {
177                                                         $SelfURL = $SelfURL;
178                                                 } else {
179                                                         $SelfURL = $SelfURL . '/index.php';
180                                                 }
181
182                                         }
183
184                                         $CONF['ItemURL']     = $SelfURL;
185                                         $CONF['CategoryURL'] = $SelfURL;
186
187                                         if ( substr($TempURL, -1) != '/'
188                                           && substr($TempURL, -4) != '.php') {
189                                                 $TempURL .= '/';
190                                         }
191
192                                         $patternURL = '/^' . preg_replace('/\//', '\/', $BlogURL) . '/';
193
194                                         if (preg_match($patternURL, $TempURL)) {
195
196                                                 if (end($path_arr) == 'ror.xml') {
197                                                         $rorTitleURL  = $this->_prepareLink($SelfURL, $TempURL);
198                                                         $rooTitleURL  = htmlspecialchars($rooTitleURL, ENT_QUOTES, _CHARSET);
199                                                         $sitemapTitle = "     <title>ROR Sitemap for " . $rorTitleURL . "</title>\n"
200                                                                                   . "     <link>" . $rorTitleURL . "</link>\n"
201                                                                                   . "     <item>\n"
202                                                                                   . "     <title>ROR Sitemap for " . $rorTitleURL . "</title>\n"
203                                                                                   . "     <link>" . $rorTitleURL . "</link>\n"
204                                                                                   . "     <ror:about>sitemap</ror:about>\n"
205                                                                                   . "     <ror:type>SiteMap</ror:type>\n"
206                                                                                   . "     </item>\n";
207                                                 } else {
208                                                         $sitemap[] = array(
209                                                                 'loc'        => $this->_prepareLink($SelfURL, $TempURL),
210                                                                 'priority'   => '1.0',
211                                                                 'changefreq' => 'daily'
212                                                         );
213                                                 }
214
215                                                 $catQuery  = 'SELECT * '
216                                                                    . 'FROM %s '
217                                                                    . 'WHERE cblog = %d '
218                                                                    . 'ORDER BY catid';
219                                                 $catTable  = sql_table('category');
220                                                 $catQuery  = sprintf($catQuery, $catTable, $blog_id);
221                                                 $catResult = sql_query($catQuery);
222
223                                                 while ($cat = mysql_fetch_array($catResult)) {
224
225                                                         $cat_id = intval($cat['catid']);
226                                                         $Link   = createCategoryLink($cat_id);
227                                                         $catLoc =$this->_prepareLink($SelfURL, $Link);
228
229                                                         if (end($path_arr) != 'ror.xml') {
230                                                                 $sitemap[] = array(
231                                                                         'loc'        => $catLoc,
232                                                                         'priority'   => '1.0',
233                                                                         'changefreq' => 'daily'
234                                                                 );
235                                                         }
236
237                                                         if ($mcategories) {
238                                                                 $scatQuery  = 'SELECT * '
239                                                                                         . 'FROM %s '
240                                                                                         . 'WHERE catid = %d '
241 //                                                                                      . 'ORDER BY scatid';
242                                                                                         . 'ORDER BY ordid';
243                                                                 $scatTable  = sql_table('plug_multiple_categories_sub');
244                                                                 $scatQuery  = sprintf($scatQuery, $scatTable, $cat_id);
245                                                                 $scatResult = sql_query($scatQuery);
246
247                                                                 while ($scat = mysql_fetch_array($scatResult)) {
248
249                                                                         $scat_id = intval($scat['scatid']);
250                                                                         $params  = array($subReq => $scat_id);
251                                                                         $Link    = createCategoryLink($cat_id, $params);
252                                                                         $scatLoc = $this->_prepareLink($SelfURL, $Link);
253
254                                                                         if (end($path_arr) != 'ror.xml') {
255                                                                                 $sitemap[] = array(
256                                                                                         'loc'        => $scatLoc,
257                                                                                         'priority'   => '1.0',
258                                                                                         'changefreq' => 'daily'
259                                                                                 );
260                                                                         }
261
262                                                                 }
263
264                                                         }
265
266                                                 }
267
268                                                 $itemQuery  = 'SELECT *, '
269                                                                         . '       UNIX_TIMESTAMP(itime) AS timestamp '
270                                                                         . 'FROM %s '
271                                                                         . 'WHERE iblog  = %d '
272                                                                         . 'AND   idraft = 0 '
273                                                                         . 'ORDER BY itime DESC';
274                                                 $itemTable  = sql_table('item');
275                                                 $itemQuery  = sprintf($itemQuery, $itemTable, $blog_id);
276                                                 $itemResult = sql_query($itemQuery);
277                                                 while ($item = mysql_fetch_array($itemResult)) {
278
279                                                         $item_id = intval($item['inumber']);
280                                                         $Link    = createItemLink($item_id);
281                                                         $tz      = date('O', $item['timestamp']);
282                                                         $tz      = substr($tz, 0, 3) . ':' . substr($tz, 3, 2);
283                                                         $itemLoc = $this->_prepareLink($SelfURL, $Link);
284
285                                                         $mdQuery = 'SELECT'
286                                                                          . '   UNIX_TIMESTAMP(ctime) AS timestamp'
287                                                                          . ' FROM '
288                                                                          .     sql_table('comment')
289                                                                          . ' WHERE'
290                                                                          . '   citem = ' . $item_id
291                                                                          . ' ORDER BY'
292                                                                          . '   ctime DESC'
293                                                                          . ' LIMIT'
294                                                                          . '   1';
295                                                         $modTime = sql_query($mdQuery);
296                                                         if (mysql_num_rows($modTime) > 0) {
297                                                                 $lastMod  = mysql_fetch_object($modTime);
298                                                                 $itemTime = $lastMod->timestamp;
299                                                         } elseif ($npUpdateTime) { // NP_UpdateTime exists
300                                                                 $mdQuery = 'SELECT'
301                                                                                  . '   UNIX_TIMESTAMP(ctime) AS timestamp'
302                                                                                  . ' FROM '
303                                                                                  .     sql_table('plugin_rectime')
304                                                                                  . ' WHERE'
305                                                                                  . '   up_id = ' . $item_id;
306                                                                 $modTime = sql_query($mdQuery);
307                                                                 if (mysql_num_rows($modTime) > 0) { 
308                                                                         $lastMod  = mysql_fetch_object($modTime);
309                                                                         $itemTime = $lastMod->timestamp;
310                                                                 }
311                                                         } else {
312                                                                 $itemTime = $item['timestamp'];
313                                                         }
314
315 /*                                                      if (time() - $itemTime < 86400 * 2) {
316                                                                 $fq = 'hourly';
317                                                         } elseif (time() - $itemTime < 86400 * 14) {
318                                                                 $fq = 'daily'; 
319                                                         } elseif (time() - $itemTime < 86400 * 62) {
320                                                                 $fq = 'weekly';
321                                                         } else {
322                                                                 $fq = 'monthly';
323                                                         }*/
324                                                         if ($itemTime < strtotime('-1 month')) {
325                                                                 $fq = 'monthly';
326                                                         } elseif ($itemTime < strtotime('-1 week')) {
327                                                                 $fq = 'weekly';
328                                                         } elseif ($itemTime < strtotime('-1 day')) {
329                                                                 $fq = 'daily'; 
330                                                         } else {
331                                                                 $fq = 'hourly';
332                                                         }
333                                                         $lastmod = gmdate('Y-m-d\TH:i:s', $itemTime) . $tz;
334
335                                                         if (end($path_arr) != 'ror.xml') {
336                                                                 $sitemap[] = array(
337                                                                         'loc'        => $itemLoc,
338                                                                         'lastmod'    => $lastmod,
339                                                                         'priority'   => '1.0',
340                                                                         'changefreq' => $fq
341                                                                 );
342                                                         } else {
343                                                                 $iTitle = $item['ititle'];
344                                                                 if (_CHARSET != 'UTF-8') {
345                                                                         $iTitle = mb_conbert_encoding($iTitle, 'UTF-8', _CHARSET);
346                                                                 }
347                                                                 $sitemap[] = array(
348                                                                         'title'            => $iTitle,
349                                                                         'link'             => $itemLoc,
350                                                                         'ror:updated'      => $lastmod,
351                                                                         'ror:updatePeriod' => 'day',
352                                                                         'ror:sortOrder'    => '0',
353                                                                         'ror:resourceOf'   => 'sitemap',
354                                                                 );
355                                                         }
356
357                                                 }
358
359                                         }
360
361                                 }
362
363                                 if ($CONF['URLMode'] != $URLMode) {
364                                         $CONF['URLMode'] = $URLMode;
365                                 }
366
367                         }
368
369                         $manager->notify('SiteMap', array ('sitemap' => & $sitemap));
370
371                         header ("Content-type: application/xml");
372
373                         if (end($path_arr) == 'ror.xml') {
374
375                         // ror sitemap feed
376                         $sitemapHeader ="<" . "?xml version='1.0' encoding='UTF-8'?" . ">\n\n"
377                                                    . "<!--  This file is a ROR Sitemap for describing this website to the search engines. "
378                                                    . "For details about the ROR format, go to www.rorweb.com.   -->\n"
379                                                    . '<rss version="2.0" xmlns:ror="http://rorweb.com/0.1/" >' . "\n"
380                                                    . "<channel>\n";
381
382                         } else {
383
384                         // old Google sitemap protocol ver.0.84
385 //                      $sitemapHeader  = "<" . "?xml version='1.0' encoding='UTF-8'?" . ">\n\n";
386 //                                                      . "\t<urlset" . ' xmlns="http://www.google.com/schemas/sitemap/0.84"' . "\n";
387 //                                                      . "\t" . 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n";
388 //                                                      . "\t" . 'xsi:schemaLocation="http://www.google.com/schemas/sitemap/0.84' . "\n";
389 //                                                      . "\t" . '        http://www.google.com/schemas/sitemap/0.84/sitemap.xsd">' . "\n";
390
391                         // new sitemap common protocol ver 0.9
392                         $sitemapHeader  = "<" . "?xml version='1.0' encoding='UTF-8'?" . ">\n\n"
393                                                         . '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n"
394                                                         . '         xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9' . "\n"
395                                                         . '         http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"' . "\n"
396                                                         . '         xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"';
397                         // uncomment and edit next line when you need "example_schema"
398 //                      $sitemapHeader .= '         xmlns:example="http://www.example.com/schemas/example_schema"';
399                         $sitemapHeader .= '>';
400
401                         }
402
403                         echo $sitemapHeader;
404                         if (end($path_arr) == 'ror.xml') {
405                                 echo $sitemapTitle;
406                         }
407
408                         while (list(, $url) = each($sitemap)) {
409
410                                 if (end($path_arr) == 'ror.xml') {
411                                         echo "\t<item>\n";
412                                 } else {
413                                         echo "\t<url>\n";
414                                 }
415
416                                 while (list($key, $value) = each($url)) {
417                                         if ($key == 'loc') {
418                                                 $value = preg_replace('|[^a-zA-Z0-9-~+_.?#=&;,/:@%]|i', '', $value);
419                                                 $data  = "\t\t<" . $key . ">"
420                                                            . htmlspecialchars($value, ENT_QUOTES, _CHARSET)
421                                                            . "</" . $key . ">\n";
422                                         } else {
423                                                 $data  = "\t\t<" . $key . ">"
424                                                            . htmlspecialchars($value, ENT_QUOTES, _CHARSET)
425                                                            . "</" . $key . ">\n";
426                                         }
427                                         echo $data;
428                                 }
429
430                                 if (end($path_arr) == 'ror.xml') {
431                                         echo "\t</item>\n";
432                                 } else {
433                                         echo "\t</url>\n";
434                                 }
435
436                         }
437
438                         if (end($path_arr) == 'ror.xml') {
439                                 echo "</channel>\n</rss>\n";
440                         } else {
441                                 echo "</urlset>\n";
442                         }
443 //                      echo "</urlset>\n";
444                         exit;
445
446                 }
447         }
448
449         function pluginCheck($pluginName)
450         {
451                 global $manager;
452                 if (!$manager->pluginInstalled('NP_' . $pluginName)) {
453                         return;
454                 } else {
455                         $plugin =& $manager->getPlugin('NP_' . $pluginName);
456                         return $plugin;
457                 }
458         }
459
460         function _prepareLink($base, $url) {
461                 if (substr($url, 0, 7) == 'http://') {
462                         return $url;
463                 } else {
464                         return $base . $url;
465                 }
466         }
467
468         function event_PostAddItem(&$data)
469         {
470                 global $manager, $CONF;
471
472                 $item_id = intval($data['itemid']);
473                 $blog_id = intval(getBlogIDFromItemID($item_id));
474
475                 if ($this->getBlogOption($blog_id, 'PingGoogle') == 'yes') {
476
477                         $b     =& $manager->getBlog($blog_id);
478                         $b_url =  $b->getURL();
479
480                         if (substr($b_url, -4) == '.php') $CONF['URLMode'] = 'normal';
481                         $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
482
483                         if (substr($b_url, -1) == '/') {
484                                 if (!$usePathInfo) {
485                                         $b_url .= 'index.php?virtualpath=';
486                                 }
487                         } elseif (substr($b_url, -4) == '.php') {
488                                 $b_url .= '?virtualpath=';
489                         } else {
490                                 if ($usePathInfo) {
491                                         $b_url = $b_url . '/';
492                                 } else {
493                                         $b_url = $b_url . '/index.php?virtualpath=';
494                                 }
495                         }
496
497                         $siteMap = $this->getBlogOption($blog_id, 'PcSitemap');
498                         $url     = 'http://www.google.com/webmasters/sitemaps/ping?sitemap='
499                                      . urlencode($b_url . $siteMap);
500                         $url     = preg_replace('|[^a-zA-Z0-9-~+_.?#=&;,/:@%]|i', '', $url);
501                         $fp      = @fopen($url, 'r');
502                         @fclose($fp);
503                         $MobileMap = $this->getBlogOption($blog_id, 'MobileSitemap');
504                         if (!empty($MobileMap)) {
505                                 $url = 'http://www.google.com/webmasters/sitemaps/ping?sitemap='
506                                          . urlencode($b_url . $MobileMap);
507                                 $url = preg_replace('|[^a-zA-Z0-9-~+_.?#=&;,/:@%]|i', '', $url);
508                                 $fp  = @fopen($url, 'r');
509                                 @fclose($fp);
510                         }
511                 }
512         }
513
514         function init()
515         {
516                 global $admin;
517                 $language = ereg_replace( '[\\|/]', '', getLanguageName());
518                 if (file_exists($this->getDirectory() . $language.'.php')) {
519                         include_once($this->getDirectory() . $language.'.php');
520                 }else {
521                         include_once($this->getDirectory() . 'english.php');
522                 }
523         }
524
525         function install()
526         {
527                 $this->createOption('AllBlogMap',         _G_SITEMAP_ALLB, 'yesno', 'yes');
528                 $this->createBlogOption('PingGoogle',     _G_SITEMAP_PING, 'yesno', 'yes');
529                 $this->createBlogOption('IncludeSitemap', _G_SITEMAP_INC,  'yesno', 'yes');
530                 $this->createBlogOption('PcSitemap',      _G_SITEMAP_PCSM, 'text',  'sitemap.xml');
531                 $this->createBlogOption('MobileSitemap',  _G_SITEMAP_MBSM, 'text',  '');
532         }
533 }