caseyamcl / toc

Table of Contents Generator for HTML Markup
MIT License
84 stars 15 forks source link

Empty markup provided to getHtmlMenu causes TypeError #6

Closed Mark-H closed 5 years ago

Mark-H commented 5 years ago

Using the following code:

        $tocGenerator = new TocGenerator();

        $renderer = new TocRenderer(new Matcher(),
            $this->currentUrl,
            [
                'currentClass' => 'c-toc__item--active',
                'ancestorClass' => 'c-toc__item--activeancestor',
                'firstClass' => 'c-toc__item--first',
                'lastClass' => 'c-toc__item--last',
            ]
        );

        return $tocGenerator->getHtmlMenu(
            $body,
            $topLevel,
            $depth,
            $renderer
        );

where $body happens to be an empty string (which admittedly is an edge case), results in the following TypeError:

Type: TypeError
Message: Argument 1 passed to Knp\Menu\Renderer\ListRenderer::render() must implement interface Knp\Menu\ItemInterface, array given, called in vendor/caseyamcl/toc/src/TocGenerator.php on line 153
File: vendor/knplabs/knp-menu/src/Knp/Menu/Renderer/ListRenderer.php
Line: 42

Trace
#0 vendor/caseyamcl/toc/src/TocGenerator.php(153): Knp\Menu\Renderer\ListRenderer->render(Array)
#1 src/Model/Page.php(194): TOC\TocGenerator->getHtmlMenu('', 2, 6, Object(MODXDocs\Helpers\TocRenderer))
#2 src/Views/Doc.php(74): MODXDocs\Model\Page->getTableOfContents()
#3 [internal function]: MODXDocs\Views\Doc->get(Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
#4 vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php(41): call_user_func(Array, Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
#5 vendor/slim/slim/Slim/Route.php(356): Slim\Handlers\Strategies\RequestResponse->__invoke(Array, Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
#6 vendor/slim/slim/Slim/MiddlewareAwareTrait.php(117): Slim\Route->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response))
#7 vendor/slim/slim/Slim/Route.php(334): Slim\Route->callMiddlewareStack(Object(Slim\Http\Request), Object(Slim\Http\Response))
#8 vendor/slim/slim/Slim/App.php(516): Slim\Route->run(Object(Slim\Http\Request), Object(Slim\Http\Response))
#9 src/Middlewares/RequestMiddleware.php(27): Slim\App->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response))
#10 [internal function]: MODXDocs\Middlewares\RequestMiddleware->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response), Object(Slim\App))
#11 vendor/slim/slim/Slim/DeferredCallable.php(43): call_user_func_array(Object(MODXDocs\Middlewares\RequestMiddleware), Array)
#12 [internal function]: Slim\DeferredCallable->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response), Object(Slim\App))
#13 vendor/slim/slim/Slim/MiddlewareAwareTrait.php(70): call_user_func(Object(Slim\DeferredCallable), Object(Slim\Http\Request), Object(Slim\Http\Response), Object(Slim\App))
#14 vendor/slim/slim/Slim/MiddlewareAwareTrait.php(117): Slim\App->Slim\{closure}(Object(Slim\Http\Request), Object(Slim\Http\Response))
#15 vendor/slim/slim/Slim/App.php(407): Slim\App->callMiddlewareStack(Object(Slim\Http\Request), Object(Slim\Http\Response))
#16 vendor/slim/slim/Slim/App.php(315): Slim\App->process(Object(Slim\Http\Request), Object(Slim\Http\Response))
#17 src/DocsApp.php(64): Slim\App->run()
#18 public/index.php(20): MODXDocs\DocsApp->run()
#19 {main}

It appears that the return []; should be replaced with return $menu; to allow it to fall back gracefully here: https://github.com/caseyamcl/toc/blob/master/src/TocGenerator.php#L74-L76

As a workaround I've added a try {} catch () {} to the code, but it seems like this would be a bug.

Also, nice work on this project :) We're using it to power the TOC on a new documentation site for a CMS called MODX: https://docs.modx.org/

caseyamcl commented 5 years ago

Hi Mark H.

I believe this was fixed in v2.0, but if it wasn't, let me know, and I'll try fixing it. Happy to hear that you are using it successfully!

https://github.com/caseyamcl/toc/releases