X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fmodules%2Fcontrib%2Fsimple_sitemap%2Fsrc%2FSitemapGenerator.php;fp=web%2Fmodules%2Fcontrib%2Fsimple_sitemap%2Fsrc%2FSitemapGenerator.php;h=ce1198faf773c311d357785f7f0598d1ebfa326d;hb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;hp=0000000000000000000000000000000000000000;hpb=57c063afa3f66b07c4bbddc2d6129a96d90f0aad;p=yaffs-website diff --git a/web/modules/contrib/simple_sitemap/src/SitemapGenerator.php b/web/modules/contrib/simple_sitemap/src/SitemapGenerator.php new file mode 100644 index 000000000..ce1198faf --- /dev/null +++ b/web/modules/contrib/simple_sitemap/src/SitemapGenerator.php @@ -0,0 +1,309 @@ +batch = $batch; + $this->entityHelper = $entityHelper; + $this->db = $database; + $this->moduleHandler = $module_handler; + $this->languageManager = $language_manager; + $this->setIsHreflangSitemap(); + } + + protected function setIsHreflangSitemap() { + $this->isHreflangSitemap = count($this->languageManager->getLanguages()) > 1; + } + + /** + * @return bool + */ + public function isHreflangSitemap() { + return $this->isHreflangSitemap; + } + + /** + * @param \Drupal\simple_sitemap\Simplesitemap $generator + * @return $this + */ + public function setGenerator(Simplesitemap $generator) { + $this->generator = $generator; + return $this; + } + + /** + * @param string $from + * @return $this + */ + public function setGenerateFrom($from) { + $this->generateFrom = $from; + return $this; + } + + /** + * Adds all operations to the batch and starts it. + */ + public function startGeneration() { + $this->batch->setBatchInfo([ + 'from' => $this->generateFrom, + 'batch_process_limit' => !empty($this->generator->getSetting('batch_process_limit')) + ? $this->generator->getSetting('batch_process_limit') : NULL, + 'max_links' => $this->generator->getSetting('max_links', 2000), + 'skip_untranslated' => $this->generator->getSetting('skip_untranslated', FALSE), + 'remove_duplicates' => $this->generator->getSetting('remove_duplicates', TRUE), + 'entity_types' => $this->generator->getBundleSettings(), + 'base_url' => $this->generator->getSetting('base_url', ''), + ]); + // Add custom link generating operation. + $this->batch->addOperation('generateCustomUrls', $this->getCustomUrlsData()); + + // Add entity link generating operations. + foreach ($this->getEntityTypeData() as $data) { + $this->batch->addOperation('generateBundleUrls', $data); + } + $this->batch->start(); + } + + /** + * Returns a batch-ready data array for custom link generation. + * + * @return array + * Data to be processed. + */ + protected function getCustomUrlsData() { + $paths = []; + foreach ($this->generator->getCustomLinks() as $i => $custom_path) { + $paths[$i]['path'] = $custom_path['path']; + $paths[$i]['priority'] = isset($custom_path['priority']) ? $custom_path['priority'] : NULL; + // todo: implement lastmod. + $paths[$i]['lastmod'] = NULL; + } + return $paths; + } + + /** + * Collects entity metadata for entities that are set to be indexed + * and returns an array of batch-ready data sets for entity link generation. + * + * @return array + */ + protected function getEntityTypeData() { + $data_sets = []; + $sitemap_entity_types = $this->entityHelper->getSitemapEntityTypes(); + $entity_types = $this->generator->getBundleSettings(); + foreach ($entity_types as $entity_type_name => $bundles) { + if (isset($sitemap_entity_types[$entity_type_name])) { + $keys = $sitemap_entity_types[$entity_type_name]->getKeys(); + + // Menu fix. + $keys['bundle'] = $entity_type_name == 'menu_link_content' ? 'menu_name' : $keys['bundle']; + + foreach ($bundles as $bundle_name => $bundle_settings) { + if ($bundle_settings['index']) { + $data_sets[] = [ + 'bundle_settings' => $bundle_settings, + 'bundle_name' => $bundle_name, + 'entity_type_name' => $entity_type_name, + 'keys' => $keys, + ]; + } + } + } + } + return $data_sets; + } + + /** + * Wrapper method which takes links along with their options, lets other + * modules alter the links and then generates and saves the sitemap. + * + * @param array $links + * All links with their multilingual versions and settings. + * @param bool $remove_sitemap + * Remove old sitemap from database before inserting the new one. + */ + public function generateSitemap(array $links, $remove_sitemap = FALSE) { + // Invoke alter hook. + $this->moduleHandler->alter('simple_sitemap_links', $links); + + $values = [ + 'id' => $remove_sitemap ? self::FIRST_CHUNK_INDEX + : $this->db->query('SELECT MAX(id) FROM {simple_sitemap}') + ->fetchField() + 1, + 'sitemap_string' => $this->generateSitemapChunk($links), + 'sitemap_created' => REQUEST_TIME, + ]; + if ($remove_sitemap) { + $this->db->truncate('simple_sitemap')->execute(); + } + $this->db->insert('simple_sitemap')->fields($values)->execute(); + } + + /** + * Generates and returns the sitemap index for all sitemap chunks. + * + * @param array $chunk_info + * Array containing chunk creation timestamps keyed by chunk ID. + * + * @return string sitemap index + */ + public function generateSitemapIndex(array $chunk_info) { + $writer = new XMLWriter(); + $writer->openMemory(); + $writer->setIndent(TRUE); + $writer->startDocument(self::XML_VERSION, self::ENCODING); + $writer->writeComment(self::GENERATED_BY); + $writer->startElement('sitemapindex'); + $writer->writeAttribute('xmlns', self::XMLNS); + + foreach ($chunk_info as $chunk_id => $chunk_data) { + $writer->startElement('sitemap'); + $writer->writeElement('loc', $this->getCustomBaseUrl() . '/sitemaps/' . $chunk_id . '/' . 'sitemap.xml'); + $writer->writeElement('lastmod', date_iso8601($chunk_data->sitemap_created)); + $writer->endElement(); + } + $writer->endElement(); + $writer->endDocument(); + return $writer->outputMemory(); + } + + public function getCustomBaseUrl() { + $customBaseUrl = $this->generator->getSetting('base_url', ''); + return !empty($customBaseUrl) ? $customBaseUrl : $GLOBALS['base_url']; + } + + /** + * Generates and returns a sitemap chunk. + * + * @param array $links + * All links with their multilingual versions and settings. + * + * @return string + * Sitemap chunk + */ + protected function generateSitemapChunk(array $links) { + $writer = new XMLWriter(); + $writer->openMemory(); + $writer->setIndent(TRUE); + $writer->startDocument(self::XML_VERSION, self::ENCODING); + $writer->writeComment(self::GENERATED_BY); + $writer->startElement('urlset'); + $writer->writeAttribute('xmlns', self::XMLNS); + + if ($this->isHreflangSitemap()) { + $writer->writeAttribute('xmlns:xhtml', self::XMLNS_XHTML); + } + + foreach ($links as $link) { + + // Add each translation variant URL as location to the sitemap. + $writer->startElement('url'); + $writer->writeElement('loc', $link['url']); + + // If more than one language is enabled, add all translation variant URLs + // as alternate links to this location turning the sitemap into a hreflang + // sitemap. + if ($this->isHreflangSitemap()) { + foreach ($link['alternate_urls'] as $language_id => $alternate_url) { + $writer->startElement('xhtml:link'); + $writer->writeAttribute('rel', 'alternate'); + $writer->writeAttribute('hreflang', $language_id); + $writer->writeAttribute('href', $alternate_url); + $writer->endElement(); + } + } + + // Add lastmod if any. + if (isset($link['lastmod'])) { + $writer->writeElement('lastmod', $link['lastmod']); + } + + //todo: Implement changefreq here. + + // Add priority if any. + if (isset($link['priority'])) { + $writer->writeElement('priority', $link['priority']); + } + + $writer->endElement(); + } + $writer->endElement(); + $writer->endDocument(); + return $writer->outputMemory(); + } + +}