diff --git a/.travis.yml b/.travis.yml index 1dd623e..aaf07fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,12 +6,12 @@ php: env: - DB=MYSQL CORE_RELEASE=3.1 - - DB=MYSQL CORE_RELEASE=master + - DB=MYSQL CORE_RELEASE=3 matrix: include: - php: 5.4 - env: DB=MYSQL CORE_RELEASE=master + env: DB=MYSQL CORE_RELEASE=3 before_script: - git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support @@ -19,4 +19,4 @@ before_script: - cd ~/builds/ss script: - - phpunit docsviewer/tests/ \ No newline at end of file + - phpunit docsviewer/tests/ diff --git a/code/DocumentationManifest.php b/code/DocumentationManifest.php index c4245f8..cd8b279 100644 --- a/code/DocumentationManifest.php +++ b/code/DocumentationManifest.php @@ -54,6 +54,8 @@ class DocumentationManifest { */ protected $pages = array(); + protected $redirects = array(); + /** * @var DocumentationEntity */ @@ -224,7 +226,8 @@ class DocumentationManifest { */ protected function init() { if (!$this->forceRegen && $data = $this->cache->load($this->cacheKey)) { - $this->pages = $data; + $this->pages = $data['pages']; + $this->redirects = $data['redirects']; $this->inited = true; } else { $this->regenerate(); @@ -245,6 +248,14 @@ class DocumentationManifest { return $this->pages; } + public function getRedirects() { + if(!$this->inited) { + $this->init(); + } + + return $this->redirects; + } + /** * Returns a particular page for the requested URL. * @@ -275,6 +286,21 @@ class DocumentationManifest { } } + /** + * Get any redirect for the given url + * + * @param type $url + * @return string + */ + public function getRedirect($url) { + $pages = $this->getRedirects(); + $url = $this->normalizeUrl($url); + + if(isset($pages[$url])) { + return $pages[$url]; + } + } + /** * Regenerates the manifest by scanning the base path. * @@ -287,6 +313,7 @@ class DocumentationManifest { 'file_callback' => array($this, 'handleFile') )); + $this->redirects = array(); foreach($this->getEntities() as $entity) { $this->entity = $entity; @@ -328,12 +355,63 @@ class DocumentationManifest { } if ($cache) { - $this->cache->save($this->pages, $this->cacheKey); + $this->cache->save( + array( + 'pages' => $this->pages, + 'redirects' => $this->redirects + ), + $this->cacheKey + ); } $this->inited = true; } + /** + * Remove the link_base from the start of a link + * + * @param string $link + * @return string + */ + protected function stripLinkBase($link) { + return ltrim(str_replace( + Config::inst()->get('DocumentationViewer', 'link_base'), + '', + $link + ), '/'); + } + + /** + * + * @param DocumentationPage $page + * @param string $basename + * @param string $path + */ + protected function addPage($page, $basename, $path) { + $link = $this->stripLinkBase($page->Link()); + + $this->pages[$link] = array( + 'title' => $page->getTitle(), + 'basename' => $basename, + 'filepath' => $path, + 'type' => get_class($page), + 'entitypath' => $this->entity->getPath(), + 'summary' => $page->getSummary() + ); + } + + /** + * Add a redirect + * + * @param string $from + * @param string $to + */ + protected function addRedirect($from, $to) { + $fromLink = $this->stripLinkBase($from); + $toLink = $this->stripLinkBase($to); + $this->redirects[$fromLink] = $toLink; + } + /** * */ @@ -342,20 +420,15 @@ class DocumentationManifest { 'DocumentationFolder', $this->entity, $basename, $path ); - $link = ltrim(str_replace( - Config::inst()->get('DocumentationViewer', 'link_base'), - '', - $folder->Link() - ), '/'); + // Add main folder link + $fullLink = $folder->Link(); + $this->addPage($folder, $basename, $path); - $this->pages[$link] = array( - 'title' => $folder->getTitle(), - 'basename' => $basename, - 'filepath' => $path, - 'type' => 'DocumentationFolder', - 'entitypath' => $this->entity->getPath(), - 'summary' => '' - ); + // Add alternative link + $shortLink = $folder->Link(true); + if($shortLink != $fullLink) { + $this->addRedirect($shortLink, $fullLink); + } } /** @@ -379,20 +452,15 @@ class DocumentationManifest { // populate any meta data $page->getMarkdown(); - $link = ltrim(str_replace( - Config::inst()->get('DocumentationViewer', 'link_base'), - '', - $page->Link() - ), '/'); + // Add main link + $fullLink = $page->Link(); + $this->addPage($page, $basename, $path); - $this->pages[$link] = array( - 'title' => $page->getTitle(), - 'filepath' => $path, - 'entitypath' => $this->entity->getPath(), - 'basename' => $basename, - 'type' => 'DocumentationPage', - 'summary' => $page->getSummary() - ); + // If this is a stable version, add the short link + $shortLink = $page->Link(true); + if($fullLink != $shortLink) { + $this->addRedirect($shortLink, $fullLink); + } } /** diff --git a/code/controllers/DocumentationViewer.php b/code/controllers/DocumentationViewer.php index 91a156b..8aa36ae 100755 --- a/code/controllers/DocumentationViewer.php +++ b/code/controllers/DocumentationViewer.php @@ -247,6 +247,10 @@ class DocumentationViewer extends Controller { )); return new SS_HTTPResponse($body, 200); + } else if($redirect = $this->getManifest()->getRedirect($url)) { + $response = new SS_HTTPResponse(); + $to = Controller::join_links(Director::baseURL(), $base, $redirect); + return $response->redirect($to, 301); } else if(!$url || $url == $lang) { $body = $this->renderWith(array( "DocumentationViewer_DocumentationFolder", diff --git a/code/models/DocumentationEntity.php b/code/models/DocumentationEntity.php index d905e04..e57f284 100755 --- a/code/models/DocumentationEntity.php +++ b/code/models/DocumentationEntity.php @@ -112,9 +112,11 @@ class DocumentationEntity extends ViewableData { * * Includes the version information * + * @param boolean $short If true, will attempt to return a short version of the url + * This might omit the version number if this is the default version. * @return string */ - public function Link() { + public function Link($short = false) { if($this->getIsDefaultEntity()) { $base = Controller::join_links( Config::inst()->get('DocumentationViewer', 'link_base'), @@ -132,7 +134,7 @@ class DocumentationEntity extends ViewableData { $base = ltrim(str_replace('//', '/', $base), '/'); - if($this->stable) { + if($short && $this->stable) { return $base; } diff --git a/code/models/DocumentationPage.php b/code/models/DocumentationPage.php index 53aaea7..0bc208b 100755 --- a/code/models/DocumentationPage.php +++ b/code/models/DocumentationPage.php @@ -229,14 +229,13 @@ class DocumentationPage extends ViewableData { * Returns the URL that will be required for the user to hit to view the * given document base name. * - * @param string $file - * @param string $path - * + * @param boolean $short If true, will attempt to return a short version of the url + * This might omit the version number if this is the default version. * @return string */ - public function Link() { + public function Link($short = false) { return ltrim(Controller::join_links( - $this->entity->Link(), + $this->entity->Link($short), $this->getRelativeLink() ), '/'); } diff --git a/composer.json b/composer.json index 52ef414..40a3061 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ }], "require": { "silverstripe/framework": "~3.1", - "erusev/parsedown-extra": "0.2.2" + "erusev/parsedown-extra": "0.2.2", + "erusev/parsedown": "~1.1.0" }, "suggest": { "silverstripe/staticpublisher": "Allows publishing documentation as HTML" diff --git a/tests/DocumentationManifestTests.php b/tests/DocumentationManifestTests.php index 3ba3f57..1a76745 100644 --- a/tests/DocumentationManifestTests.php +++ b/tests/DocumentationManifestTests.php @@ -84,8 +84,8 @@ class DocumentationManifestTests extends SapphireTest { 'en/testdocs/2.3/subfolder/subsubfolder/', 'en/testdocs/2.3/subfolder/subsubfolder/subsubpage/', 'en/testdocs/2.3/test/', - 'en/testdocs/', - 'en/testdocs/test/', + 'en/testdocs/2.4/', + 'en/testdocs/2.4/test/', 'en/testdocs/3.0/', 'en/testdocs/3.0/changelog/', 'en/testdocs/3.0/tutorials/', diff --git a/tests/DocumentationViewerTest.php b/tests/DocumentationViewerTest.php index 1402442..de3c015 100755 --- a/tests/DocumentationViewerTest.php +++ b/tests/DocumentationViewerTest.php @@ -98,13 +98,13 @@ class DocumentationViewerTest extends FunctionalTest { // 2.4 is the stable release. Not in the URL - $response = $this->get('dev/docs/en/doc_test/'); + $response = $this->get('dev/docs/en/doc_test/2.4'); $this->assertEquals($response->getStatusCode(), 200, 'Existing base folder'); $this->assertContains('english test', $response->getBody(), 'Toplevel content page'); - // accessing 2.4 is redirects to the version without the version number. - $response = $this->get('dev/docs/en/doc_test/2.4/'); - $this->assertEquals($response->getStatusCode(), 404, 'Existing base folder redirects to without version'); + // accessing base redirects to the version with the version number. + $response = $this->get('dev/docs/en/doc_test/'); + $this->assertEquals($response->getStatusCode(), 301, 'Existing base folder redirects to with version'); $response = $this->get('dev/docs/en/doc_test/3.0/'); $this->assertEquals($response->getStatusCode(), 200, 'Existing base folder'); @@ -156,7 +156,7 @@ class DocumentationViewerTest extends FunctionalTest { $this->assertEquals($expected, $actual); - $response = $v->handleRequest(new SS_HTTPRequest('GET', 'en/doc_test/'), DataModel::inst()); + $response = $v->handleRequest(new SS_HTTPRequest('GET', 'en/doc_test/2.4/'), DataModel::inst()); $this->assertEquals('current', $v->getMenu()->first()->LinkingMode); // 2.4 stable release has 1 child page (not including index) @@ -164,14 +164,12 @@ class DocumentationViewerTest extends FunctionalTest { // menu should contain all the english entities $expected = array( - 'dev/docs/en/doc_test/' => 'Doc Test', + 'dev/docs/en/doc_test/2.4/' => 'Doc Test', 'dev/docs/en/documentationvieweraltmodule1/' => 'DocumentationViewerAltModule1', 'dev/docs/en/documentationvieweraltmodule2/' => 'DocumentationViewerAltModule2' ); - $this->assertEquals($expected, $v->getMenu()->map('Link', 'Title')); - - + $this->assertEquals($expected, $v->getMenu()->map('Link', 'Title')); }