Commit 7b5e53ae authored by gbyte.co's avatar gbyte.co

Now all is object-oriented and pseude aching implemented.

parent 5c497bd6
content_types: []
home:
custom:
home:
path: /
index: true
priority: 1
custom:
- contact:
path: contact
contact:
path: /contact
index: false
priority: 0.3
priority: 0.5
<?php
/**
* @file
* Main module file containing hooks.
*/
use Drupal\simplesitemap\Simplesitemap;
/**
* Implements hook_form_alter.
*/
function simplesitemap_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
if ($form_id == 'node_type_edit_form') {
$content_types = \Drupal::config('simplesitemap.settings')->get('content_types');
$sitemap = new Simplesitemap;
// Get current content type sitemap settings.
$content_types = $sitemap->get_content_types();
$form['simplesitemap'] = array(
'#group' => 'additional_settings',
......@@ -18,28 +30,52 @@ function simplesitemap_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $
'#default_value' => $index_content_checked,
);
$priority = isset($content_types[$form['type']['#default_value']]['priority']) ? $content_types[$form['type']['#default_value']]['priority'] : 0.5;
$priority = isset($content_types[$form['type']['#default_value']]['priority']) ? $content_types[$form['type']['#default_value']]['priority'] : $sitemap->get_priority_default();
$form['simplesitemap']['simplesitemap_priority'] = array(
'#type' => 'select',
'#title' => 'Priority',
'#options' => $sitemap->get_priority_select_values(),
'#default_value' => $priority,
'#description' => 'The priority nodes of this content type will have in the eyes of search engine bots.',
);
foreach(range(0, 10) as $value) {
$value = $value / 10;
$options[(string)$value] = (string)$value;
}
$form['simplesitemap']['simplesitemap_priority']['#options'] = $options;
// Add submission handler.
$form['actions']['submit']['#submit'][] = 'simplesitemap_bundle_form_submit';
}
}
/**
* Form submission handler callback.
*/
function simplesitemap_bundle_form_submit($form, &$form_state) {
$values = $form_state->getValues();
$config = \Drupal::service('config.factory')->getEditable('simplesitemap.settings');
$content_types = $config->get('content_types');
// Only make changes in DB if sitemap settings actually changed.
if ($form['simplesitemap']['simplesitemap_index_content']['#default_value'] != $form['simplesitemap']['simplesitemap_index_content']['#value'] || $form['simplesitemap']['simplesitemap_priority']['#default_value'] != $form['simplesitemap']['simplesitemap_priority']['#value']) {
$sitemap = new Simplesitemap;
// Get current content type sitemap settings.
$content_types = $sitemap->get_content_types();
$content_types[$form['type']['#default_value']]['index'] = $values['simplesitemap_index_content'];
$content_types[$form['type']['#default_value']]['priority'] = $values['simplesitemap_priority'];
$config->set('content_types', $content_types)->save();
// Save new content type settings.
$sitemap->set_content_types($content_types);
// Regenerate sitemaps for all languages and save them into strings for performance reason (pseudo caching).
$sitemap->generate_all_sitemaps();
}
}
/**
* Implements hook_cron.
*/
function simplesitemap_cron() {
// Regenerate sitemaps for all languages and save them into strings for performance reasons (pseudo caching).
$sitemap = new Simplesitemap;
$sitemap->generate_all_sitemaps();
}
simplesitemap.sitemap:
path: '/sitemap.xml'
defaults:
_controller: '\Drupal\simplesitemap\Controller\SimplesitemapController::generate_sitemap'
_title: 'XML Sitemap'
_controller: '\Drupal\simplesitemap\Controller\SimplesitemapController::get_sitemap'
requirements:
_permission: 'access content'
......@@ -7,7 +7,7 @@
namespace Drupal\simplesitemap\Controller;
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Url;
use Drupal\simplesitemap\Simplesitemap;
/**
* SimplesitemapController.
......@@ -15,54 +15,14 @@ use Drupal\Core\Url;
class SimplesitemapController {
/**
* Generates an example page.
* Generates the sitemap.
*/
public function generate_sitemap() {
public function get_sitemap() {
$config = \Drupal::config('simplesitemap.settings');
$output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
global $base_url;
$home = $config->get('home');
if ($home['index'])
$output .= "<url><loc>" . $base_url . "</loc><priority>" . $home['priority'] . "</priority></url>";
$custom = $config->get('custom');
foreach($custom as $page) {
if ($page['index'])
$output .= "<url><loc>" . $base_url . '/' . $page['path'] . "</loc><priority>" . $page['priority'] . "</priority></url>";
}
$content_types = $config->get('content_types');
if (count($content_types) > 0) {
//todo: D8 entityQuery doesn't seem to take multiple OR conditions, that's why that ugly db_select.
/* $query = \Drupal::entityQuery('node')
->condition('status', 1)
->condition('type', array_keys($content_types));
$nids = $query->execute();*/
$query = db_select('node_field_data', 'n')
->fields('n', array('nid', 'type'))
->condition('status', 1);
$db_or = db_or();
foreach($content_types as $machine_name => $options) {
if ($options['index'])
$db_or->condition('type', $machine_name);
}
$query->condition($db_or);
$nids = $query->execute()->fetchAllAssoc('nid');
foreach($nids as $nid => $node) {
$link_url = Url::fromRoute('entity.node.canonical', array('node' => $nid), array('absolute' => TRUE));
$output .= "<url><loc>" . $link_url->toString() . "</loc><priority>" . $content_types[$node->type]['priority'] . "</priority></url>";
}
}
$output .= "</urlset>";
$sitemap = new Simplesitemap;
$output = $sitemap->get_sitemap();
// Display sitemap with correct xml header.
return new Response($output, Response::HTTP_OK, array('content-type' => 'application/xml'));
}
}
<?php
/**
* @file
* Contains \Drupal\simplesitemap\Simplesitemap.
*/
namespace Drupal\simplesitemap;
use Drupal\Core\Url;
/**
* Simplesitemap class.
*/
class Simplesitemap {
private $config;
private $sitemap;
private $lang;
private $priority_default = 0.5;
function __construct() {
$this->set_current_lang();
$this->set_config();
}
private function set_current_lang() {
$this->lang = \Drupal::languageManager()->getCurrentLanguage();
}
private function set_config() {
$this->config = \Drupal::config('simplesitemap.settings');
$this->sitemap = $this->config->get('sitemap_' . $this->lang->getId());
}
private function save_sitemap() {
\Drupal::service('config.factory')->getEditable('simplesitemap.settings')->set('sitemap_' . $this->lang->getId(), $this->sitemap)->save();
$this->set_config();
}
private function add_xml_link_markup($url, $priority) {
return "<url><loc>" . $url . "</loc><priority>" . $priority . "</priority></url>";
}
private function generate_sitemap() {
$output = '';
$config = $this->config;
// Add custom links according to config file.
$custom = $config->get('custom');
foreach ($custom as $page) {
if ($page['index']) {
$output .= $this->add_xml_link_markup(Url::fromUserInput($page['path'], array('language' => $this->lang, 'absolute' => TRUE))->toString(), $page['priority']);
}
}
// Add node links according to content type settings.
$content_types = $config->get('content_types');
if (count($content_types) > 0) {
//todo: D8 entityQuery doesn't seem to take multiple OR conditions, that's why that ugly db_select.
// $query = \Drupal::entityQuery('node')
// ->condition('status', 1)
// ->condition('type', array_keys($content_types));
// $nids = $query->execute();
$query = db_select('node_field_data', 'n')
->fields('n', array('nid', 'type'))
->condition('status', 1);
$db_or = db_or();
foreach ($content_types as $machine_name => $options) {
if ($options['index']) {
$db_or->condition('type', $machine_name);
}
}
$query->condition($db_or);
$nids = $query->execute()->fetchAllAssoc('nid');
foreach ($nids as $nid => $node) {
$output .= $this->add_xml_link_markup(Url::fromRoute('entity.node.canonical', array('node' => $nid), array('language' => $this->lang, 'absolute' => TRUE))->toString(), $content_types[$node->type]['priority']);
}
}
// Add sitemap markup.
$output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">" . $output . "</urlset>";
$this->sitemap = $output;
$this->save_sitemap();
}
public function set_content_types($content_types) {
\Drupal::service('config.factory')->getEditable('simplesitemap.settings')->set('content_types', $content_types)->save();
$this->set_config();
}
public function get_content_types() {
return $this->config->get('content_types');
}
public function get_sitemap() {
if (empty($this->sitemap)) {
$this->generate_sitemap();
}
return $this->sitemap;
}
public function generate_all_sitemaps() {
foreach(\Drupal::languageManager()->getLanguages() as $language) {
$this->lang = $language;
$this->generate_sitemap();
}
}
public function get_priority_select_values() {
foreach(range(0, 10) as $value) {
$value = $value / 10;
$options[(string)$value] = (string)$value;
}
return $options;
}
public function get_priority_default() {
return $this->priority_default;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment