Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Shows the board's Hugo documentation site inside phpBB, styled with the active b

The build's HTML is shown inside the board as-is, so only put a build you trust at the docs build path, in a directory only administrators can write to.

Boards upgraded from an earlier version keep their build at `ext/phpbbmodders/documentation/docs-build/` if one was already there; move it to the new location and update the docs build path to stop the next extension update deleting it.
Boards upgraded from an earlier version keep their build at `ext/phpbbmodders/documentation/docs-build/` if one was already there; move it to the new location and update the docs build path to stop the next extension update deleting it. The settings page warns while the build is inside the extension's directory. If the build is moved but the setting isn't updated, the extension reads it from `store/phpbbmodders_documentation/` and the settings page asks for the setting to be updated.

If you add a new top-level section or a new language to the docs build later, use the **Resync permissions** button on the settings page.

Expand Down
3 changes: 3 additions & 0 deletions acp/main_module.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ public function main($id, $mode)
'ERROR_MSG' => implode('<br>', $error),

'S_DOCUMENTATION_BUILD_FOUND' => $docs_root_found,
'S_DOCUMENTATION_STORE_FALLBACK' => $doc_helper->is_using_store_fallback(),
'S_DOCUMENTATION_BUILD_IN_EXTENSION' => $doc_helper->is_build_inside_extension(),
'DOCUMENTATION_DEFAULT_DOCS_PATH' => $doc_helper::DEFAULT_DOCS_PATH,
'RESYNC_FEEDBACK' => $resync_feedback,

'DOCUMENTATION_DOCS_PATH' => $cfg_array['phpbbmodders_documentation_docs_path'],
Expand Down
12 changes: 12 additions & 0 deletions adm/style/acp_documentation.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ <h3>{{ lang('WARNING') }}</h3>
</div>
{% endif %}

{% if S_DOCUMENTATION_STORE_FALLBACK %}
<div class="errorbox">
<p>{{ lang('ACP_DOCUMENTATION_STORE_FALLBACK', DOCUMENTATION_DEFAULT_DOCS_PATH)|e }}</p>
</div>
{% endif %}

{% if S_DOCUMENTATION_BUILD_IN_EXTENSION %}
<div class="errorbox">
<p>{{ lang('ACP_DOCUMENTATION_BUILD_IN_EXTENSION', DOCUMENTATION_DEFAULT_DOCS_PATH)|e }}</p>
</div>
{% endif %}

{% if not S_DOCUMENTATION_BUILD_FOUND %}
<div class="errorbox">
<p>{{ lang('ACP_DOCUMENTATION_BUILD_MISSING') }}</p>
Expand Down
86 changes: 81 additions & 5 deletions controller/documentation_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ class documentation_helper
/** Page whose wide tables get wrapped in a horizontally scrollable region. */
const EVENTS_LIST_PATH = 'development/extensions/events_list';

/** Default docs build path, relative to the phpBB root. */
const DEFAULT_DOCS_PATH = 'store/phpbbmodders_documentation';

/**
* Default before the build moved to store/. Boards still set to it use
* DEFAULT_DOCS_PATH when this has no build but that does.
*/
const LEGACY_DOCS_PATH = 'ext/phpbbmodders/documentation/docs-build';

/** This extension's own directory, relative to the phpBB root. */
const EXTENSION_PATH = 'ext/phpbbmodders/documentation';

/** Character Hugo's breadcrumb puts before its home link. */
const HUGO_HOME_GLYPH = '⌂';

Expand Down Expand Up @@ -167,24 +179,88 @@ public function get_docs_root()
}

/**
* @return string|false The configured docs path, resolved and
* existence-checked, but without requiring it to be non-empty.
* The configured docs path, resolved and existence-checked, but
* without requiring it to be non-empty. A board still set to
* LEGACY_DOCS_PATH with no build there gets DEFAULT_DOCS_PATH instead
* when that has a build, so moving the build to store/ works before
* the setting is updated.
*
* @return string|false
*/
protected function resolve_configured_root()
{
$configured = (string) $this->config['phpbbmodders_documentation_docs_path'];
$root = $this->resolve_path($configured);

if ($this->is_store_fallback($configured, $root))
{
return $this->resolve_path(self::DEFAULT_DOCS_PATH);
}

return $root;
}

/**
* @param string $configured The docs path setting.
* @param string|false $root That setting, resolved.
* @return bool Whether the build is read from DEFAULT_DOCS_PATH instead.
*/
protected function is_store_fallback($configured, $root)
{
if ($configured !== self::LEGACY_DOCS_PATH || ($root !== false && $this->has_any_language_directory($root)))
{
return false;
}

$store = $this->resolve_path(self::DEFAULT_DOCS_PATH);

return $store !== false && $this->has_any_language_directory($store);
}

if ($configured === '')
/**
* @param string $path Absolute, or relative to the phpBB root.
* @return string|false The existing directory's real path.
*/
protected function resolve_path($path)
{
if ($path === '')
{
return false;
}

$root = (strpos($configured, '/') === 0) ? $configured : $this->phpbb_root_path . $configured;
$real = realpath($root);
$real = realpath((strpos($path, '/') === 0) ? $path : $this->phpbb_root_path . $path);

return ($real !== false && is_dir($real)) ? $real : false;
}

/**
* Whether the docs build path setting is still the old default but the
* build is read from DEFAULT_DOCS_PATH, so the setting should be updated.
*
* @return bool
*/
public function is_using_store_fallback()
{
$configured = (string) $this->config['phpbbmodders_documentation_docs_path'];

return $this->is_store_fallback($configured, $this->resolve_path($configured));
}

/**
* Whether the build in use lives inside this extension's own
* directory, which is replaced, build and all, when the extension is
* updated.
*
* @return bool
*/
public function is_build_inside_extension()
{
$root = $this->get_docs_root();
$extension = $this->resolve_path(self::EXTENSION_PATH);

return $root !== false && $extension !== false && strpos($root . DIRECTORY_SEPARATOR, $extension . DIRECTORY_SEPARATOR) === 0;
}

/**
* @param string $root
* @return bool
Expand Down
Empty file removed docs-build/.gitkeep
Empty file.
25 changes: 0 additions & 25 deletions docs-build/.htaccess

This file was deleted.

3 changes: 3 additions & 0 deletions language/en/info_acp_documentation.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
'ACP_DOCUMENTATION_SETTINGS' => 'Documentation settings',
'ACP_DOCUMENTATION_SETTINGS_EXPLAIN' => 'Configure where the built documentation site lives and how it behaves inside the forum.',

'ACP_DOCUMENTATION_STORE_FALLBACK' => 'The docs build path still points to the old location inside the extension, which has no build, so the documentation is being read from %s instead. Set the docs build path below to that directory.',
'ACP_DOCUMENTATION_BUILD_IN_EXTENSION' => 'The documentation build is inside the extension’s own directory, which is deleted when the extension is updated. Move the build to %s and set the docs build path below to that directory.',

'ACP_DOCUMENTATION_BUILD_MISSING' => 'No documentation build was found at the configured path. Documentation will stay hidden from the forum until this is fixed.',

'ACP_DOCUMENTATION_DOCS_PATH' => 'Docs build path',
Expand Down
76 changes: 76 additions & 0 deletions tests/controller/documentation_helper_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -790,4 +790,80 @@ public static function search_max_results_provider()
'too high' => array(array('phpbbmodders_documentation_search_max_results' => 5000), 200),
);
}

/**
* A helper for a phpBB root at $board, with the docs build path set to $docs_path.
*
* @param string $board Absolute phpBB root, with a trailing slash.
* @param string $docs_path
* @return documentation_helper
*/
protected function get_board_helper($board, $docs_path)
{
return new documentation_helper(
$this->get_config(array('phpbbmodders_documentation_docs_path' => $docs_path)),
$this->createMock(language::class),
$this->get_request(),
$this->get_user(),
$board,
$this->get_controller_helper()
);
}

protected function make_board_build($board, $path)
{
mkdir($board . $path . '/en', 0777, true);
file_put_contents($board . $path . '/en/index.html', 'page');
}

public function test_old_default_path_without_a_build_falls_back_to_store()
{
$board = $this->docs_root . '/board/';
mkdir($board . documentation_helper::LEGACY_DOCS_PATH, 0777, true);
$this->make_board_build($board, documentation_helper::DEFAULT_DOCS_PATH);

$helper = $this->get_board_helper($board, documentation_helper::LEGACY_DOCS_PATH);

$this->assertSame(realpath($board . documentation_helper::DEFAULT_DOCS_PATH), $helper->get_docs_root());
$this->assertSame(array('en'), $helper->get_available_languages());
$this->assertTrue($helper->is_using_store_fallback());
$this->assertFalse($helper->is_build_inside_extension());
}

public function test_old_default_path_with_a_build_keeps_it_and_warns()
{
$board = $this->docs_root . '/board/';
$this->make_board_build($board, documentation_helper::LEGACY_DOCS_PATH);
$this->make_board_build($board, documentation_helper::DEFAULT_DOCS_PATH);

$helper = $this->get_board_helper($board, documentation_helper::LEGACY_DOCS_PATH);

$this->assertSame(realpath($board . documentation_helper::LEGACY_DOCS_PATH), $helper->get_docs_root());
$this->assertFalse($helper->is_using_store_fallback());
$this->assertTrue($helper->is_build_inside_extension());
}

public function test_other_missing_paths_do_not_fall_back_to_store()
{
$board = $this->docs_root . '/board/';
$this->make_board_build($board, documentation_helper::DEFAULT_DOCS_PATH);

$helper = $this->get_board_helper($board, 'store/somewhere_else');

$this->assertFalse($helper->get_docs_root());
$this->assertFalse($helper->is_using_store_fallback());
}

public function test_store_path_is_neither_a_fallback_nor_inside_the_extension()
{
$board = $this->docs_root . '/board/';
mkdir($board . documentation_helper::EXTENSION_PATH, 0777, true);
$this->make_board_build($board, documentation_helper::DEFAULT_DOCS_PATH);

$helper = $this->get_board_helper($board, documentation_helper::DEFAULT_DOCS_PATH);

$this->assertSame(realpath($board . documentation_helper::DEFAULT_DOCS_PATH), $helper->get_docs_root());
$this->assertFalse($helper->is_using_store_fallback());
$this->assertFalse($helper->is_build_inside_extension());
}
}
Loading