Cheetah
ChWsbSiteMaps.php
Go to the documentation of this file.
1 <?php
2 
8 ch_import('ChWsbSiteMapsQuery');
9 
10 define('CH_SITE_MAPS_URLS_PER_FILE', 20000);
11 define('CH_SITE_MAPS_FILES_PREFIX', 'sitemap_');
12 define('CH_SITE_MAPS_FILE_INDEX', 'sitemap.xml');
13 
32 {
33  static protected $BASE_PATH = CH_DIRECTORY_PATH_CACHE_PUBLIC; // path to generated sitemaps
34  static protected $BASE_URL = CH_WSB_URL_CACHE_PUBLIC; // url to generated sitemaps
35  static protected $BASE_PATH_INDEX = CH_DIRECTORY_PATH_ROOT; // path to generated index sitemap
36  static protected $BASE_URL_INDEX = CH_WSB_URL_ROOT; // url to generated index sitemap
37 
38  protected $_aSystem = array (); // current sitemap system array
39  protected $_oQuery = null;
40  protected $_aQueryParts = array (
41  'fields' => "", // fields list, for example: `id`, `uri`, `last_edit_ts`
42  'field_date' => "", // date field name, for example: `last_edit_ts`
43  'field_date_type' => "timestamp", // date field type (datetime or timestamp)
44  'table' => "", // table name, for example: `my_table`
45  'join' => "", // join SQL part
46  'where' => "", // SQL condition, without WHERE, for example: active = 1
47  'order' => "", // SQL order, without ORDER BY, for example: `date` ASC
48  );
49 
50  protected function __construct($aSystem)
51  {
52  $this->_aSystem = $aSystem;
53  $this->_oQuery = new ChWsbSiteMapsQuery($this->_aSystem);
54  }
55 
61  static public function getObjectInstance($sObject)
62  {
63  if (isset($GLOBALS['chWsbClasses']['ChWsbSiteMaps!'.$sObject]))
64  return $GLOBALS['chWsbClasses']['ChWsbSiteMaps!'.$sObject];
65 
67  if (!$aSystems || !isset($aSystems[$sObject]))
68  return false;
69 
70  $aObject = $aSystems[$sObject];
71 
72  if (!($sClass = $aObject['class_name']))
73  return false;
74 
75  if (!empty($aObject['class_file']))
76  require_once(CH_DIRECTORY_PATH_ROOT . $aObject['class_file']);
77  else
78  ch_import($sClass);
79 
80  $o = new $sClass($aObject);
81 
82  return ($GLOBALS['chWsbClasses']['ChWsbSiteMaps!'.$sObject] = $o);
83  }
84 
88  static public function & getSystems () {
89  if (!isset($GLOBALS['ch_dol_site_maps_systems']))
90  $GLOBALS['ch_dol_site_maps_systems'] = ChWsbSiteMapsQuery::getAllActiveSystemsFromCache ();
91  return $GLOBALS['ch_dol_site_maps_systems'];
92  }
93 
97  static public function generateAllSiteMaps ()
98  {
99  if (!self::deleteAllSiteMaps ())
100  return false;
101 
102  if (!getParam('sys_sitemap_enable'))
103  return false;
104 
106  $aFiles = array ();
107  foreach ($aSystems as $sSystem => $aSystem) {
108  if (!($o = self::getObjectInstance($sSystem)))
109  continue;
110  $aFiles = array_merge($aFiles, $o->generate());
111  }
112  if (empty($aFiles))
113  return true;
114 
115  $sFileContents = '<' . '?xml version="1.0" encoding="UTF-8"?' . ">\n";
116  $sFileContents .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
117 
118  foreach ($aFiles as $sFile) {
119  $sFileContents .= "\t<sitemap>\n";
120  $sFileContents .= "\t\t<loc>" . self::_escape(self::$BASE_URL . $sFile) . "</loc>\n";
121  $sFileContents .= "\t\t<lastmod>" . self::_formatDate (time()) . "</lastmod>\n";
122  $sFileContents .= "\t</sitemap>\n";
123  }
124 
125  $sFileContents .= '</sitemapindex>';
126 
127  if (!file_put_contents (self::$BASE_PATH_INDEX . CH_SITE_MAPS_FILE_INDEX, $sFileContents))
128  return false;
129 
130  return true;
131  }
132 
136  static public function deleteAllSiteMaps ()
137  {
138  if (file_exists(self::$BASE_PATH_INDEX . CH_SITE_MAPS_FILE_INDEX) && false === file_put_contents(self::$BASE_PATH_INDEX . CH_SITE_MAPS_FILE_INDEX, ''))
139  return false;
140 
141  if (!($rHandler = opendir(self::$BASE_PATH)))
142  return false;
143 
144  $l = strlen(CH_SITE_MAPS_FILES_PREFIX);
145  while (($sFile = readdir($rHandler)) !== false)
146  if (0 === strncmp($sFile, CH_SITE_MAPS_FILES_PREFIX, $l) && file_exists(self::$BASE_PATH . $sFile))
147  @unlink (self::$BASE_PATH . $sFile);
148 
149  closedir($rHandler);
150 
151  return true;
152  }
153 
157  static public function getSiteMapIndexUrl ()
158  {
159  return self::$BASE_URL_INDEX . CH_SITE_MAPS_FILE_INDEX;
160  }
161 
165  static public function getSiteMapIndexPath ()
166  {
167  return self::$BASE_PATH_INDEX . CH_SITE_MAPS_FILE_INDEX;
168  }
169 
173  public function generate ()
174  {
175  if (!getParam('sys_sitemap_enable'))
176  return array ();
177 
178  $aFiles = array ();
179  $iStart = 0;
180  $iCount = $this->_getCount();
181  if (!$iCount)
182  return array ();
183 
184  do {
185 
186  $aRows = $this->_getRecords ($iStart);
187  if (empty($aRows))
188  break;
189 
190  $iFileIndex = round($iStart / CH_SITE_MAPS_URLS_PER_FILE);
191  $sFileName = CH_SITE_MAPS_FILES_PREFIX . $this->_aSystem['object'] . '_' . $iFileIndex . '.xml';
192  if (!($f = fopen (self::$BASE_PATH . $sFileName, 'w')))
193  break;
194 
195  fwrite($f, $this->_genXmlUrlsBegin ());
196  foreach ($aRows as $aRow)
197  fwrite($f, $this->_genXmlUrl ($aRow));
198  fwrite($f, $this->_genXmlUrlsEnd ());
199 
200  fclose($f);
201 
202  @chmod (self::$BASE_PATH . $sFileName, 0666);
203 
204  $aFiles[] = $sFileName;
205 
206  $iStart += CH_SITE_MAPS_URLS_PER_FILE;
207 
208  } while ($iStart < $iCount);
209 
210  return $aFiles;
211  }
212 
213  protected function _genXmlUrlsBegin ()
214  {
215  $s = '<' . '?xml version="1.0" encoding="UTF-8"?' . ">\n";
216  $s .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
217  return $s;
218  }
219 
220  protected function _genXmlUrlsEnd ()
221  {
222  return '</urlset>';
223  }
224 
225  protected function _genXmlUrl ($a)
226  {
227  $sUrl = $this->_genUrl($a);
228 
229  if (ChWsbRequest::serviceExists('pageac', 'is_url_accessable')) {
230  if (!ChWsbService::call('pageac', 'is_url_accessable', array($sUrl)))
231  return '';
232  }
233 
234  $s = "\t<url>\n";
235 
236  $s .= "\t\t<loc>" . $this->_escape($sUrl) . "</loc>\n";
237 
238  if (!empty($a[$this->_aQueryParts['field_date']]))
239  $s .= "\t\t<lastmod>" . $this->_genDate ($a) . "</lastmod>\n";
240 
241  if (!empty($this->_aSystem['changefreq']))
242  $s .= "\t\t<changefreq>" . $this->_genChangeFreq($a) . "</changefreq>\n";
243 
244  if (!empty($this->_aSystem['priority']))
245  $s .= "\t\t<priority>" . $this->_aSystem['priority'] . "</priority>\n";
246 
247  $s .= "\t</url>\n";
248 
249  return $s;
250  }
251 
252  protected function _genUrl ($a)
253  {
254  // override this
255  return '';
256  }
257 
258  protected function _genDate ($a)
259  {
260  return $this->_formatDate ($this->_getDateTimeStamp($a));
261  }
262 
263  protected function _genChangeFreq ($a)
264  {
265  if ('auto' != $this->_aSystem['changefreq'])
266  return $this->_aSystem['changefreq'];
267 
268  if (empty($a[$this->_aQueryParts['field_date']]))
269  return 'daily';
270 
271  // auto
272  $iTimestamp = abs(time() - $this->_getDateTimeStamp($a));
273  if ($iTimestamp < 2*86400) // less than 2 days
274  return 'hourly';
275  elseif ($iTimestamp < 14*86400) // less than 2 weeks
276  return 'daily';
277  elseif ($iTimestamp < 60*86400) // less than 2 months
278  return 'weekly';
279  else
280  return 'monthly';
281  }
282 
283  protected function _getCount ()
284  {
285  return $this->_oQuery->getCount($this->_aQueryParts);
286  }
287 
288  protected function _getRecords ($iStart)
289  {
290  return $this->_oQuery->getRecords($this->_aQueryParts, $iStart, CH_SITE_MAPS_URLS_PER_FILE);
291  }
292 
293  static protected function _formatDate ($iTimestamp)
294  {
295  return date('Y-m-d', $iTimestamp);
296  }
297 
298  protected function _getDateTimeStamp ($a)
299  {
300  if ('datetime' == $this->_aQueryParts['field_date_type'])
301  return 0 === strncmp('0000-00-00', $a[$this->_aQueryParts['field_date']], 10) ? time() : strtotime($a[$this->_aQueryParts['field_date']]);
302  else
303  return 0 == $this->_aQueryParts['field_date'] ? time() : $a[$this->_aQueryParts['field_date']];
304  }
305 
306  static protected function _escape ($s)
307  {
308  return htmlspecialchars ($s, ENT_COMPAT|ENT_HTML401, 'UTF-8');
309  }
310 }
ChWsbSiteMaps\getSiteMapIndexUrl
static getSiteMapIndexUrl()
Definition: ChWsbSiteMaps.php:157
ChWsbSiteMaps\$BASE_URL
static $BASE_URL
Definition: ChWsbSiteMaps.php:34
ChWsbSiteMaps\$_aSystem
$_aSystem
Definition: ChWsbSiteMaps.php:38
$f
global $f
Definition: callback.php:13
ChWsbRequest\serviceExists
static serviceExists($mixedModule, $sMethod, $sClass="Module")
Definition: ChWsbRequest.php:70
ChWsbSiteMaps\generate
generate()
Definition: ChWsbSiteMaps.php:173
$aSystems
$aSystems
Definition: cmts.php:20
ChWsbSiteMaps\_genDate
_genDate($a)
Definition: ChWsbSiteMaps.php:258
ChWsbSiteMaps\_getCount
_getCount()
Definition: ChWsbSiteMaps.php:283
ch_import
ch_import($sClassName, $aModule=array())
Definition: utils.inc.php:1218
$sUrl
$sUrl
Definition: cart.php:15
php
ChWsbSiteMaps\getSiteMapIndexPath
static getSiteMapIndexPath()
Definition: ChWsbSiteMaps.php:165
ChWsbSiteMaps\__construct
__construct($aSystem)
Definition: ChWsbSiteMaps.php:50
ChWsbSiteMaps\_genChangeFreq
_genChangeFreq($a)
Definition: ChWsbSiteMaps.php:263
ChWsbSiteMaps\_getDateTimeStamp
_getDateTimeStamp($a)
Definition: ChWsbSiteMaps.php:298
CH_SITE_MAPS_FILE_INDEX
const CH_SITE_MAPS_FILE_INDEX
Definition: ChWsbSiteMaps.php:12
$sFile
$sFile
Definition: index.php:20
getParam
getParam($sParamName, $bUseCache=true)
Definition: db.inc.php:130
ChWsbSiteMaps\_escape
static _escape($s)
Definition: ChWsbSiteMaps.php:306
ChWsbSiteMaps\getObjectInstance
static getObjectInstance($sObject)
Definition: ChWsbSiteMaps.php:61
CH_SITE_MAPS_URLS_PER_FILE
const CH_SITE_MAPS_URLS_PER_FILE
Definition: ChWsbSiteMaps.php:10
ChWsbSiteMaps\_getRecords
_getRecords($iStart)
Definition: ChWsbSiteMaps.php:288
ChWsbSiteMaps\$BASE_PATH
static $BASE_PATH
Definition: ChWsbSiteMaps.php:33
CH_SITE_MAPS_FILES_PREFIX
const CH_SITE_MAPS_FILES_PREFIX
Definition: ChWsbSiteMaps.php:11
ChWsbSiteMaps
Definition: ChWsbSiteMaps.php:32
time
that in the case of a Adaptation or at a minimum such credit will if a credit for all contributing authors of the Adaptation or Collection then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors For the avoidance of You may only use the credit required by this Section for the purpose of attribution in the manner set out above by exercising Your rights under this You may not implicitly or explicitly assert or imply any connection sponsorship or endorsement by the Original Licensor and or Attribution as of You or Your use of the without the express prior written permission of the Original Licensor and or Attribution Parties Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable if You Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or You must not modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author s honor or reputation Licensor agrees that in those in which any exercise of the right granted in modification or other derogatory action prejudicial to the Original Author s honor and the Licensor will waive or not as this to the fullest extent permitted by the applicable national to enable You to reasonably exercise Your right under Warranties and Disclaimer UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN LICENSOR OFFERS THE WORK AS IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE STATUTORY OR WITHOUT WARRANTIES OF FITNESS FOR A PARTICULAR OR THE ABSENCE OF LATENT OR OTHER OR THE PRESENCE OF ABSENCE OF WHETHER OR NOT DISCOVERABLE SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED SO SUCH EXCLUSION MAY NOT APPLY TO YOU Limitation on Liability EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES Termination This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License Individuals or entities who have received Adaptations or Collections from You under this will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses and will survive any termination of this License Subject to the above terms and the license granted here is Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time
Definition: license.txt:56
ChWsbSiteMapsQuery\getAllActiveSystemsFromCache
static getAllActiveSystemsFromCache()
Definition: ChWsbSiteMapsQuery.php:23
ChWsbSiteMaps\generateAllSiteMaps
static generateAllSiteMaps()
Definition: ChWsbSiteMaps.php:97
ChWsbSiteMaps\$_oQuery
$_oQuery
Definition: ChWsbSiteMaps.php:39
$s
$s
Definition: embed.php:13
ChWsbSiteMaps\$_aQueryParts
$_aQueryParts
Definition: ChWsbSiteMaps.php:40
ChWsbSiteMaps\_genXmlUrlsEnd
_genXmlUrlsEnd()
Definition: ChWsbSiteMaps.php:220
ChWsbSiteMaps\$BASE_URL_INDEX
static $BASE_URL_INDEX
Definition: ChWsbSiteMaps.php:36
ChWsbSiteMaps\_genUrl
_genUrl($a)
Definition: ChWsbSiteMaps.php:252
ChWsbSiteMapsQuery
Definition: ChWsbSiteMapsQuery.php:14
ChWsbSiteMaps\_genXmlUrl
_genXmlUrl($a)
Definition: ChWsbSiteMaps.php:225
ChWsbSiteMaps\$BASE_PATH_INDEX
static $BASE_PATH_INDEX
Definition: ChWsbSiteMaps.php:35
empty
Attr AllowedRel this is empty
Definition: Attr.AllowedRel.txt:7
$o
$o
Definition: cmd.php:193
ChWsbService\call
static call($mixed, $sMethod, $aParams=array(), $sClass='Module')
Definition: ChWsbService.php:32
ChWsbSiteMaps\_genXmlUrlsBegin
_genXmlUrlsBegin()
Definition: ChWsbSiteMaps.php:213
as
as
Definition: Filter.ExtractStyleBlocks.Escaping.txt:10
ChWsbSiteMaps\_formatDate
static _formatDate($iTimestamp)
Definition: ChWsbSiteMaps.php:293
$GLOBALS
$GLOBALS['iAdminPage']
Definition: advanced_settings.php:10
ChWsbSiteMaps\getSystems
static & getSystems()
Definition: ChWsbSiteMaps.php:88
ChWsbSiteMaps\deleteAllSiteMaps
static deleteAllSiteMaps()
Definition: ChWsbSiteMaps.php:136