diff --git a/code/GoogleSitemap.php b/code/GoogleSitemap.php
index 7d30ce3..d36f5af 100644
--- a/code/GoogleSitemap.php
+++ b/code/GoogleSitemap.php
@@ -26,11 +26,6 @@ class GoogleSitemap extends Controller {
*/
protected static $enabled = true;
- /**
- * @var DataObjectSet
- */
- protected $Pages;
-
/**
* @var boolean
*/
@@ -148,12 +143,12 @@ class GoogleSitemap extends Controller {
$filter = "{$bt}ShowInSearch{$bt} = 1";
}
- $this->Pages = Versioned::get_by_stage('SiteTree', 'Live', $filter);
-
+ $pages = Versioned::get_by_stage('SiteTree', 'Live', $filter);
+
$newPages = new DataObjectSet();
- if($this->Pages) {
- foreach($this->Pages as $page) {
+ if($pages) {
+ foreach($pages as $page) {
// Only include pages from this host and pages which are not an
// instance of ErrorPage. We prefix $_SERVER['HTTP_HOST'] with
// 'http://' so that parse_url to help parse_url identify the
@@ -182,10 +177,14 @@ class GoogleSitemap extends Controller {
/**
* Notifies Google about changes to your sitemap.
+ *
* Triggered automatically on every publish/unpublish of a page.
* This behaviour is disabled by default, enable with:
+ *
+ *
* GoogleSitemap::enable_google_notificaton();
- *
+ *
+ *
* If the site is in "dev-mode", no ping will be sent regardless wether
* the Google notification is enabled.
*
@@ -241,7 +240,7 @@ class GoogleSitemap extends Controller {
// But we want to still render.
return array();
} else {
- return new SS_HTTPResponse('Not allowed', 405);
+ return new SS_HTTPResponse('Page not found', 404);
}
}
@@ -261,5 +260,5 @@ class GoogleSitemap extends Controller {
*/
public static function disable() {
self::$enabled = false;
- }
+ }
}
diff --git a/code/GoogleSitemapDecorator.php b/code/GoogleSitemapDecorator.php
index 1d7aeaf..4e85382 100644
--- a/code/GoogleSitemapDecorator.php
+++ b/code/GoogleSitemapDecorator.php
@@ -15,124 +15,118 @@ class GoogleSitemapDecorator extends DataObjectDecorator {
*/
class GoogleSitemapSiteTreeDecorator extends SiteTreeDecorator {
- function extraStatics() {
- return array(
- 'db' => array(
- "Priority" => "Varchar(5)",
- )
- );
- }
+ function extraStatics() {
+ return array(
+ 'db' => array(
+ "Priority" => "Varchar(5)",
+ ),
+ );
+ }
- function updateCMSFields(&$fields) {
- $pagePriorities = array(
- '' => _t('SiteTree.PRIORITYAUTOSET', 'Auto-set based on page depth'),
- '-1' => _t('SiteTree.PRIORITYNOTINDEXED', "Not indexed"), // We set this to -ve one because a blank value implies auto-generation of Priority
- '1.0' => '1 - ' . _t('SiteTree.PRIORITYMOSTIMPORTANT', "Most important"),
- '0.9' => '2',
- '0.8' => '3',
- '0.7' => '4',
- '0.6' => '5',
- '0.5' => '6',
- '0.4' => '7',
- '0.3' => '8',
- '0.2' => '9',
- '0.1' => '10 - ' . _t('SiteTree.PRIORITYLEASTIMPORTANT', "Least important")
- );
+ function updateCMSFields(&$fields) {
+ $prorities = array(
+ '' => _t('SiteTree.PRIORITYAUTOSET', 'Auto-set based on page depth'),
+ '-1' => _t('SiteTree.PRIORITYNOTINDEXED', "Not indexed"), // We set this to -ve one because a blank value implies auto-generation of Priority
+ '1.0' => '1 - ' . _t('SiteTree.PRIORITYMOSTIMPORTANT', "Most important"),
+ '0.9' => '2',
+ '0.8' => '3',
+ '0.7' => '4',
+ '0.6' => '5',
+ '0.5' => '6',
+ '0.4' => '7',
+ '0.3' => '8',
+ '0.2' => '9',
+ '0.1' => '10 - ' . _t('SiteTree.PRIORITYLEASTIMPORTANT', "Least important")
+ );
- $tabset = $fields->findOrMakeTab('Root.Content');
- $tabset->push(
- $addTab = new Tab(
- 'GoogleSitemap',
- _t('SiteTree.TABGOOGLESITEMAP', 'Google Sitemap'),
- new LiteralField(
- "GoogleSitemapIntro",
- "
" . - sprintf( - _t( - 'SiteTree.METANOTEPRIORITY', "Manually specify a Google Sitemaps priority for this page (%s)" - ), '?' - ) . - "
" - ), - new DropdownField("Priority", $this->owner->fieldLabel('Priority'), $pagePriorities) - ) - ); - } + $tabset = $fields->findOrMakeTab('Root.Content'); + + $message = ""; + $message .= sprintf(_t('SiteTree.METANOTEPRIORITY', "Manually specify a Google Sitemaps priority for this page (%s)"), + '?' + ); + $message .= "
"; + + $tabset->push(new Tab('GoogleSitemap', _t('SiteTree.TABGOOGLESITEMAP', 'Google Sitemap'), + new LiteralField("GoogleSitemapIntro", $message), + new DropdownField("Priority", $this->owner->fieldLabel('Priority'), $prorities) + )); + } - function updateFieldLabels(&$labels) { - parent::updateFieldLabels($labels); + function updateFieldLabels(&$labels) { + parent::updateFieldLabels($labels); - $labels['Priority'] = _t('SiteTree.METAPAGEPRIO', "Page Priority"); - } + $labels['Priority'] = _t('SiteTree.METAPAGEPRIO', "Page Priority"); + } - function onAfterPublish() { - GoogleSitemap::ping(); - } + function onAfterPublish() { + GoogleSitemap::ping(); + } - function onAfterUnpublish() { - GoogleSitemap::ping(); - } + function onAfterUnpublish() { + GoogleSitemap::ping(); + } - /** - * The default value of the priority field depends on the depth of the page in - * the site tree, so it must be calculated dynamically. - */ - function getPriority() { - if (!$this->owner->getField('Priority')) { - $parentStack = $this->owner->parentStack(); - $numParents = is_array($parentStack) ? count($parentStack) - 1 : 0; - return max(0.1, 1.0 - ($numParents / 10)); - } elseif ($this->owner->getField('Priority') == -1) { - return 0; - } else { - return $this->owner->getField('Priority'); - } - } + /** + * The default value of the priority field depends on the depth of the page in + * the site tree, so it must be calculated dynamically. + * + * @return float + */ + function getPriority() { + if(!$this->owner->getField('Priority')) { + $parentStack = $this->owner->parentStack(); + $numParents = is_array($parentStack) ? count($parentStack) - 1 : 0; + + return max(0.1, 1.0 - ($numParents / 10)); + } + elseif ($this->owner->getField('Priority') == -1) { + return 0; + } + else { + $priority = abs($this->owner->getField('Priority')); + + return (is_float($priority) && $priority <= 1.0) ? $priority : 0.5; + } + } - /** - * Set a pages change frequency calculated by pages age and number of versions. - * Google expects always, hourly, daily, weekly, monthly, yearly or never as values. - * - * @return void - */ - public function setChangeFrequency() { - // The one field that isn't easy to deal with in the template is - // Change frequency, so we set that here. + /** + * Set a pages change frequency calculated by pages age and number of versions. + * Google expects always, hourly, daily, weekly, monthly, yearly or never as values. + * + * @return void + */ + public function setChangeFrequency() { + // The one field that isn't easy to deal with in the template is + // Change frequency, so we set that here. + $date = date('Y-m-d H:i:s'); - $date = date('Y-m-d H:i:s'); + $prop = $this->owner->toMap(); + $created = new SS_Datetime(); + $created->value = (isset($prop['Created'])) ? $prop['Created'] : $date; - $prop = $this->owner->toMap(); - $created = new SS_Datetime(); - $created->value = (isset($prop['Created'])) ? $prop['Created'] : $date; + $now = new SS_Datetime(); + $now->value = $date; + $versions = (isset($prop['Version'])) ? $prop['Version'] : 1; - $now = new SS_Datetime(); - $now->value = $date; - $versions = (isset($prop['Version'])) ? $prop['Version'] : 1; + $timediff = $now->format('U') - $created->format('U'); - $timediff = $now->format('U') - $created->format('U'); - - // Check how many revisions have been made over the lifetime of the - // Page for a rough estimate of it's changing frequency. - $period = $timediff / ($versions + 1); - - if ($period > 60 * 60 * 24 * 365) { - // > 1 year - $this->owner->ChangeFreq = 'yearly'; - } elseif ($period > 60 * 60 * 24 * 30) { - $this->owner->ChangeFreq = 'monthly'; - } elseif ($period > 60 * 60 * 24 * 7) { - // > 1 week - $this->owner->ChangeFreq = 'weekly'; - } elseif ($period > 60 * 60 * 24) { - // > 1 day - $this->owner->ChangeFreq = 'daily'; - } elseif ($period > 60 * 60) { - // > 1 hour - $this->owner->ChangeFreq = 'hourly'; - } else { - // < 1 hour - $this->owner->ChangeFreq = 'always'; - } - } + // Check how many revisions have been made over the lifetime of the + // Page for a rough estimate of it's changing frequency. + $period = $timediff / ($versions + 1); + if ($period > 60 * 60 * 24 * 365) { + $this->owner->ChangeFreq = 'yearly'; + } elseif ($period > 60 * 60 * 24 * 30) { + $this->owner->ChangeFreq = 'monthly'; + } elseif ($period > 60 * 60 * 24 * 7) { + $this->owner->ChangeFreq = 'weekly'; + } elseif ($period > 60 * 60 * 24) { + $this->owner->ChangeFreq = 'daily'; + } elseif ($period > 60 * 60) { + $this->owner->ChangeFreq = 'hourly'; + } else { + $this->owner->ChangeFreq = 'always'; + } + } } \ No newline at end of file diff --git a/tests/GoogleSitemapTest.php b/tests/GoogleSitemapTest.php index e50aabb..3d4d5df 100644 --- a/tests/GoogleSitemapTest.php +++ b/tests/GoogleSitemapTest.php @@ -1,20 +1,148 @@ - * @since 11.06.2011 + * @package googlesitemaps */ -class GoogleSitemapTest extends SapphireTest { - - public function testItems() { - //Publish a page and check if it returns - $obj = $this->objFromFixture("Page", "Page1"); - $page = DataObject::get_by_id("Page", $obj->ID); - #$page->publish(); - #$sitemap = new GoogleSitemap(); - #$this->assertEquals(1, $sitemap->Items()->Count()); - } +class GoogleSitemapTest extends FunctionalTest { + + public static $fixture_file = 'googlesitemaps/tests/GoogleSitemapTest.yml'; + + protected $extraDataObjects = array( + 'GoogleSitemapTest_DataObject', + 'GoogleSitemapTest_OtherDataObject', + 'GoogleSitemapTest_UnviewableDataObject' + ); + + function testItems() { + $page = $this->objFromFixture('Page', 'Page1'); + $page->publish('Stage', 'Live'); + $page->flushCache(); + + $page2 = $this->objFromFixture('Page', 'Page2'); + $page2->publish('Stage', 'Live'); + $page2->flushCache(); + + $sitemap = new GoogleSitemap(); + $this->assertDOSEquals(array( + array('Title' => 'Testpage1'), + array('Title' => 'Testpage2') + ), $sitemap->Items(), "There should be 2 pages in the sitemap after publishing"); + + // check if we make a page readonly that it is hidden + $page2->CanViewType = 'LoggedInUsers'; + $page2->write(); + $page2->publish('Stage', 'Live'); + + $this->session()->inst_set('loggedInAs', null); + + $this->assertDOSEquals(array( + array('Title' => 'Testpage1') + ), $sitemap->Items(), "There should be only 1 page, other is logged in only"); + + // register a DataObject and see if its aded to the sitemap + GoogleSitemap::register_dataobject("GoogleSitemapTest_DataObject", ''); + + // check to see if we have the GoogleSitemapTest_DataObject objects + $this->assertEquals(3, $sitemap->Items()->Count()); + + // register another dataobject + GoogleSitemap::register_dataobject("GoogleSitemapTest_OtherDataObject"); + $this->assertEquals(4, $sitemap->Items()->Count()); + + // check if we register objects that are unreadable they don't end up + // in the sitemap + GoogleSitemap::register_dataobject("GoogleSitemapTest_UnviewableDataObject"); + $this->assertEquals(4, $sitemap->Items()->Count()); + } + + function testAccess() { + GoogleSitemap::enable(); + + $response = $this->get('sitemap.xml'); + $this->assertEquals(200, $response->getStatusCode(), 'Sitemap returns a 200 success when enabled'); + $this->assertEquals('application/xml; charset="utf-8"', $response->getHeader('Content-Type')); + + GoogleSitemap::disable(); + + $response = $this->get('sitemap.xml'); + $this->assertEquals(404, $response->getStatusCode(), 'Sitemap returns a 404 when disabled'); + } + + function testDecoratorAddsFields() { + $page = $this->objFromFixture('Page', 'Page1'); + + $fields = $page->getCMSFields(); + + $tab = $fields->fieldByName('Root')->fieldByName('Content')->fieldByName('GoogleSitemap'); + + $this->assertInstanceOf('Tab', $tab); + $this->assertInstanceOf('DropdownField', $tab->fieldByName('Priority')); + $this->assertInstanceOf('LiteralField', $tab->fieldByName('GoogleSitemapIntro')); + } + + function testGetPriority() { + $page = $this->objFromFixture('Page', 'Page1'); + + // invalid field doesn't break google + $page->Priority = 'foo'; + $this->assertEquals(0.5, $page->getPriority()); + + // google doesn't like -1 but we use it to indicate the minimum + $page->Priority = -1; + $this->assertEquals(0, $page->getPriority()); + } } +/** + * @package googlesitemaps + */ +class GoogleSitemapTest_DataObject extends DataObject implements TestOnly { + + public static $db = array( + 'Priority' => 'Varchar(10)' + ); + + public function canView($member = null) { + return true; + } + + public function AbsoluteLink() { + return Director::baseURL(); + } +} + +/** + * @package googlesitemaps + */ +class GoogleSitemapTest_OtherDataObject extends DataObject implements TestOnly { + + public static $db = array( + 'Priority' => 'Varchar(10)' + ); + + public function canView($member = null) { + return true; + } + + public function AbsoluteLink() { + return Director::baseURL(); + } +} + +/** + * @package googlesitemaps + */ +class GoogleSitemapTest_UnviewableDataObject extends DataObject implements TestOnly { + + public static $db = array( + 'Priority' => 'Varchar(10)' + ); + + public function canView($member = null) { + return false; + } + + public function AbsoluteLink() { + return Director::baseURL(); + } +} diff --git a/tests/GoogleSitemapTest.yml b/tests/GoogleSitemapTest.yml index 2a997be..b628e3e 100644 --- a/tests/GoogleSitemapTest.yml +++ b/tests/GoogleSitemapTest.yml @@ -1,9 +1,20 @@ Page: Page1: + Title: Testpage1 + Priority: 0.2 Page2: - Page3: + Title: Testpage2 -DataObject: - DataObject1: - DataObject2: - DataObject3: +GoogleSitemapTest_DataObject: + DataObjectTest1: + Priority: 0.4 + DataObjectTest2: + Priority: 0.2 + +GoogleSitemapTest_OtherDataObject: + OtherDataObjectTest2: + Priority: 0.3 + +GoogleSitemapTest_UnviewableDataObject: + Unviewable1: + Priority: 0.4 \ No newline at end of file