Skip to content

feat(template): set a checkbox #2414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
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
26 changes: 26 additions & 0 deletions docs/templates-processing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,32 @@ You can also set multiple values by passing all of them in an array.

$templateProcessor->setValues(array('firstname' => 'John', 'lastname' => 'Doe'));

setCheckbox
"""""""""""
Given a template containing a checkbox control with the title or tag named:

.. code-block:: clean

${checkbox}

The following will check the checkbox:

.. code-block:: php

$templateProcessor->setCheckbox('checkbox', true);

.. note::

To add a checkbox and set its title or tag in a template:

1. Go to **Developer** tab > **Controls** group,
2. Select the **Check Box Content Control**,
3. Right-click on your checkbox,
4. Click on **Properties**,
5. Set the title or the tag.

These steps may change regarding the version of Microsoft Word used.

setMacroOpeningChars
""""""""
You can define a custom opening macro. The following will set ``{#`` as the opening search pattern.
Expand Down
19 changes: 19 additions & 0 deletions samples/Sample_42_TemplateSetCheckbox.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

include_once 'Sample_Header.php';

// Template processor instance creation
echo date('H:i:s'), ' Creating new TemplateProcessor instance...', EOL;
$filename = 'Sample_42_TemplateSetCheckbox.docx';
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor("resources/{$filename}");

$templateProcessor->setCheckbox('checkbox', true);
$templateProcessor->setCheckbox('checkbox2', false);

echo date('H:i:s'), ' Saving the result document...', EOL;
$templateProcessor->saveAs("results/{$filename}");

echo getEndingNotes(['Word2007' => 'docx'], "results/{$filename}");
if (!CLI) {
include_once 'Sample_Footer.php';
}
Binary file not shown.
21 changes: 21 additions & 0 deletions src/PhpWord/TemplateProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,27 @@ public function setValues(array $values): void
}
}

public function setCheckbox(string $search, bool $checked): void
{
$search = static::ensureMacroCompleted($search);
$blockType = 'w:sdt';

$where = $this->findContainingXmlBlockForMacro($search, $blockType);
if (!is_array($where)) {
return;
}

$block = $this->getSlice($where['start'], $where['end']);

$val = $checked ? '1' : '0';
$block = preg_replace('/(<w14:checked w14:val=)".*?"(\/>)/', '$1"' . $val . '"$2', $block);

$text = $checked ? '☒' : '☐';
$block = preg_replace('/(<w:t>).*?(<\/w:t>)/', '$1' . $text . '$2', $block);

$this->replaceXmlBlock($search, $block, $blockType);
}

/**
* @param string $search
*/
Expand Down
153 changes: 153 additions & 0 deletions tests/PhpWordTests/TemplateProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,159 @@ public function testSetValuesWithCustomMacro(): void
self::assertStringContainsString('Hello John Doe', $templateProcessor->getMainPart());
}

/**
* @covers ::setCheckbox
*/
public function testSetCheckbox(): void
{
$mainPart = '<?xml version="1.0" encoding="UTF-8"?>
<w:p>
<w:sdt>
<w:sdtPr>
<w:alias w:val="${checkbox}"/>
<w14:checkbox>
<w14:checked w14:val="0"/>
</w14:checkbox>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>☐</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
</w:p>
<w:p>
<w:sdt>
<w:sdtPr>
<w:alias w:val="${checkbox2}"/>
<w14:checkbox>
<w14:checked w14:val="1"/>
</w14:checkbox>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>☒</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
</w:p>';

$result = '<?xml version="1.0" encoding="UTF-8"?>
<w:p>
<w:sdt>
<w:sdtPr>
<w:alias w:val="${checkbox}"/>
<w14:checkbox>
<w14:checked w14:val="1"/>
</w14:checkbox>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>☒</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
</w:p>
<w:p>
<w:sdt>
<w:sdtPr>
<w:alias w:val="${checkbox2}"/>
<w14:checkbox>
<w14:checked w14:val="0"/>
</w14:checkbox>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>☐</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
</w:p>';

$templateProcessor = new TestableTemplateProcesor($mainPart);
$templateProcessor->setCheckbox('checkbox', true);
$templateProcessor->setCheckbox('checkbox2', false);

self::assertEquals(preg_replace('/>\s+</', '><', $result), preg_replace('/>\s+</', '><', $templateProcessor->getMainPart()));
}

/**
* @covers ::setCheckbox
*/
public function testSetCheckboxWithCustomMacro(): void
{
$mainPart = '<?xml version="1.0" encoding="UTF-8"?>
<w:p>
<w:sdt>
<w:sdtPr>
<w:alias w:val="{#checkbox#}"/>
<w14:checkbox>
<w14:checked w14:val="0"/>
</w14:checkbox>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>☐</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
</w:p>
<w:p>
<w:sdt>
<w:sdtPr>
<w:alias w:val="{#checkbox2#}"/>
<w14:checkbox>
<w14:checked w14:val="1"/>
</w14:checkbox>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>☒</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
</w:p>';

$result = '<?xml version="1.0" encoding="UTF-8"?>
<w:p>
<w:sdt>
<w:sdtPr>
<w:alias w:val="{#checkbox#}"/>
<w14:checkbox>
<w14:checked w14:val="1"/>
</w14:checkbox>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>☒</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
</w:p>
<w:p>
<w:sdt>
<w:sdtPr>
<w:alias w:val="{#checkbox2#}"/>
<w14:checkbox>
<w14:checked w14:val="0"/>
</w14:checkbox>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>☐</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
</w:p>';

$templateProcessor = new TestableTemplateProcesor($mainPart);
$templateProcessor->setMacroChars('{#', '#}');
$templateProcessor->setCheckbox('checkbox', true);
$templateProcessor->setCheckbox('checkbox2', false);

self::assertEquals(preg_replace('/>\s+</', '><', $result), preg_replace('/>\s+</', '><', $templateProcessor->getMainPart()));
}

/**
* @covers ::setImageValue
*/
Expand Down