mirror of
https://github.com/silverstripe/silverstripe-docsviewer
synced 2024-10-22 11:05:56 +02:00
ENHANCEMENT: cleaned up logic around Link() and Path() attributes throughout. FEATURE: added search pagination and rough templates for the search results
This commit is contained in:
parent
fede2626fc
commit
842043a8e3
@ -205,26 +205,45 @@ class DocumentationEntity extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the absolute path to this documentation entity.
|
||||
* Return the absolute path to this documentation entity on the
|
||||
* filesystem
|
||||
*
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
public function getPath($version = false, $lang = false) {
|
||||
|
||||
if(!$version) $version = '';
|
||||
if(!$lang) $lang = 'en';
|
||||
|
||||
// Get version, or fall back to first available
|
||||
if($this->hasVersion($version)) {
|
||||
$path = $this->versions[$version];
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$versions = $this->getVersions();
|
||||
$path = $this->versions[$versions[0]];
|
||||
}
|
||||
|
||||
$path = $this->versions[$versions[0]];
|
||||
}
|
||||
|
||||
return rtrim($path, '/') . '/' . rtrim($lang, '/') .'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the web accessible link to this Entity
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Link($version = false, $lang = false) {
|
||||
if(!$version) $version = '';
|
||||
if(!$lang) $lang = 'en';
|
||||
|
||||
return Controller::join_links(
|
||||
Director::absoluteBaseURL(),
|
||||
DocumentationViewer::get_link_base(),
|
||||
$version,
|
||||
$lang,
|
||||
$this->moduleFolder
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -14,10 +14,12 @@ class DocumentationPage extends ViewableData {
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* Stores the relative path (from the {@link DocumentationEntity} to
|
||||
* this page. The actual file name can be accessed via {@link $this->getFilename()}
|
||||
*
|
||||
* @var String
|
||||
*/
|
||||
protected $relativePath;
|
||||
protected $fullPath; // needed for the search
|
||||
|
||||
/**
|
||||
* @var String
|
||||
@ -73,49 +75,54 @@ class DocumentationPage extends ViewableData {
|
||||
* @return string
|
||||
*/
|
||||
function getPath($defaultFile = false) {
|
||||
if($this->fullPath) {
|
||||
$path = $this->fullPath;
|
||||
}
|
||||
elseif($this->entity) {
|
||||
$path = realpath(rtrim($this->entity->getPath($this->version, $this->lang), '/') . '/' . trim($this->getRelativePath(), '/'));
|
||||
if($this->entity) {
|
||||
$path = rtrim($this->entity->getPath($this->version, $this->lang), '/') . '/' . trim($this->getRelativePath(), '/');
|
||||
|
||||
if(!is_dir($path)) $path = realpath($path);
|
||||
else if($defaultFile) {
|
||||
$file = DocumentationService::find_page($this->entity, explode('/', $this->getRelativePath()));
|
||||
|
||||
if($file) $path = $file;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$path = $this->relativePath;
|
||||
}
|
||||
|
||||
if(!is_dir($path)) return $path;
|
||||
|
||||
if($defaultFile && ($entity = $this->getEntity())) {
|
||||
if($relative = $this->getRelativePath()) {
|
||||
return DocumentationService::find_page($entity, explode($relative, '/'));
|
||||
}
|
||||
else {
|
||||
$parts = str_replace($entity->getPath($this->version, $this->lang), '', $this->fullPath);
|
||||
|
||||
return DocumentationService::find_page($entity, explode($parts, '/'));
|
||||
}
|
||||
$path = $this->getRelativePath();
|
||||
}
|
||||
|
||||
if(!file_exists($path)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Path could not be found. Module path: %s, file path: %s',
|
||||
$this->entity->getPath(),
|
||||
$this->relativePath
|
||||
$this->getRelativePath()
|
||||
));
|
||||
}
|
||||
|
||||
return $path;
|
||||
|
||||
return (is_dir($path)) ? rtrim($path, '/') . '/' : $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the link for the webbrowser
|
||||
* Returns the link for the web browser
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getLink() {
|
||||
$web = Director::absoluteBaseUrl() . DocumentationViewer::get_link_base();
|
||||
|
||||
return (str_replace(BASE_PATH, $web , $this->getPath(true)));
|
||||
function Link() {
|
||||
if($entity = $this->getEntity()) {
|
||||
$link = Controller::join_links($entity->Link($this->version, $this->lang), $this->getRelativePath());
|
||||
|
||||
$link = rtrim(DocumentationService::trim_extension_off($link), '/');
|
||||
|
||||
// folders should have a / on them. Looks nicer
|
||||
try {
|
||||
if(is_dir($this->getPath())) $link .= '/';
|
||||
}
|
||||
catch (Exception $e) {}
|
||||
}
|
||||
else {
|
||||
$link = $this->getPath(true);
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
function setFullPath($path) {
|
||||
@ -147,10 +154,17 @@ class DocumentationPage extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @return string
|
||||
*/
|
||||
function isFolder() {
|
||||
return (is_dir($this->getPath()));
|
||||
function getFilename() {
|
||||
$path = rtrim($this->relativePath, '/');
|
||||
|
||||
try {
|
||||
return (is_dir($this->getPath())) ? $path . '/' : $path;
|
||||
}
|
||||
catch (Exception $e) {}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,6 +12,8 @@ class DocumentationSearch {
|
||||
|
||||
private static $enabled = false;
|
||||
|
||||
private $query;
|
||||
|
||||
private $results;
|
||||
|
||||
private $totalResults;
|
||||
@ -103,33 +105,121 @@ class DocumentationSearch {
|
||||
* Rebuilds the index if it out of date
|
||||
*/
|
||||
public function performSearch($query) {
|
||||
$this->query = $query;
|
||||
|
||||
$index = Zend_Search_Lucene::open(self::get_index_location());
|
||||
|
||||
Zend_Search_Lucene::setResultSetLimit(200);
|
||||
|
||||
$results = $index->find($query);
|
||||
|
||||
$this->results = new DataObjectSet();
|
||||
$this->results = $index->find($query);
|
||||
$this->totalResults = $index->numDocs();
|
||||
|
||||
foreach($results as $result) {
|
||||
$data = $result->getDocument();
|
||||
|
||||
$this->results->push(new ArrayData(array(
|
||||
'Title' => DBField::create('Varchar', $data->Title),
|
||||
'Link' => DBField::create('Varchar',$data->Link),
|
||||
'Language' => DBField::create('Varchar',$data->Language),
|
||||
'Version' => DBField::create('Varchar',$data->Version),
|
||||
'Content' => DBField::create('Text', $data->content)
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DataObjectSet
|
||||
*/
|
||||
public function getResults($start) {
|
||||
return $this->results;
|
||||
public function getDataArrayFromHits($start) {
|
||||
$data = array(
|
||||
'Results' => null,
|
||||
'Query' => null,
|
||||
'Title' => _t('DocumentationSearch.SEARCHRESULTS', 'Search Results'),
|
||||
'TotalResults' => null,
|
||||
'TotalPages' => null,
|
||||
'ThisPage' => null,
|
||||
'StartResult' => null,
|
||||
'EndResult' => null,
|
||||
'PrevUrl' => DBField::create('Text', 'false'),
|
||||
'NextUrl' => DBField::create('Text', 'false'),
|
||||
'SearchPages' => new DataObjectSet()
|
||||
);
|
||||
|
||||
$pageLength = 10;
|
||||
$currentPage = floor( $start / $pageLength ) + 1;
|
||||
|
||||
$totalPages = ceil(count($this->results) / $pageLength );
|
||||
|
||||
if ($totalPages == 0) $totalPages = 1;
|
||||
if ($currentPage > $totalPages) $currentPage = $totalPages;
|
||||
|
||||
$results = new DataObjectSet();
|
||||
|
||||
foreach($this->results as $k => $hit) {
|
||||
if($k < ($currentPage-1)*$pageLength || $k >= ($currentPage*$pageLength)) continue;
|
||||
|
||||
$doc = $hit->getDocument();
|
||||
|
||||
$content = $hit->content;
|
||||
|
||||
// do a simple markdown parse of the file
|
||||
$obj = new ArrayData(array(
|
||||
'Title' => DBField::create('Varchar', $doc->getFieldValue('Title')),
|
||||
'Link' => DBField::create('Varchar',$doc->getFieldValue('Link')),
|
||||
'Language' => DBField::create('Varchar',$doc->getFieldValue('Language')),
|
||||
'Version' => DBField::create('Varchar',$doc->getFieldValue('Version')),
|
||||
'Content' => DBField::create('HTMLText', $content),
|
||||
'Score' => $hit->score,
|
||||
'Number' => $k + 1
|
||||
));
|
||||
|
||||
$results->push($obj);
|
||||
}
|
||||
|
||||
$data['Results'] = $results;
|
||||
$data['Query'] = DBField::create('Text', $this->query);
|
||||
$data['TotalResults'] = DBField::create('Text', count($this->results));
|
||||
$data['TotalPages'] = DBField::create('Text', $totalPages);
|
||||
$data['ThisPage'] = DBField::create('Text', $currentPage);
|
||||
$data['StartResult'] = $start + 1;
|
||||
$data['EndResult'] = $start + count($results);
|
||||
|
||||
// Pagination links
|
||||
if($currentPage > 1) {
|
||||
$data['PrevUrl'] = DBField::create('Text',
|
||||
$this->buildQueryUrl(array('start' => ($currentPage - 2) * $pageLength))
|
||||
);
|
||||
}
|
||||
|
||||
if($currentPage < $totalPages) {
|
||||
$data['NextUrl'] = DBField::create('Text',
|
||||
$this->buildQueryUrl(array('start' => $currentPage * $pageLength))
|
||||
);
|
||||
}
|
||||
|
||||
if($totalPages > 1) {
|
||||
// Always show a certain number of pages at the start
|
||||
for ( $i = 1; $i <= $totalPages; $i++ ) {
|
||||
$obj = new DataObject();
|
||||
$obj->IsEllipsis = false;
|
||||
$obj->PageNumber = $i;
|
||||
$obj->Link = $this->buildQueryUrl(array(
|
||||
'start' => ($i - 1) * $pageLength
|
||||
));
|
||||
|
||||
$obj->Current = false;
|
||||
if ( $i == $currentPage ) $obj->Current = true;
|
||||
$data['SearchPages']->push($obj);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function buildQueryUrl($params) {
|
||||
$url = parse_url($_SERVER['REQUEST_URI']);
|
||||
if ( ! array_key_exists('query', $url) ) $url['query'] = '';
|
||||
parse_str($url['query'], $url['query']);
|
||||
if ( ! is_array($url['query']) ) $url['query'] = array();
|
||||
// Remove 'start parameter if it exists
|
||||
if ( array_key_exists('start', $url['query']) ) unset( $url['query']['start'] );
|
||||
// Add extra parameters from argument
|
||||
$url['query'] = array_merge($url['query'], $params);
|
||||
$url['query'] = http_build_query($url['query']);
|
||||
$url = $url['path'] . ($url['query'] ? '?'.$url['query'] : '');
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -255,6 +255,10 @@ class DocumentationService {
|
||||
* @param Float $version Version of module.
|
||||
* @param String $title Nice title to use
|
||||
* @param bool $major is this a major release
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return DocumentationEntity
|
||||
*/
|
||||
public static function register($module, $path, $version = '', $title = false, $major = false) {
|
||||
if(!file_exists($path)) throw new InvalidArgumentException(sprintf('Path "%s" doesn\'t exist', $path));
|
||||
@ -270,7 +274,7 @@ class DocumentationService {
|
||||
// module exists so add the version to it
|
||||
$entity = self::$registered_modules[$module];
|
||||
|
||||
$entity->addVersion($version, $path);
|
||||
$entity->addVersion($version, $path, true);
|
||||
}
|
||||
|
||||
if($major) {
|
||||
@ -280,6 +284,8 @@ class DocumentationService {
|
||||
self::$major_versions[] = $version;
|
||||
}
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -450,6 +456,16 @@ class DocumentationService {
|
||||
// remove extension
|
||||
$name = self::trim_extension_off($name);
|
||||
|
||||
// if it starts with a number strip and contains a space strip it off
|
||||
if(strpos($name, ' ') !== false) {
|
||||
$space = strpos($name, ' ');
|
||||
$short = substr($name, 0, $space);
|
||||
|
||||
if(is_numeric($short)) {
|
||||
$name = substr($name, $space);
|
||||
}
|
||||
}
|
||||
|
||||
// convert first letter
|
||||
return ucfirst(trim($name));
|
||||
}
|
||||
@ -465,7 +481,13 @@ class DocumentationService {
|
||||
$hasExtension = strrpos($name, '.');
|
||||
|
||||
if($hasExtension !== false && $hasExtension > 0) {
|
||||
$name = substr($name, 0, $hasExtension);
|
||||
$shorted = substr($name, $hasExtension);
|
||||
|
||||
// can remove the extension only if we know how
|
||||
// to read it again
|
||||
if(in_array(rtrim($shorted, '/'), self::get_valid_extensions())) {
|
||||
$name = substr($name, 0, $hasExtension);
|
||||
}
|
||||
}
|
||||
|
||||
return $name;
|
||||
@ -476,61 +498,60 @@ class DocumentationService {
|
||||
* Return the children from a given module sorted by Title using natural ordering.
|
||||
* It is used for building the tree of the page.
|
||||
*
|
||||
* @param string|DocumentationEntity path
|
||||
* @param DocumentationEntity path
|
||||
* @param string - an optional path within a module
|
||||
* @param bool enable several recursive calls (more than 1 level)
|
||||
*
|
||||
* @throws Exception
|
||||
* @return DataObjectSet
|
||||
*/
|
||||
public static function get_pages_from_folder($module, $recursive = true) {
|
||||
public static function get_pages_from_folder($module, $relativePath = false, $recursive = true) {
|
||||
// var_dump("START: get pages from $module | $relativePath");
|
||||
$output = new DataObjectSet();
|
||||
|
||||
$pages = array();
|
||||
if($module instanceof DocumentationEntity) {
|
||||
if(self::is_registered_module($module)) {
|
||||
self::get_pages_from_folder_recursive($module->getPath(), $module, $recursive, $pages);
|
||||
}
|
||||
else {
|
||||
return user_error("$module is not registered", E_USER_WARNING);
|
||||
}
|
||||
if(!$module instanceof DocumentationEntity) user_error("get_pages_from_folder must be passed a module", E_USER_ERROR);
|
||||
|
||||
if(self::is_registered_module($module)) {
|
||||
self::get_pages_from_folder_recursive($module->getPath(), $relativePath, $recursive, $pages);
|
||||
}
|
||||
else {
|
||||
self::get_pages_from_folder_recursive($module, false, $recursive, $pages);
|
||||
return user_error("$module is not registered", E_USER_WARNING);
|
||||
}
|
||||
|
||||
if(count($pages) > 0) {
|
||||
natsort($pages);
|
||||
|
||||
foreach($pages as $key => $path) {
|
||||
|
||||
// get file name from the path
|
||||
$file = ($pos = strrpos($path, '/')) ? substr($path, $pos + 1) : $path;
|
||||
|
||||
// trim off the extension
|
||||
|
||||
$page = new DocumentationPage();
|
||||
$page->setTitle(self::clean_page_name($file));
|
||||
$page->setFullPath($path);
|
||||
|
||||
$page->Filename = self::trim_extension_off($file);
|
||||
|
||||
if($module instanceof DocumentationEntity) {
|
||||
$page->setEntity($module);
|
||||
}
|
||||
|
||||
$relative = str_replace($module->getPath(), '', $path);
|
||||
|
||||
$page->setEntity($module);
|
||||
$page->setRelativePath($relative);
|
||||
// var_dump("ADDING FILE: ". $relative . " [$path]");
|
||||
$output->push($page);
|
||||
}
|
||||
}
|
||||
|
||||
// var_dump("END get pages");
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively search through $folder
|
||||
*
|
||||
*/
|
||||
private static function get_pages_from_folder_recursive($folder, $module = false, $recusive, &$pages) {
|
||||
if(!is_dir($folder)) throw new Exception(sprintf('%s is not a folder', $folder));
|
||||
private static function get_pages_from_folder_recursive($base, $relative, $recusive, &$pages) {
|
||||
if(!is_dir($base)) throw new Exception(sprintf('%s is not a folder', $folder));
|
||||
|
||||
$handle = opendir($folder);
|
||||
$folder = Controller::join_links($base, $relative);
|
||||
|
||||
$handle = opendir($folder);
|
||||
|
||||
if($handle) {
|
||||
$extensions = self::get_valid_extensions();
|
||||
$ignore = self::get_ignored_files();
|
||||
@ -538,16 +559,17 @@ class DocumentationService {
|
||||
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
if(!in_array($file, $ignore)) {
|
||||
$file = trim(strtolower($file), '/');
|
||||
$path = rtrim($folder, '/') . '/'. $file;
|
||||
|
||||
$path = Controller::join_links($folder, $file);
|
||||
$relativeFilePath = Controller::join_links($relative, $file);
|
||||
|
||||
if(is_dir($path)) {
|
||||
$pages[] = $path;
|
||||
$pages[] = $relativeFilePath;
|
||||
|
||||
if($recusive) self::get_pages_from_folder_recursive($path, $module, $recusive, $pages);
|
||||
if($recusive) self::get_pages_from_folder_recursive($base, $relativeFilePath, $recusive, $pages);
|
||||
}
|
||||
else if(in_array(substr($file, (strrpos($file, '.'))), $extensions)) {
|
||||
$pages[] = $path;
|
||||
$pages[] = $relativeFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -343,14 +343,14 @@ class DocumentationViewer extends Controller {
|
||||
*/
|
||||
function getPage() {
|
||||
$module = $this->getModule();
|
||||
|
||||
|
||||
if(!$module) return false;
|
||||
|
||||
$absFilepath = DocumentationService::find_page($module, $this->Remaining);
|
||||
|
||||
if($absFilepath) {
|
||||
$relativeFilePath = str_replace($module->getPath(), '', $absFilepath);
|
||||
|
||||
|
||||
$page = new DocumentationPage();
|
||||
$page->setRelativePath($relativeFilePath);
|
||||
$page->setEntity($module);
|
||||
@ -372,7 +372,7 @@ class DocumentationViewer extends Controller {
|
||||
*/
|
||||
function getModulePages() {
|
||||
if($module = $this->getModule()) {
|
||||
$pages = DocumentationService::get_pages_from_folder($module, false);
|
||||
$pages = DocumentationService::get_pages_from_folder($module, null, false);
|
||||
|
||||
if($pages) {
|
||||
foreach($pages as $page) {
|
||||
@ -382,14 +382,9 @@ class DocumentationViewer extends Controller {
|
||||
continue;
|
||||
}
|
||||
|
||||
$linkParts = array();
|
||||
|
||||
// don't include the 'index in the url
|
||||
if(strtolower($page->Title) != "index") $linkParts[] = $page->Filename;
|
||||
|
||||
$page->Link = $this->Link($linkParts);
|
||||
$page->LinkingMode = 'link';
|
||||
$page->Children = $this->_getModulePagesNested($page);
|
||||
|
||||
$page->Children = $this->_getModulePagesNested($page, $module);
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,21 +398,21 @@ class DocumentationViewer extends Controller {
|
||||
* Get the module pages under a given page. Recursive call for {@link getModulePages()}
|
||||
*
|
||||
* @param ArrayData CurrentPage
|
||||
* @param DocumentationEntity
|
||||
* @param int Depth of page in the tree
|
||||
*
|
||||
* @return DataObjectSet|false
|
||||
*/
|
||||
private function _getModulePagesNested(&$page, $level = 0) {
|
||||
private function _getModulePagesNested(&$page, $module, $level = 0) {
|
||||
// only support 2 more levels
|
||||
if(isset($this->Remaining[$level])) {
|
||||
|
||||
if(strtolower($this->Remaining[$level]) == $page->Filename) {
|
||||
if(strtolower($this->Remaining[$level]) == trim($page->Filename, '/')) {
|
||||
|
||||
// its either in this section or is the actual link
|
||||
$page->LinkingMode = (isset($this->Remaining[$level + 1])) ? 'section' : 'current';
|
||||
|
||||
if(is_dir($page->getPath())) {
|
||||
$children = DocumentationService::get_pages_from_folder($page->getPath(), false);
|
||||
$children = DocumentationService::get_pages_from_folder($module, $page->getRelativePath(), false);
|
||||
|
||||
$segments = array();
|
||||
for($x = 0; $x <= $level; $x++) {
|
||||
@ -430,10 +425,9 @@ class DocumentationViewer extends Controller {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$child->Link = $this->Link(array_merge($segments, array($child->Filename)));
|
||||
|
||||
$child->LinkingMode = 'link';
|
||||
$child->Children = $this->_getModulePagesNested($child, $level + 1);
|
||||
$child->Children = $this->_getModulePagesNested($child, $module, $level + 1);
|
||||
}
|
||||
|
||||
return $children;
|
||||
@ -453,6 +447,7 @@ class DocumentationViewer extends Controller {
|
||||
*/
|
||||
function getContent() {
|
||||
if($page = $this->getPage()) {
|
||||
|
||||
// Remove last portion of path (filename), we want a link to the folder base
|
||||
$html = DocumentationParser::parse($page, $this->Link(array_slice($this->Remaining, -1, -1)));
|
||||
return DBField::create("HTMLText", $html);
|
||||
@ -523,7 +518,9 @@ class DocumentationViewer extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
return $base . self::$link_base . $version . $lang . $module . $action;
|
||||
$link = Controller::join_links($base, self::get_link_base(), $version, $lang, $module, $action);
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -627,14 +624,8 @@ class DocumentationViewer extends Controller {
|
||||
$search = new DocumentationSearch();
|
||||
$search->performSearch($query);
|
||||
|
||||
$results = $search->getResults($start);
|
||||
$total = $search->getTotalResults();
|
||||
$data = $search->getDataArrayFromHits($start);
|
||||
|
||||
echo $this->customise(array(
|
||||
'Results' => $results,
|
||||
'Query' => DBField::create('HTMLVarchar', $query),
|
||||
'Start' => DBField::create('HTMLVarchar', $start),
|
||||
'TotalResults'
|
||||
))->renderWith(array('DocumentationViewer_results', 'DocumentationViewer'));
|
||||
return $this->customise($data)->renderWith(array('DocumentationViewer_results', 'DocumentationViewer'));
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ class RebuildLuceneDocsIndex extends BuildTask {
|
||||
* based on the user. It's a
|
||||
*/
|
||||
function run($request) {
|
||||
|
||||
require_once('../sapphiredocs/thirdparty/markdown.php');
|
||||
ini_set("memory_limit", -1);
|
||||
ini_set('max_execution_time', 0);
|
||||
|
||||
@ -55,11 +55,14 @@ class RebuildLuceneDocsIndex extends BuildTask {
|
||||
|
||||
if(!is_dir($page->getPath())) {
|
||||
$doc = new Zend_Search_Lucene_Document();
|
||||
$doc->addField(Zend_Search_Lucene_Field::Text('content', $page->getMarkdown()));
|
||||
$content = $page->getMarkdown();
|
||||
if($content) $content = Markdown($content);
|
||||
|
||||
$doc->addField(Zend_Search_Lucene_Field::Text('content', $content));
|
||||
$doc->addField(Zend_Search_Lucene_Field::Text('Title', $page->getTitle()));
|
||||
$doc->addField(Zend_Search_Lucene_Field::Keyword('Version', $page->getVersion()));
|
||||
$doc->addField(Zend_Search_Lucene_Field::Keyword('Language', $page->getLang()));
|
||||
$doc->addField(Zend_Search_Lucene_Field::Keyword('Link', $page->getLink()));
|
||||
$doc->addField(Zend_Search_Lucene_Field::Keyword('Link', $page->Link()));
|
||||
$index->addDocument($doc);
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,39 @@
|
||||
<div id="documentation-page">
|
||||
<div id="left-column">
|
||||
<p>Your search for <strong>"$Query.XML"</strong> found $TotalResults result<% if TotalResults != 1 %>s<% end_if %>.</p>
|
||||
|
||||
<% if Results %>
|
||||
<p>Showing page $ThisPage of $TotalPages</p>
|
||||
<% control Results %>
|
||||
<h2><a href="$Link">$Title</a></h2>
|
||||
$Content.Summary
|
||||
$Content.LimitWordCountXML
|
||||
<% end_control %>
|
||||
|
||||
<% if SearchPages %>
|
||||
<ul class="pagination">
|
||||
<% if PrevUrl = false %><% else %>
|
||||
<li class="prev"><a href="$PrevUrl">Prev</a></li>
|
||||
<% end_if %>
|
||||
|
||||
<% control SearchPages %>
|
||||
<% if IsEllipsis %>
|
||||
<li class="ellipsis">...</li>
|
||||
<% else %>
|
||||
<% if Current %>
|
||||
<li class="active"><strong>$PageNumber</strong></li>
|
||||
<% else %>
|
||||
<li><a href="$Link">$PageNumber</a></li>
|
||||
<% end_if %>
|
||||
<% end_if %>
|
||||
<% end_control %>
|
||||
|
||||
<% if NextUrl = false %>
|
||||
<% else %>
|
||||
<li class="next"><a href="$NextUrl">Next</a></li>
|
||||
<% end_if %>
|
||||
</ul>
|
||||
<% end_if %>
|
||||
|
||||
<% else %>
|
||||
<p>No Results</p>
|
||||
<% end_if %>
|
||||
|
@ -29,6 +29,5 @@ class DocumentationEntityTest extends SapphireTest {
|
||||
$entity->addVersion('1.1.', '../sapphiredocs/tests/docs-2/');
|
||||
$entity->setCurrentVersion('1.0');
|
||||
$this->assertEquals('1.0', $entity->getCurrentVersion(), 'Manual setting');
|
||||
|
||||
}
|
||||
}
|
@ -1,6 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package sapphiredocs
|
||||
* @subpackage tests
|
||||
*/
|
||||
|
||||
class DocumentationPageTest extends SapphireTest {
|
||||
|
||||
function testGetLink() {
|
||||
$entity = new DocumentationEntity('testmodule', null, BASE_PATH . '/sapphiredocs/tests/docs/');
|
||||
|
||||
$page = new DocumentationPage();
|
||||
$page->setRelativePath('test.md');
|
||||
$page->setEntity($entity);
|
||||
|
||||
// single layer
|
||||
$this->assertStringEndsWith('en/testmodule/test', $page->Link(), 'The page link should have no extension and have a language');
|
||||
|
||||
$folder = new DocumentationPage();
|
||||
$folder->setRelativePath('sort');
|
||||
$folder->setEntity($entity);
|
||||
|
||||
// folder, should have a trailing slash
|
||||
$this->assertStringEndsWith('en/testmodule/sort/', $folder->Link());
|
||||
|
||||
// second
|
||||
$nested = new DocumentationPage();
|
||||
$nested->setRelativePath('subfolder/subpage.md');
|
||||
$nested->setEntity($entity);
|
||||
|
||||
$this->assertStringEndsWith('en/testmodule/subfolder/subpage', $nested->Link());
|
||||
|
||||
// test with version.
|
||||
$entity = DocumentationService::register("versionlinks", BASE_PATH . "/sapphiredocs/tests/docs-2/", '1');
|
||||
$page = new DocumentationPage();
|
||||
$page->setRelativePath('test.md');
|
||||
$page->setEntity($entity);
|
||||
$page->setVersion('1');
|
||||
$this->assertStringEndsWith('1/en/versionlinks/test', $page->Link());
|
||||
}
|
||||
|
||||
|
||||
function testGetRelativePath() {
|
||||
$page = new DocumentationPage();
|
||||
$page->setRelativePath('test.md');
|
||||
|
@ -31,6 +31,7 @@ class DocumentationParserTest extends SapphireTest {
|
||||
$page->setVersion('2.4');
|
||||
|
||||
$result = DocumentationParser::rewrite_image_links($page->getMarkdown(), $page, 'mycontroller/cms/2.4/en/');
|
||||
|
||||
$this->assertContains(
|
||||
'[relative image link](' . Director::absoluteBaseURL() . '/sapphiredocs/tests/docs/en/subfolder/_images/image.png)',
|
||||
$result
|
||||
@ -183,28 +184,4 @@ class DocumentationParserTest extends SapphireTest {
|
||||
$result
|
||||
);
|
||||
}
|
||||
|
||||
function testCleanPageNames() {
|
||||
$names = array(
|
||||
'documentation-Page',
|
||||
'documentation_Page',
|
||||
'documentation.md',
|
||||
'documentation.pdf',
|
||||
'documentation.file.txt',
|
||||
'.hidden'
|
||||
);
|
||||
|
||||
$should = array(
|
||||
'Documentation Page',
|
||||
'Documentation Page',
|
||||
'Documentation',
|
||||
'Documentation',
|
||||
'Documentation.file',
|
||||
'.hidden' // don't display something without a title
|
||||
);
|
||||
|
||||
foreach($names as $key => $value) {
|
||||
$this->assertEquals(DocumentationService::clean_page_name($value), $should[$key]);
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,42 @@
|
||||
|
||||
class DocumentationServiceTest extends SapphireTest {
|
||||
|
||||
function testGetPagesFromFolder() {
|
||||
$entity = DocumentationService::register('testdocs', BASE_PATH . '/sapphiredocs/tests/docs/');
|
||||
$pages = DocumentationService::get_pages_from_folder($entity);
|
||||
|
||||
// check folders and files exist as their filenames
|
||||
$this->assertContains('index.md', $pages->column('Filename'), 'The tests/docs/en folder should contain a index file');
|
||||
$this->assertContains('subfolder/', $pages->column('Filename'), 'The tests/docs/en folder should contain a subfolder called subfolder');
|
||||
$this->assertContains('test.md', $pages->column('Filename'), 'The tests/docs/en folder should contain a test file');
|
||||
$this->assertNotContains('_images', $pages->column('Filename'), 'It should not include hidden files');
|
||||
$this->assertNotContains('.svn', $pages->column('Filename'), 'It should not include hidden files');
|
||||
|
||||
// test the order of pages
|
||||
$pages = DocumentationService::get_pages_from_folder($entity, 'sort');
|
||||
|
||||
$this->assertEquals(
|
||||
array('Basic', 'Intermediate', 'Advanced', 'Some page', 'Another page'),
|
||||
$pages->column('Title')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function testGetPagesFromFolderRecursive() {
|
||||
$entity = DocumentationService::register('testdocsrecursive', BASE_PATH . '/sapphiredocs/tests/docs-recursive/');
|
||||
|
||||
$pages = DocumentationService::get_pages_from_folder($entity, null, true);
|
||||
|
||||
// check to see all the pages are found, we don't care about order
|
||||
$this->assertEquals($pages->Count(), 9);
|
||||
|
||||
$pages = $pages->column('Title');
|
||||
|
||||
foreach(array('Index', 'SubFolder TestFile', 'SubSubFolder TestFile', 'TestFile') as $expected) {
|
||||
$this->assertContains($expected, $pages);
|
||||
}
|
||||
}
|
||||
|
||||
function testFindPath() {
|
||||
DocumentationService::register("DocumentationViewerTests", BASE_PATH . "/sapphiredocs/tests/docs/");
|
||||
|
||||
@ -34,35 +70,28 @@ class DocumentationServiceTest extends SapphireTest {
|
||||
$this->assertEquals(BASE_PATH . "/sapphiredocs/tests/docs/en/subfolder/subsubfolder/subsubpage.md", $path);
|
||||
}
|
||||
|
||||
function testGetPagesFromFolder() {
|
||||
$pages = DocumentationService::get_pages_from_folder(BASE_PATH . '/sapphiredocs/tests/docs/en/');
|
||||
|
||||
$this->assertContains('index', $pages->column('Filename'), 'The tests/docs/en folder should contain a index file');
|
||||
$this->assertContains('subfolder', $pages->column('Filename'), 'The tests/docs/en folder should contain a subfolder called subfolder');
|
||||
$this->assertContains('test', $pages->column('Filename'), 'The tests/docs/en folder should contain a test file');
|
||||
$this->assertNotContains('_images', $pages->column('Filename'), 'It should not include hidden files');
|
||||
$this->assertNotContains('.svn', $pages->column('Filename'), 'It should not include hidden files');
|
||||
|
||||
// test the order of pages
|
||||
$pages = DocumentationService::get_pages_from_folder(BASE_PATH . '/sapphiredocs/tests/docs/en/sort');
|
||||
|
||||
$this->assertEquals(
|
||||
array('1 basic', '2 intermediate', '3 advanced', '10 some page', '21 another page'),
|
||||
$pages->column('Title')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function testGetPagesFromFolderRecursive() {
|
||||
$pages = DocumentationService::get_pages_from_folder(BASE_PATH . '/sapphiredocs/tests/docs-recursive/en/');
|
||||
function testCleanPageNames() {
|
||||
$names = array(
|
||||
'documentation-Page',
|
||||
'documentation_Page',
|
||||
'documentation.md',
|
||||
'documentation.pdf',
|
||||
'documentation.file.txt',
|
||||
'.hidden'
|
||||
);
|
||||
|
||||
// check to see all the pages are found, we don't care about order
|
||||
$this->assertEquals($pages->Count(), 9);
|
||||
|
||||
$pages = $pages->column('Title');
|
||||
$should = array(
|
||||
'Documentation Page',
|
||||
'Documentation Page',
|
||||
'Documentation',
|
||||
'Documentation.pdf', // do not remove an extension we don't know
|
||||
'Documentation.file', // .txt we do know about
|
||||
'.hidden' // don't display something without a title
|
||||
);
|
||||
|
||||
foreach(array('Index', 'Subfolder testfile', 'Subsubfolder testfile', 'Testfile') as $expected) {
|
||||
$this->assertContains($expected, $pages);
|
||||
foreach($names as $key => $value) {
|
||||
$this->assertEquals(DocumentationService::clean_page_name($value), $should[$key]);
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
* @package sapphiredocs
|
||||
*/
|
||||
|
||||
class DocumentationViewerTests extends FunctionalTest {
|
||||
class DocumentationViewerTest extends FunctionalTest {
|
||||
|
||||
static $fixture_file = 'sapphiredocs/tests/DocumentTests.yml';
|
||||
|
||||
@ -39,6 +39,67 @@ class DocumentationViewerTests extends FunctionalTest {
|
||||
DocumentationViewer::set_link_base($this->origLinkBase);
|
||||
}
|
||||
|
||||
function testGetModulePagesShort() {
|
||||
$v = new DocumentationViewer();
|
||||
$response = $v->handleRequest(new SS_HTTPRequest('GET', '2.4/en/DocumentationViewerTests/subfolder/'));
|
||||
$pages = $v->getModulePages();
|
||||
|
||||
$arr = $pages->toArray();
|
||||
$page = $arr[2];
|
||||
|
||||
$this->assertEquals('Subfolder', $page->Title);
|
||||
}
|
||||
|
||||
function testGetModulePages() {
|
||||
$v = new DocumentationViewer();
|
||||
$response = $v->handleRequest(new SS_HTTPRequest('GET', '2.4/en/DocumentationViewerTests/subfolder/'));
|
||||
$pages = $v->getModulePages();
|
||||
$this->assertEquals(
|
||||
array('sort/', 'subfolder/', 'test.md'),
|
||||
$pages->column('Filename')
|
||||
);
|
||||
$this->assertEquals(
|
||||
array('link','current', 'link'),
|
||||
$pages->column('LinkingMode')
|
||||
);
|
||||
|
||||
foreach($pages as $page) {
|
||||
$page->setVersion('2.4');
|
||||
}
|
||||
|
||||
$links = $pages->column('Link');
|
||||
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/sort/', $links[0]);
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/subfolder/', $links[1]);
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/test', $links[2]);
|
||||
|
||||
// Children
|
||||
$pagesArr = $pages->toArray();
|
||||
$child1 = $pagesArr[1];
|
||||
|
||||
$this->assertFalse($child1->Children);
|
||||
$child2 = $pagesArr[2];
|
||||
|
||||
$this->assertType('DataObjectSet', $child2->Children);
|
||||
|
||||
$this->assertEquals(
|
||||
array('subfolder/subpage.md', 'subfolder/subsubfolder/'),
|
||||
$child2->Children->column('Filename')
|
||||
);
|
||||
|
||||
$children = $child2->Children;
|
||||
|
||||
foreach($children as $child) {
|
||||
$child->setVersion('2.4');
|
||||
}
|
||||
|
||||
$child2Links = $children->column('Link');
|
||||
$subpage = $children->First();
|
||||
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/subfolder/subpage', $child2Links[0]);
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/subfolder/subsubfolder/', $child2Links[1]);
|
||||
}
|
||||
|
||||
function testCurrentRedirection() {
|
||||
$response = $this->get('dev/docs/3.0/en/DocumentationViewerTests/test');
|
||||
|
||||
@ -118,45 +179,6 @@ class DocumentationViewerTests extends FunctionalTest {
|
||||
$this->assertStringEndsWith('DocumentationViewerTests/subfolder/subpage/', $crumbLinks[2]);
|
||||
}
|
||||
|
||||
function testGetModulePages() {
|
||||
$v = new DocumentationViewer();
|
||||
$response = $v->handleRequest(new SS_HTTPRequest('GET', '2.4/en/DocumentationViewerTests/subfolder/'));
|
||||
$pages = $v->getModulePages();
|
||||
$this->assertEquals(
|
||||
array('sort', 'subfolder', 'test'),
|
||||
$pages->column('Filename')
|
||||
);
|
||||
$this->assertEquals(
|
||||
array('link','current', 'link'),
|
||||
$pages->column('LinkingMode')
|
||||
);
|
||||
$links = $pages->column('Link');
|
||||
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/sort/', $links[0]);
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/subfolder/', $links[1]);
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/test/', $links[2]);
|
||||
|
||||
// Children
|
||||
$pagesArr = $pages->toArray();
|
||||
|
||||
$child1 = $pagesArr[1];
|
||||
|
||||
$this->assertFalse($child1->Children);
|
||||
|
||||
$child2 = $pagesArr[2];
|
||||
|
||||
$this->assertType('DataObjectSet', $child2->Children);
|
||||
|
||||
$this->assertEquals(
|
||||
array('subpage', 'subsubfolder'),
|
||||
$child2->Children->column('Filename')
|
||||
);
|
||||
|
||||
$child2Links = $child2->Children->column('Link');
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/subfolder/subpage/', $child2Links[0]);
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/subfolder/subsubfolder/', $child2Links[1]);
|
||||
}
|
||||
|
||||
function testRouting() {
|
||||
$response = $this->get('dev/docs/2.4/en/DocumentationViewerTests/test');
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
|
Loading…
Reference in New Issue
Block a user