phpDocumentor Web Pages Are Not Styled

In between working on building my Fractional CTO portfolio, I’ve been busy working on updating Store Locator Plus® to get it to a point where we can eventually hire a part-time developer to assist with ongoing maintenance and general improvements. Part of that process has been re-learning this massive PHP + JavaScript project. The first step, renew the code documentation with a tool like phpDocumentor. While this tool worked great in a quick trial run, it quickly ran into an issue. The phpDocumentor web pages are not styled.

Normally a phpDocumentor site, when the tool works properly, comes out looking something like the image below. A nice clean interface that is easy to navigate.

phpDocumentor when not missing styles
phpDocumentor , properly styles

Sadly, with some code sets the documentation tool breaks and generates as website with missing styles like the image below.

phpDocumentor web pages are not styled
phpDocumentor web pages are not styled

My theory is that the pages are not styled because the phpDocumentor tool executes the theme generation, looks like a Twig-generated CSS stack via that web theme tool, happens in the last steps of the web page generation cycle.

Hints That Styling Will Break

In my environment I already have Docker installed and am running phpDocumentor using their phpDoc Docker image (say that ten times fast). During the run it will generate the following error message.

CRITICAL  [console] An error occurred while using the console. Message: "Call to a member function getFile() on null" ["exception" => Error { …},"message" => "Call to a member function getFile() on null"]
The phpDocumentor run when a getFile() on null rears its ugly head.

Semicolon (;) Breaking Comment

After a lot of trial and error I was finally able to find the source of the error code; Any error at this stage will generate phpDocumentor web pages that are not styled. Turns out that in my case a rogue semicolon in a phpDoc block header was triggering the failure. A bug report has been submitted to phpDocumentor that we hope is fixed soon; Finding these random ; in comment blocks is a nightmare even with good IDE and command-line code search tools.


/**
This breaks...

Export locations to a CSV file.
@property-read array $active_columns;
@property-read string[] $dbFields The fields we want to export.
*/
class SLP_Power_Locations_Export {}

/**
This works...

Export locations to a CSV file.
@property-read array $active_columns
@property-read string[] $dbFields The fields we want to export.
*/
class SLP_Power_Locations_Export {}

Missing The $ On A Variable

The following section of a docblock also breaks the phpDocumentor tool:

/**
* Do Something
*
* This breaks phpDocumentor.
* 
* @property AClass AProperty The property
*/
class ABC {}

/**
* Do Something
*
* This works.
* 
* @property AClass $AProperty The property
*/
class ABC {}

Tracking Down Breaking Comments

Tracking down the comments that are breaking phpDocumentor can be done by eliminating entire directories using the phpDocumentor configuration file. Add a phpdoc.dist.xml file to the root directory of your project where you are running the phpDocumentor command.

Add directories or subdirectories to the ignore list until the error stops. Slowly add back directories until it breaks again. It is a lot of trial-and-error. Eventually you will hopefully have one directory that contains the troublemaker file. Rename the file to not have a PHP suffix and see if the command runs…then start looking through your comments.

Here is an example phpdocs.dist.xml config file for Store Locator Plus®.

<?xml version="1.0" encoding="UTF-8" ?>
<phpdocumentor
configVersion="3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://www.phpdoc.org"
>
<title>Store Locator Plus®</title>
<paths>
<output>.phpdoc/slp</output>
<cache>.phpdoc/cache</cache>
</paths>
<version number="latest">
<api>
<default-package-name>Store Locator Plus®</default-package-name>
<ignore hidden="true" symlinks="true">
<path>assets/**/*</path>
<path>build/**/*</path>
<path>css/**/*</path>
<path>fonts/**/*</path>
<path>images/**/*</path>
<path>js/**/*</path>
<path>languages/**/*</path>
<path>node_modules/**/*</path>
<path>src/**/*</path>
<path>uploads/**/*</path>
<path>*.md</path>
<path>*.json</path>
<path>*.txt</path>
<path>*.xml</path>
<path>*.lock</path>
</ignore>
</api>
</version>
</phpdocumentor>

The path *.<extension> means ignore the files with those extensions in the root directory only.

The path <directory>/**/* means ignore all subdirectories and files. Example: include/**/*

post image via Pixabay

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.