Skip to content
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

Template : Set a checkbox #2509

Merged
merged 1 commit into from
Nov 27, 2023
Merged
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
1 change: 1 addition & 0 deletions docs/changes/1.x/1.2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- PDF Writer : Added support for PageBreak
- PDF Writer : Added callback for modifying the HTML
- Added Support for Language, both for document overall and individual text elements
- Template : Set a checkbox by [@nxtpge](https://github.com/nxtpge) in [#2509](https://github.com/PHPOffice/PHPWord/pull/2509)

### Bug fixes

Expand Down
25 changes: 25 additions & 0 deletions docs/usage/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,31 @@ 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:

``` clean
${checkbox}
```
The following will check the checkbox:

``` php
<?php

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

!!! note annotate "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
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ nav:
- Comment: 'usage/elements/comment.md'
- Field: 'usage/elements/field.md'
- Footnote & Endnote: 'usage/elements/note.md'
- Formula: 'usage/elements/formula.md'
- Image: 'usage/elements/image.md'
- Line: 'usage/elements/line.md'
- Link: 'usage/elements/link.md'
Expand Down
21 changes: 21 additions & 0 deletions samples/Sample_42_TemplateSetCheckbox.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

include_once 'Sample_Header.php';

use PhpOffice\PhpWord\TemplateProcessor;

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

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

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

echo getEndingNotes(['Word2007' => 'docx'], "results/{$filename}");
if (!CLI) {
include_once 'Sample_Footer.php';
}
File renamed without changes.
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 @@ -372,6 +372,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 @@ -610,6 +610,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
Loading