1: <?php
  2: 
  3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31: 
 32: 
 33: $client = cRegistry::getClientId();
 34: $cfgClient = cRegistry::getClientConfig();
 35: 
 36: 
 37: $idcatStart = "CMS_VALUE[1]";
 38: $idcatStart = cSecurity::toInteger($idcatStart);
 39: 
 40: 
 41: $filename = "CMS_VALUE[2]";
 42: if (!empty($filename)) {
 43:     $filename = basename($filename);
 44:     
 45:     if (substr($filename, -4) !== '.xml') {
 46:         $filename .= '.xml';
 47:     }
 48: }
 49: 
 50: try {
 51: 
 52:     
 53:     
 54:     if (!empty($filename) && !array_key_exists('rerun', $_REQUEST)) {
 55:         checkJobRerun('xml_sitemap_' . cRegistry::getClient()->get('name') . '_' . cRegistry::getLanguage()->get('name'));
 56:     }
 57: 
 58:     
 59:     $categoryCollection = new cApiCategoryCollection();
 60:     $categoryIds = $categoryCollection->getAllCategoryIdsRecursive($idcatStart, $client);
 61: 
 62:     $xmlString = <<<EOD
 63: <?xml version="1.0" encoding="UTF-8"?>
 64: <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>
 65: EOD;
 66: 
 67:     $sitemap = new SimpleXMLElement($xmlString);
 68: 
 69:     $itemCount = array();
 70: 
 71:     
 72:     $clientLanguageCollection = new cApiClientLanguageCollection();
 73:     foreach ($clientLanguageCollection->getLanguagesByClient($client) as $currentIdlang) {
 74: 
 75:         
 76:         $language = new cApiLanguage($currentIdlang);
 77:         if (!$language->isLoaded() || '1' != $language->get('active')) {
 78:             continue;
 79:         }
 80: 
 81:         
 82:         $arrayObject = new ArrayObject($categoryIds);
 83:         $currentCategoryIds = $arrayObject->getArrayCopy();
 84: 
 85:         
 86:         foreach ($currentCategoryIds as $key => $categoryId) {
 87:             $categoryLanguage = new cApiCategoryLanguage();
 88:             $categoryLanguage->loadByCategoryIdAndLanguageId($categoryId, $currentIdlang);
 89:             if ($categoryLanguage->get('visible') == false || $categoryLanguage->get('public') == false) {
 90:                 unset($currentCategoryIds[$key]);
 91:             }
 92:         }
 93: 
 94:         $itemCount[] = addArticlesToSitemap($sitemap, $currentCategoryIds, $currentIdlang);
 95:     }
 96: 
 97:     
 98:     if (0 < array_sum($itemCount)) {
 99:         
100:         $sitemap = cApiCecHook::executeAndReturn('Contenido.Content.XmlSitemapCreate', $sitemap);
101:     }
102: 
103:     
104:     saveSitemap($sitemap, $filename);
105: } catch (cException $e) {
106:     echo "\n\n[" . date('Y-m-d') . "] " . $e->getMessage() . "\n";
107: }
108: 
109: 110: 111: 112: 113: 114: 115: 116: 
117: function checkJobRerun($jobname) {
118:     
119:     $cfg = cRegistry::getConfig();
120:     $filename = $cfg['path']['contenido_cronlog'] . $jobname . '.job';
121:     if (cFileHandler::exists($filename)) {
122:         
123:         $cronlogContent = file_get_contents($filename);
124:         $lastRun = cSecurity::toInteger($cronlogContent);
125:         
126:         if ($lastRun > strtotime('-23 hour')) {
127:             
128:             throw new cException('job was already executed within last 23h');
129:         }
130:     }
131:     
132:     file_put_contents($filename, time());
133: }
134: 
135: 136: 137: 138: 139: 
140: function addArticlesToSitemap(SimpleXMLElement $sitemap, $categoryIds, $lang) {
141:     $itemCount = 0;
142: 
143:     
144:     if (0 < count($categoryIds)) {
145: 
146:         $cfg = cRegistry::getConfig();
147:         $tab = $cfg['tab'];
148:         $db = cRegistry::getDb();
149: 
150:         $useCategoryUrlsForStartArticles = 'true' == getEffectiveSetting('content-sitemap-xml', 'cat-url-for-startart', 'true');
151: 
152:         $categoryIds = implode(',', $categoryIds);
153: 
154:         
155:         $db->query("
156:             SELECT
157:                 art_lang.idart
158:                 , art_lang.idartlang
159:                 , UNIX_TIMESTAMP(art_lang.lastmodified) as lastmod
160:                 , art_lang.changefreq
161:                 , art_lang.sitemapprio
162:                 , cat_art.idcat
163:                 , IF(art_lang.idartlang = cat_lang.startidartlang, 1, 0) AS is_start
164:             FROM
165:                 `$tab[art_lang]` AS art_lang
166:                 , `$tab[cat_art]` AS cat_art
167:                 , `$tab[cat_lang]` AS cat_lang
168:             WHERE
169:                 art_lang.idart = cat_art.idart
170:                 AND art_lang.idlang = $lang
171:                 AND art_lang.online = 1
172:                 AND cat_art.idcat = cat_lang.idcat
173:                 AND cat_art.idcat IN ($categoryIds)
174:                 AND cat_lang.idlang = $lang
175:             ;");
176: 
177:         
178:         while ($db->nextRecord()) {
179:             $indexState = conGetMetaValue($db->f('idartlang'), 7);
180: 
181:             if (preg_match('/noindex/', $indexState)) {
182:                 continue;
183:             }
184: 
185:             $params = array();
186:             $params['lang'] = $lang;
187:             $params['changelang'] = $lang;
188: 
189:             
190:             
191:             if (1 == $db->f('is_start') && $useCategoryUrlsForStartArticles) {
192:                 $params['idcat'] = $db->f('idcat');
193:             } else {
194:                 $params['idart'] = $db->f('idart');
195:             }
196: 
197:             $loc = cUri::getInstance()->build($params, true);
198:             $loc = htmlentities($loc);
199: 
200:             addUrl($sitemap, array(
201:                 
202:                 'loc' => $loc,
203:                 
204:                 'lastmod' => (int) $db->f('lastmod'),
205:                 
206:                 'changefreq' => $db->f('changefreq'),
207:                 
208:                 'priority' => $db->f('sitemapprio')
209:             ));
210:             $itemCount++;
211:         }
212:     }
213: 
214:     return $itemCount;
215: }
216: 
217: 218: 219: 220: 221: 
222: function addUrl(SimpleXMLElement $sitemap, array $data) {
223:     $url = $sitemap->addChild('url');
224: 
225:     $url->addChild('loc', $data['loc']);
226: 
227:     if ($data['lastmod'] == '0000-00-00 00:00:00' || $data['lastmod'] == '') {
228:         $url->addChild('lastmod', conHtmlSpecialChars(iso8601Date(mktime())));
229:     } else {
230:         $url->addChild('lastmod', conHtmlSpecialChars(iso8601Date($data['lastmod'])));
231:     }
232: 
233:     if (!empty($data['changefreq'])) {
234:         $url->addChild('changefreq', $data['changefreq']);
235:     }
236: 
237:     if (!empty($data['priority']) || $data['priority'] == 0) {
238:         $url->addChild('priority', $data['priority']);
239:     }
240: }
241: 
242: 243: 244: 245: 246: 247: 248: 249: 250: 
251: function iso8601Date($time) {
252:     $tzd = date('O', $time);
253:     $tzd = chunk_split($tzd, 3, ':');
254:     $tzd = substr($tzd, 0, 6);
255:     $date = date('Y-m-d\TH:i:s', $time);
256:     return $date . $tzd;
257: }
258: 
259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 
269: function saveSitemap(SimpleXMLElement $sitemap, $filename = '') {
270:     if (empty($filename)) {
271:         header('Content-type: text/xml');
272:         echo $sitemap->asXML();
273:     } else if ($sitemap->asXML($cfgClient[$client]['path']['frontend'] . $filename)) {
274:         echo conHtmlSpecialChars(mi18n("XML sitemap successfully written to %s", $filename));
275:     } else {
276:         echo conHtmlSpecialChars(mi18n("XML sitemap could not be written to %s", $filename));
277:     }
278: }
279: 
280: ?>