Skip to content

Nested lists only works with invalid HTML #1279

Closed
@rkorebrits

Description

@rkorebrits

This is a bug report

Expected Behavior

In HTML when nesting lists, the nested <ul> needs to be inside, at the end of the parent <li> node.

Current Behavior

E.g. Sample 26 uses invalid HTML to build HTML for the list.

The error message that I receive:

Type: BadMethodCallException
Message: Cannot add ListItemRun in ListItemRun.
Filename: /www/_ditto/ditto/vendor/phpoffice/phpword/src/PhpWord/Element/AbstractContainer.php
Line Number: 230

How to Reproduce

<?php
    public function runTest(){
        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $section = $phpWord->addSection();
        $html = '<h1>Adding element via HTML</h1>';

        // WRONG - but works
        $html .= '<ul><li>Item 1</li><li>Item 2</li><ul><li>Item 2.1</li><li>Item 2.1</li></ul></ul>';
        // RIGHT - But throws an error
        $html .= '<ul><li>Item 1</li><li>Item 2<ul><li>Item 2.1</li><li>Item 2.1</li></ul></li></ul>';

        \PhpOffice\PhpWord\Shared\Html::addHtml($section, $html, false, false);

        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter(
            $phpWord, 'Word2007'
        );

        $file_path_docx = 'test_bullets.docx';
        $objWriter->save($file_path_docx);
    }

To solve this for now, I've added a regex to extract the HTML to make it work:

    // First replace new lines by spaces
    $html = str_replace(["\r\n", "\n", "\r"], '', $html);
    // Extract UL from LI an place after
    $html = preg_replace('/(<li.*?>.*?)(<ul>.*?<\/ul>)\s?(<\/li>)/i', '$1$3$2', $html);

Not sure if it's the best regex, but for our solution it works.

Context

  • PHP version: 7.1
  • PHPWord version: latest dev

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions