Check that a plugin is loaded when accessing its pages

A plugin can be registered yet fail to load for example due to unmet
dependencies.

Fixes #17359
Whitespace
plugin.php: replace DIRECTORY_SEPARATOR by '/'
Move plugin upgrade needed check before loaded check

Ensures we capture display appropriate error message to the user. Before
that, they would get the 'not loaded, dependencies not met' message
instead of the 'upgrade needed' one.
Add plugin basename to error messages

Helps users identifying what plugin is having issues.

Fixes #17368
More plugin error messages improvements

- ERROR_PLUGIN_PAGE_NOT_FOUND: Add plugin basename and page name
- ERROR_PLUGIN_FILE_NOT_FOUND: new message based on above
- New specific messages for invalid page and file specification
  (ERROR_PLUGIN_INVALID_PAGE and ERROR_PLUGIN_INVALID_FILE) instead of
  using ERROR_GENERIC

Fixes #17368
Plugin API: consistent handling of MantisCore pseudo-plugin

- return true and not 1 if we declare return type to be boolean
- plugin_is_installed() returns true for MantisCore since by definition
  it is always installed
Remove direct access to $g_plugin_cache global variable

Introduces 2 new API functions
- plugin_is_registered()
- plugin_get()

Fixes #17366
Code cleanup and whitespace

- Use Closure instead of defining a function to sort plugins
- Remove unnecessary variable assignments
Revise plugin file regex to allow multiple '.' in filename

Allows inclusion of plugin files named like file.name.ext
Remove "with MantisBT" from ERROR_PLUGIN_NOT_REGISTERED
Do not register previously registered plugins

It may happen that a plugin listed as enabled in the plugin table is in
fact already registered with MantisBT if that plugin is also listed as
force_installed in the configuration.

In that case, re-registering it basically 'unprotects' it, and
manage_plugin_page.php displays an Uninstall action even though the
plugin can't actually be uninstalled.
Fix data type issues in plugin API

- enabled and protected are boolean
- priority is int

The type cast before assignment ensures we don't get type mismatch
errors in check_selected/check_checked functions, since DB api seems to
return these fields as strings.
New API to return list of force-installed plugins
Remove unnecessary MantisCore-specific code

Using the new plugin_get_force_installed() function (which always
returns 'MantisCore') allows simplification of several plugin API, as
they no longer require specific code to handle the pseudo plugin.
Simplify code to list installed plugins
Coding guidelines
Improve plugin path regex to avoid arbitrary includes

The path and filename components are not allowed to start with a '.',
which prevents uses like ../../../etc/password
Remove leftover commented out line
Document MantisCore inclusion in plugin_register_installed()