/dmAdminPlugin/lib/sitemap/dmXmlSitemapGenerator.php

https://github.com/h16bit/diem · PHP · 211 lines · 164 code · 39 blank · 8 comment · 5 complexity · 8d214b56fba751a28c1505472b2b3f07 MD5 · raw file

  1. <?php
  2. class dmXmlSitemapGenerator extends dmConfigurable
  3. {
  4. protected
  5. $dispatcher,
  6. $filesystem,
  7. $i18n;
  8. public function __construct(sfEventDispatcher $dispatcher, dmFilesystem $filesystem, dmI18n $i18n, array $options)
  9. {
  10. $this->dispatcher = $dispatcher;
  11. $this->filesystem = $filesystem;
  12. $this->i18n = $i18n;
  13. $this->initialize($options);
  14. }
  15. /*
  16. * Generates a sitemap
  17. * and save it in fullPath
  18. */
  19. public function execute()
  20. {
  21. $this->checkBaseUrl();
  22. if($this->i18n->hasManyCultures())
  23. {
  24. $this->write('sitemap.xml', $this->getIndexXml($this->i18n->getCultures()));
  25. foreach($this->i18n->getCultures() as $culture)
  26. {
  27. $this->write('sitemap_'.$culture.'.xml', $this->getSitemapXml($culture));
  28. }
  29. }
  30. else
  31. {
  32. $this->write('sitemap.xml', $this->getSitemapXml($this->i18n->getCulture()));
  33. }
  34. $this->dispatcher->notify(new sfEvent($this, 'dm.sitemap.generated', array(
  35. 'dir' => $this->getOption('dir'),
  36. 'domain' => $this->getOption('domain'))
  37. ));
  38. }
  39. public function getDefaultOptions()
  40. {
  41. return array(
  42. 'dir' => sfConfig::get('sf_web_dir')
  43. );
  44. }
  45. public function getFiles()
  46. {
  47. $files = array($this->getOption('dir').'/sitemap.xml');
  48. if($this->i18n->hasManyCultures())
  49. {
  50. foreach($this->i18n->getCultures() as $culture)
  51. {
  52. $files[] = $this->getOption('dir').'/sitemap_'.$culture.'.xml';
  53. }
  54. }
  55. return $files;
  56. }
  57. public function delete()
  58. {
  59. $this->filesystem->unlink($this->getFiles());
  60. }
  61. protected function initialize(array $options)
  62. {
  63. $this->configure($options);
  64. }
  65. protected function getIndexXml(array $cultures)
  66. {
  67. return sprintf('<?xml version="1.0" encoding="UTF-8"?>
  68. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  69. %s
  70. </sitemapindex>
  71. ', $this->getIndexSitemaps($cultures));
  72. }
  73. protected function getIndexSitemaps(array $cultures)
  74. {
  75. $sitemaps = array();
  76. foreach($cultures as $culture)
  77. {
  78. $sitemaps[] = sprintf(' <sitemap>
  79. <loc>%s</loc>
  80. </sitemap>',
  81. $this->getOption('domain').'/sitemap_'.$culture.'.xml');
  82. }
  83. return implode("\n", $sitemaps);
  84. }
  85. protected function getSitemapXml($culture)
  86. {
  87. return sprintf('<?xml version="1.0" encoding="UTF-8"?>
  88. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  89. %s
  90. </urlset>',
  91. $this->getUrls($this->getPages($culture), $culture)
  92. );
  93. }
  94. /*
  95. * Wich pages should figure on sitemap ?
  96. * @return array of dmPage objects
  97. */
  98. protected function getPages($culture)
  99. {
  100. return dmDb::query('DmPage p')
  101. ->withI18n($culture)
  102. ->where('pTranslation.is_secure = ?', false)
  103. ->addWhere('pTranslation.is_active = ?', true)
  104. ->addWhere('p.module != ? OR ( p.action != ? AND p.action != ? AND p.action != ?)', array('main', 'error404', 'search', 'signin'))
  105. ->orderBy('p.lft asc')
  106. ->fetchRecords();
  107. }
  108. protected function getUrls(myDoctrineCollection $pages, $culture)
  109. {
  110. $urls = array();
  111. foreach($pages as $page)
  112. {
  113. $urls[] = $this->getUrl($page, $culture);
  114. }
  115. return implode("\n", $urls);
  116. }
  117. protected function getUrl(dmPage $page, $culture)
  118. {
  119. return sprintf(' <url>
  120. <loc>
  121. %s
  122. </loc>
  123. </url>', $this->getOption('domain').'/'.$page->get('Translation')->get($culture)->get('slug'));
  124. }
  125. protected function write($filePath, $xml)
  126. {
  127. $file = dmOs::join($this->getOption('dir'), $filePath);
  128. if(!file_put_contents($file, $xml))
  129. {
  130. throw new dmException('Can not save xml sitemap to '.dmProject::unRootify($file));
  131. }
  132. @$this->filesystem->chmod($file, 0666);
  133. }
  134. public function getUpdatedAt($file)
  135. {
  136. $this->checkFileExists($file);
  137. return filemtime($file);
  138. }
  139. public function countUrls($file)
  140. {
  141. $this->checkFileExists($file);
  142. return substr_count(file_get_contents($file), '<loc>');
  143. }
  144. public function getFileSize($file)
  145. {
  146. $this->checkFileExists($file);
  147. return round(filesize($file) / 1024, 2).' KB';
  148. }
  149. public function getWebPath($file)
  150. {
  151. $this->checkBaseUrl();
  152. return $this->getOption('domain').str_replace(sfConfig::get('sf_web_dir'), '', $file);
  153. }
  154. protected function checkFileExists($file = null)
  155. {
  156. $file = $file ? $file : $this->getOption('dir').'/sitemap.xml';
  157. if (!file_exists($file))
  158. {
  159. throw new dmException(sprintf('The sitemap file does not exists'));
  160. }
  161. }
  162. protected function checkBaseUrl()
  163. {
  164. if (!$this->getOption('domain'))
  165. {
  166. throw new dmException('You must give a domain option like www.my-domain.com');
  167. }
  168. }
  169. }
  170. class dmSitemapNotWritableException extends dmException
  171. {
  172. }