Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better Sitemaps! #198

Merged
merged 1 commit into from Jul 7, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Expand Up @@ -25,7 +25,7 @@ Official website : http://www.ionizecms.com
### Contributors
* [İskender Totoğlu](http://www.altivebir.com.tr)
* Martin Wernstahl

* Bhagya Nirmaan Silva - [http://about.me/bhagyas](http://about.me/bhagyas)

### Installation

Expand Down Expand Up @@ -57,4 +57,10 @@ These instruction takes in account that this version is in developement.
* From Ionize 0.9.6
* Articles Tag : Change your <ion:article filter="title:!=''" > attributes from "title:!=''" to "title !=''" (remove ":")
* Articles Tag : Change <ion:article filter="type:='your_type'"> to <ion:article type="your_type" >
* Navigation Tag : Add the "level" attribute : <ion:navigation level="0" />
* Navigation Tag : Add the "level" attribute : <ion:navigation level="0" />

###Updates
* 08 December 2014
* Added support for multilingual sitemap generation.
* Sitemaps no longer add offline pages.

7 changes: 7 additions & 0 deletions application/config/sitemaps.php 100644 → 100755
Expand Up @@ -69,6 +69,13 @@
"xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\n\t\t\t " .
"http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\">";

$config['sitemaps_multilingual_header'] = "<\x3Fxml version=\"1.0\" encoding=\"UTF-8\"\x3F>\n" .
"<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n\t" .
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t" .
"xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\n\t\t\t " .
"http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">";


$config['sitemaps_footer'] = "</urlset>\n";

/*
Expand Down
2 changes: 1 addition & 1 deletion application/controllers/admin/system_check.php
Expand Up @@ -354,7 +354,7 @@ public function check_views()
*/
public function rebuild_sitemap()
{
$this->structure->build_sitemap(TRUE);
$this->structure->build_multilingual_sitemap(TRUE);

$result = array(
'title' => lang('ionize_title_rebuild_sitemap_done'),
Expand Down
82 changes: 82 additions & 0 deletions application/libraries/Sitemaps.php
Expand Up @@ -115,6 +115,88 @@ function build($file_name = null, $gzip = NULL)
}
}

/**
* Generates a multilingual sitemap XML data
*
* @param string $file_name (optional) if file name is supplied the XML data is saved in it otherwise returned as a string
* @param bool $gzip (optional) compress sitemap, overwrites config item 'sitemaps_gzip'
* @access public
* @return string
*/
function build_multilingual($file_name = null, $gzip = NULL)
{
$CI =& get_instance();
$map = $CI->config->item('sitemaps_multilingual_header') . "\n";

foreach($this->items as $item)
{
$item['loc'] = htmlentities($item['loc'], ENT_QUOTES);
$map .= "\t<url>\n\t\t<loc>" . $item['loc'] . "</loc>\n";

$attributes = array("lastmod", "changefreq", "priority");

foreach($attributes AS $attr)
{
if(isset($item[$attr]))
{
$map .= "\t\t<$attr>" . $item[$attr] . "</$attr>\n";
}
}

if(isset($item['alternative_urls'])){
foreach($item['alternative_urls'] as $hrefllang => $alternative_url)
$map .= "\t\t<xhtml:link rel=\"alternate\" hreflang=\"$hrefllang\" href=\"$alternative_url\"/>\n";
}

$loc = $item['loc'];
$lang = $item['lang'];
$map .= "\t\t<xhtml:link rel=\"alternate\" hreflang=\"$lang\" href=\"$loc\"/>\n";

$map .= "\t</url>\n\n";
}

unset($this->items);

$map .= $CI->config->item('sitemaps_footer');

if( ! is_null($file_name))
{
$fh = @fopen($file_name, 'w');

if ($fh !== FALSE )
{
fwrite($fh, $map);
fclose($fh);

if($CI->config->item('sitemaps_filesize_error') && filesize($file_name) > 1024 * 1024 * 10)
{
show_error('Your sitemap is bigger than 10MB, most search engines will not accept it.');
}

if($gzip OR (is_null($gzip) && $CI->config->item('sitemaps_gzip')))
{
$gzdata = gzencode($map, 9);
$file_gzip = str_replace("{file_name}", $file_name, $CI->config->item('sitemaps_gzip_path'));
$fp = fopen($file_gzip, "w");
fwrite($fp, $gzdata);
fclose($fp);

// Delete the uncompressed sitemap
unlink($file_name);

return $file_gzip;
}

return $file_name;
}
return FALSE;
}
else
{
return $map;
}
}

/**
* Generate a sitemap index file pointing to other sitemaps you previously built
*
Expand Down
82 changes: 82 additions & 0 deletions application/libraries/Structure.php
Expand Up @@ -401,4 +401,86 @@ function build_sitemap($force = FALSE)
);
}
}

/**
* Multilingual Sitemap build
* Author: Bhagya Silva (http://www.about.me/bhagyas)
* Uses the lib : http://signalkraft.com/sitemaps-for-codeigniter
* @param bool $force
*/
function build_multilingual_sitemap($force = FALSE)
{
$ci =& get_instance();

$ci->config->load('sitemaps');
$ci->load->model('notification_model', '', TRUE);

$auto_create = config_item('sitemaps_auto_create');

if ($auto_create OR $force)
{
$ci->load->library('sitemaps');
$ci->load->model('sitemap_model', '', TRUE);

$get_all_lang = FALSE;

$langs = Settings::get_online_languages();

if (Settings::get('force_lang_urls') OR count($langs) > 1)
$get_all_lang = TRUE;

$urls = $ci->sitemap_model->get_multilingual_urls();

$multilingual_urls = array();

//iterate every url and build a map based on the key
foreach($urls as $url){
$url['date'] = $url['created'];
if (strtotime($url['updated']) > strtotime($url['date'])) $url['date'] = $url['updated'];
if (strtotime($url['publish_on']) > strtotime($url['date'])) $url['date'] = $url['publish_on'];
if (strtotime($url['logical_date']) > strtotime($url['date'])) $url['date'] = $url['logical_date'];

$loc = $get_all_lang == TRUE ? base_url() . $url['lang'] . '/' .$url['path'] : base_url() .$url['path'];

$alternative_urls = array();

foreach($urls as $other_url){
if($other_url['lang'] != $url['lang'] && $other_url['id_'] == $url['id_']){
$other_loc = $get_all_lang == TRUE ? base_url() . $other_url['lang'] . '/' .$other_url['path'] : base_url() .$other_url['path'];
$other_lang = $other_url['lang'];
$alternative_urls[$other_lang] = $other_loc;
}
}

$item = array(
'loc' => $loc,
'lang' => $url['lang'],
'lastmod' => date("c", strtotime($url['date'])),
'changefreq' => 'weekly',
'priority' => number_format(($url['priority'] / 10), 1,'.',''),
'alternative_urls' => $alternative_urls
);
array_push($multilingual_urls, $url['id_'], $item);
$ci->sitemaps->add_item($item);
}

$ci->sitemaps->build_multilingual('sitemap.xml');

// Set notifications as read
$ci->notification_model->set_code_as_read('sitemap_refresh');
}
else
{

// Create one notification : The sitemap should be rebuild !
$ci->notification_model->create_notification(
lang('ionize_notification_title_sitemap_refresh'),
lang('ionize_notification_message_sitemap_refresh'),
'sitemap_refresh',
'System',
TRUE
);
}
}

}
74 changes: 74 additions & 0 deletions application/models/sitemap_model.php
Expand Up @@ -165,4 +165,78 @@ public function get_urls()

return $data;
}

public function get_multilingual_urls()
{
$get_all_lang = FALSE;

$langs = Settings::get_online_languages();

if (Settings::get('force_lang_urls') OR count($langs) > 1)
$get_all_lang = TRUE;

$sql ="
select
u.id_entity as id_,
u.lang,
u.path,
p.priority,
p.created,
p.updated,
p.publish_on,
p.publish_off,
p.logical_date
from url u
inner join page p on p.id_page = u.id_entity and p.has_url = 1
inner join lang l on u.lang = l.lang and l.online = 1
where
u.type = 'page'
and u.active = 1
and u.canonical = 1
and p.priority > 0
and p.online = 1
and (p.publish_off = '0000-00-00 00:00:00' OR p.publish_off > now())
";

if ( ! $get_all_lang)
$sql .= "
and u.lang='".Settings::get_lang('default')."'
";

$sql .="
union

select
a.id_article as id_,
u.lang,
u.path,
a.priority,
a.created,
a.updated,
a.publish_on,
a.publish_off,
a.logical_date
from url u
inner join article_lang al on al.id_article= u.id_entity and al.lang=u.lang and al.online=1
inner join article a on a.id_article = al.id_article
where
u.type = 'article'
and u.active = 1
and u.canonical = 1
and a.indexed = 1
and a.priority > 0
and (a.publish_off = '0000-00-00 00:00:00' OR a.publish_off > now())
";

if ( ! $get_all_lang)
$sql .= "
and u.lang='".Settings::get_lang('default')."'
";

$query = $this->{$this->db_group}->query($sql);

$data = $query->result_array();

return $data;
}
}