Skip to content

Commit

Permalink
Merge branch 'master' into word1692
Browse files Browse the repository at this point in the history
  • Loading branch information
oleibman authored May 22, 2024
2 parents a6e8940 + 2daa50c commit c0f2310
Show file tree
Hide file tree
Showing 20 changed files with 336 additions and 136 deletions.
65 changes: 65 additions & 0 deletions .github/ISSUE_TEMPLATE/1_bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: 🐛 Bug Report
description: Create a report to help improve PHPWord
labels: [ "Bug Report" ]
body:
- type: markdown
attributes:
value: |
### ❗️ Read this before submitting your bug report:
- **Write in English/French.** Reports in all other languages will be closed.
- **Provide as much detail as possible**
- Attachments : Error logs, Screenshots, Document files (generated and expected).
- If the issue cannot be reproduced, it cannot be fixed.
- type: textarea
id: what-happened
attributes:
label: Describe the bug and add attachments
description: What went wrong? If possible, add screenshots, error logs, document files (generated and expected) or screen recordings to help explain your problem.
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: textarea
id: steps-reproduce
attributes:
label: Steps to reproduce
description: Please provide a code sample that reproduces the issue.
placeholder: |
```php
<?php
require __DIR__ . '/vendor/autoload.php';
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
$section->...
```
validations:
required: true
- type: input
id: phpword-version
attributes:
label: PHPWord version(s) where the bug happened
placeholder: "e.g., 1.2.0 or master"
validations:
required: true
- type: input
id: php-version
attributes:
label: PHP version(s) where the bug happened
placeholder: "e.g., 7.1 or 8.2"
validations:
required: true
- type: checkboxes
attributes:
label: Priority
description: Funded tickets have a higher priority.
options:
- label: I want to crowdfund the bug fix (with [@algora-io](https://docs.algora.io/bounties/overview)) and fund a community developer.
required: false
- label: I want to pay the bug fix and fund a maintainer for that. (Contact @Progi1984)
required: false
35 changes: 35 additions & 0 deletions .github/ISSUE_TEMPLATE/2_feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: 💡 Feature request
description: Suggest an idea for this project
labels: [ "Change Request" ]
body:
- type: markdown
attributes:
value: |
### ❗️ Read this before submitting your bug report:
- **Write in English/French.** Reports in all other languages will be closed.
- **Provide as much detail as possible**
- Attachments : Error logs, Screenshots, Document files (generated and expected).
- If the issue cannot be reproduced, it cannot be fixed.
- type: textarea
id: problem
attributes:
label: Describe the problem
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Describe the expected behavior
description: A clear and concise description of what you expected to happen. If possible, add screenshots, document files (expected).
validations:
required: true
- type: checkboxes
attributes:
label: Priority
description: Funded tickets have a higher priority.
options:
- label: I want to crowdfund the feature (with [@algora-io](https://docs.algora.io/bounties/overview)) and fund a community developer.
required: false
- label: I want to pay the feature and fund a maintainer for that. (Contact @Progi1984)
required: false
38 changes: 0 additions & 38 deletions .github/ISSUE_TEMPLATE/bug_report.md

This file was deleted.

22 changes: 0 additions & 22 deletions .github/ISSUE_TEMPLATE/feature_request.md

This file was deleted.

14 changes: 0 additions & 14 deletions .github/ISSUE_TEMPLATE/how-to-use.md

This file was deleted.

7 changes: 4 additions & 3 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Fixes # (issue)

### Checklist:

- [ ] I have run `composer run-script check --timeout=0` and no errors were reported
- [ ] The new code is covered by unit tests (check build/coverage for coverage report)
- [ ] I have updated the documentation to describe the changes
- [ ] My CI is :green_circle:
- [ ] I have covered by unit tests my new code (check build/coverage for coverage report)
- [ ] I have updated the [documentation](https://github.com/PHPOffice/PHPWord/tree/master/docs) to describe the changes
- [ ] I have updated the [changelog](https://github.com/PHPOffice/PHPWord/blob/master/docs/changes/2.x/2.0.0.md)
3 changes: 2 additions & 1 deletion docs/changes/1.x/1.2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,5 @@


### BC Breaks
- Removed dependency `laminas/laminas-escaper`
- Removed dependency `laminas/laminas-escaper`
- *Unintended Break* TemplateProcessor Does Not Persist File After Destruct. [#2539](https://github.com/PHPOffice/PHPWord/issues/2539) To be fixed by [#2545](https://github.com/PHPOffice/PHPWord/pull/2545
10 changes: 8 additions & 2 deletions docs/changes/2.x/2.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@

## Enhancements

- IOFactory : Added extractVariables method to extract variables from a document [@sibalonat](https://github.com/sibalonat) in [#2515](https://github.com/PHPOffice/PHPWord/pull/2515)

### Bug fixes

- MsDoc Reader : Correct Font Size Calculation by [@oleibman](https://github.com/oleibman) fixing [#2526](https://github.com/PHPOffice/PHPWord/issues/2526) in [#2531](https://github.com/PHPOffice/PHPWord/pull/2531)
- TemplateProcessor Persist File After Destruct [@oleibman](https://github.com/oleibman) fixing [#2539](https://github.com/PHPOffice/PHPWord/issues/2539) in [#2542](https://github.com/PHPOffice/PHPWord/pull/2531)
- Html Reader : Process Titles as Headings not Paragraphs [@0b10011](https://github.com/0b10011) and [@oleibman](https://github.com/oleibman) Issue [#1692](https://github.com/PHPOffice/PHPWord/issues/1692) PR [#2533](https://github.com/PHPOffice/PHPWord/pull/2533)
- TemplateProcessor Persist File After Destruct [@oleibman](https://github.com/oleibman) fixing [#2539](https://github.com/PHPOffice/PHPWord/issues/2539) in [#2545](https://github.com/PHPOffice/PHPWord/pull/2545)
- bug: TemplateProcessor fix multiline values [@gimler](https://github.com/gimler) fixing [#268](https://github.com/PHPOffice/PHPWord/issues/268), [#2323](https://github.com/PHPOffice/PHPWord/issues/2323) and [#2486](https://github.com/PHPOffice/PHPWord/issues/2486) in [#2522](https://github.com/PHPOffice/PHPWord/pull/2522)

- 32-bit Problem in PasswordEncoder [@oleibman](https://github.com/oleibman) fixing [#2550](https://github.com/PHPOffice/PHPWord/issues/2550) in [#2551](https://github.com/PHPOffice/PHPWord/pull/2551)

### Miscellaneous

Expand All @@ -18,6 +23,7 @@
- Bump phpmd/phpmd from 2.14.1 to 2.15.0 by [@dependabot](https://github.com/dependabot) in [#2538](https://github.com/PHPOffice/PHPWord/pull/2538)
- Bump phpunit/phpunit from 9.6.14 to 9.6.15 by [@dependabot](https://github.com/dependabot) in [#2537](https://github.com/PHPOffice/PHPWord/pull/2537)
- Bump symfony/process from 5.4.28 to 5.4.34 by [@dependabot](https://github.com/dependabot) in [#2536](https://github.com/PHPOffice/PHPWord/pull/2536)
- Allow rgb() when converting Html [@oleibman](https://github.com/oleibman) fixing [#2508](https://github.com/PHPOffice/PHPWord/issues/2508) in [#2512](https://github.com/PHPOffice/PHPWord/pull/2512)
- Allow rgb() when converting Html by [@oleibman](https://github.com/oleibman) fixing [#2508](https://github.com/PHPOffice/PHPWord/issues/2508) in [#2512](https://github.com/PHPOffice/PHPWord/pull/2512)
- Improved Issue Template by [@Progi1984](https://github.com/Progi1984) in [#2609](https://github.com/PHPOffice/PHPWord/pull/2609)

### BC Breaks
14 changes: 14 additions & 0 deletions samples/Sample_44_ExtractVariablesFromReaderWord2007.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

include_once 'Sample_Header.php';

// Read contents
$name = basename(__FILE__, '.php');

$source = __DIR__ . "/resources/{$name}.docx";

echo date('H:i:s'), " Reading contents from `{$source}`", EOL;

$variables = \PhpOffice\PhpWord\IOFactory::extractVariables($source);

var_dump($variables);
Binary file not shown.
39 changes: 39 additions & 0 deletions src/PhpWord/IOFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

namespace PhpOffice\PhpWord;

use PhpOffice\PhpWord\Element\Text;
use PhpOffice\PhpWord\Element\TextRun;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\Reader\ReaderInterface;
use PhpOffice\PhpWord\Writer\WriterInterface;
Expand Down Expand Up @@ -89,6 +91,43 @@ public static function load($filename, $readerName = 'Word2007')
return $reader->load($filename);
}

/**
* Loads PhpWord ${variable} from file.
*
* @param string $filename The name of the file
*
* @return array The extracted variables
*/
public static function extractVariables(string $filename, string $readerName = 'Word2007'): array
{
/** @var \PhpOffice\PhpWord\Reader\ReaderInterface $reader */
$reader = self::createReader($readerName);
$document = $reader->load($filename);
$extractedVariables = [];
foreach ($document->getSections() as $section) {
$concatenatedText = '';
foreach ($section->getElements() as $element) {
if ($element instanceof TextRun) {
foreach ($element->getElements() as $textElement) {
if ($textElement instanceof Text) {
$text = $textElement->getText();
$concatenatedText .= $text;
}
}
}
}
preg_match_all('/\$\{([^}]+)\}/', $concatenatedText, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $match) {
$trimmedMatch = trim($match);
$extractedVariables[] = $trimmedMatch;
}
}
}

return $extractedVariables;
}

/**
* Check if it's a concrete class (not abstract nor interface).
*
Expand Down
17 changes: 14 additions & 3 deletions src/PhpWord/Shared/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
*/
class Html
{
private const RGB_REGEXP = '/^\s*rgb\s*[(]\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*[)]\s*$/';

protected static $listIndex = 0;

protected static $xpath;
Expand Down Expand Up @@ -143,7 +145,7 @@ protected static function parseInlineStyle($node, $styles = [])
break;
case 'bgcolor':
// tables, rows, cells e.g. <tr bgColor="#FF0000">
$styles['bgColor'] = trim($val, '# ');
$styles['bgColor'] = self::convertRgb($val);

break;
case 'valign':
Expand Down Expand Up @@ -722,11 +724,11 @@ protected static function parseStyleDeclarations(array $selectors, array $styles

break;
case 'color':
$styles['color'] = trim($value, '#');
$styles['color'] = self::convertRgb($value);

break;
case 'background-color':
$styles['bgColor'] = trim($value, '#');
$styles['bgColor'] = self::convertRgb($value);

break;
case 'line-height':
Expand Down Expand Up @@ -1172,4 +1174,13 @@ protected static function parseHorizRule($node, $element): void
// - line - that is a shape, has different behaviour
// - repeated text, e.g. underline "_", because of unpredictable line wrapping
}

private static function convertRgb(string $rgb): string
{
if (preg_match(self::RGB_REGEXP, $rgb, $matches) === 1) {
return sprintf('%02X%02X%02X', $matches[1], $matches[2], $matches[3]);
}

return trim($rgb, '# ');
}
}
11 changes: 7 additions & 4 deletions src/PhpWord/Shared/Microsoft/PasswordEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ class PasswordEncoder
const ALGORITHM_MAC = 'MAC';
const ALGORITHM_HMAC = 'HMAC';

private const ALL_ONE_BITS = (PHP_INT_SIZE > 4) ? 0xFFFFFFFF : -1;
private const HIGH_ORDER_BIT = (PHP_INT_SIZE > 4) ? 0x80000000 : PHP_INT_MIN;

/**
* Mapping between algorithm name and algorithm ID.
*
Expand Down Expand Up @@ -128,7 +131,7 @@ public static function hashPassword($password, $algorithmName = self::ALGORITHM_
// build low-order word and hig-order word and combine them
$combinedKey = self::buildCombinedKey($byteChars);
// build reversed hexadecimal string
$hex = str_pad(strtoupper(dechex($combinedKey & 0xFFFFFFFF)), 8, '0', \STR_PAD_LEFT);
$hex = str_pad(strtoupper(dechex($combinedKey & self::ALL_ONE_BITS)), 8, '0', \STR_PAD_LEFT);
$reversedHex = $hex[6] . $hex[7] . $hex[4] . $hex[5] . $hex[2] . $hex[3] . $hex[0] . $hex[1];

$generatedKey = mb_convert_encoding($reversedHex, 'UCS-2LE', 'UTF-8');
Expand Down Expand Up @@ -232,10 +235,10 @@ private static function buildCombinedKey($byteChars)
*/
private static function int32($value)
{
$value = ($value & 0xFFFFFFFF);
$value = $value & self::ALL_ONE_BITS;

if ($value & 0x80000000) {
$value = -((~$value & 0xFFFFFFFF) + 1);
if ($value & self::HIGH_ORDER_BIT) {
$value = -((~$value & self::ALL_ONE_BITS) + 1);
}

return $value;
Expand Down
Loading

0 comments on commit c0f2310

Please sign in to comment.