Merge branch 'develop' into parse_drawings
This commit is contained in:
commit
de83da2bbf
|
|
@ -0,0 +1,21 @@
|
|||
# build config
|
||||
/.scrutinizer.yml export-ignore
|
||||
/.travis.yml export-ignore
|
||||
/php_cs.dist export-ignore
|
||||
/phpmd.xml.dist export-ignore
|
||||
/phpstan.neon export-ignore
|
||||
|
||||
/composer.lock export-ignore
|
||||
|
||||
# git files
|
||||
/.gitignore export-ignore
|
||||
/.gitattributes export-ignore
|
||||
|
||||
# project directories
|
||||
/build export-ignore
|
||||
/docs export-ignore
|
||||
/samples export-ignore
|
||||
|
||||
# tests
|
||||
/phpunit.xml.dist export-ignore
|
||||
/tests export-ignore
|
||||
|
|
@ -19,7 +19,7 @@ tools:
|
|||
config:
|
||||
ruleset: phpmd.xml.dist
|
||||
external_code_coverage:
|
||||
enabled: true
|
||||
enabled: false
|
||||
timeout: 1200
|
||||
php_cpd: true
|
||||
# php_sim: # Temporarily disabled to allow focus on things other than duplicates
|
||||
|
|
|
|||
12
.travis.yml
12
.travis.yml
|
|
@ -37,7 +37,7 @@ before_script:
|
|||
- composer self-update
|
||||
- travis_wait composer install --prefer-source
|
||||
## PHPDocumentor
|
||||
- mkdir -p build/docs
|
||||
##- mkdir -p build/docs
|
||||
- mkdir -p build/coverage
|
||||
|
||||
script:
|
||||
|
|
@ -52,10 +52,8 @@ script:
|
|||
## PHPLOC
|
||||
- if [ -z "$COVERAGE" ]; then ./vendor/bin/phploc src/ ; fi
|
||||
## PHPDocumentor
|
||||
- if [ -z "$COVERAGE" ]; then ./vendor/bin/phpdoc -q -d ./src -t ./build/docs --ignore "*/src/PhpWord/Shared/*/*" --template="responsive-twig" ; fi
|
||||
##- if [ -z "$COVERAGE" ]; then ./vendor/bin/phpdoc -q -d ./src -t ./build/docs --ignore "*/src/PhpWord/Shared/*/*" --template="responsive-twig" ; fi
|
||||
|
||||
after_script:
|
||||
## PHPDocumentor
|
||||
- bash .travis_shell_after_success.sh
|
||||
## Scrutinizer
|
||||
- if [ -n "$COVERAGE" ]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml ; fi
|
||||
after_success:
|
||||
## Coveralls
|
||||
- if [ -n "$COVERAGE" ]; then travis_retry php vendor/bin/php-coveralls -v ; fi
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "--DEBUG--"
|
||||
echo "TRAVIS_REPO_SLUG: $TRAVIS_REPO_SLUG"
|
||||
echo "TRAVIS_PHP_VERSION: $TRAVIS_PHP_VERSION"
|
||||
echo "TRAVIS_PULL_REQUEST: $TRAVIS_PULL_REQUEST"
|
||||
|
||||
if [ "$TRAVIS_REPO_SLUG" == "PHPOffice/PHPWord" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then
|
||||
|
||||
echo -e "Publishing PHPDoc...\n"
|
||||
|
||||
cp -R build/docs $HOME/docs-latest
|
||||
cp -R build/coverage $HOME/coverage-latest
|
||||
|
||||
cd $HOME
|
||||
git config --global user.email "travis@travis-ci.org"
|
||||
git config --global user.name "travis-ci"
|
||||
git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/PHPOffice/PHPWord gh-pages > /dev/null
|
||||
|
||||
cd gh-pages
|
||||
echo "--DEBUG : Suppression"
|
||||
git rm -rf ./docs/$TRAVIS_BRANCH
|
||||
|
||||
echo "--DEBUG : Dossier"
|
||||
mkdir -p docs/$TRAVIS_BRANCH
|
||||
mkdir -p coverage/$TRAVIS_BRANCH
|
||||
|
||||
echo "--DEBUG : Copie"
|
||||
cp -Rf $HOME/docs-latest/* ./docs/$TRAVIS_BRANCH/
|
||||
cp -Rf $HOME/coverage-latest/* ./coverage/$TRAVIS_BRANCH/
|
||||
|
||||
echo "--DEBUG : Git"
|
||||
git add -f .
|
||||
git commit -m "PHPDocumentor (Travis Build: $TRAVIS_BUILD_NUMBER - Branch: $TRAVIS_BRANCH)"
|
||||
git push -fq origin gh-pages > /dev/null
|
||||
|
||||
echo -e "Published PHPDoc to gh-pages.\n"
|
||||
|
||||
fi
|
||||
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -20,6 +20,11 @@ v0.15.0 (?? ??? 2018)
|
|||
- Added support for Image text wrapping distance @troosan #1310
|
||||
- Added parsing of CSS line-height and text-indent in HTML reader @troosan #1316
|
||||
- Added the ability to enable gridlines and axislabels on charts @FrankMeyer #576
|
||||
- Add support for table indent (tblInd) @Trainmaster #1343
|
||||
- Added parsing of internal links in HTML reader @lalop #1336
|
||||
- Several improvements to charts @JAEK-S #1332
|
||||
- Add parsing of html image in base64 format @jgpATs2w #1382
|
||||
- Added Support for Indentation & Tabs on RTF Writer. @smaug1985 #1405
|
||||
|
||||
### Fixed
|
||||
- Fix reading of docx default style - @troosan #1238
|
||||
|
|
@ -33,10 +38,15 @@ v0.15.0 (?? ??? 2018)
|
|||
- Fix parsing of Heading and Title formating @troosan @gthomas2 #465
|
||||
- Fix Dateformat typo, fix hours casing, add Month-Day-Year formats @ComputerTinker #591
|
||||
- Support reading of w:drawing for documents produced by word 2011+ @gthomas2 #464 #1324
|
||||
- Fix missing column width in ODText writer @potofcoffee #413
|
||||
- Disable entity loader before parsing XML to avoid XXE injection @Tom4t0 #1427
|
||||
|
||||
### Changed
|
||||
- Remove zend-stdlib dependency @Trainmaster #1284
|
||||
- The default unit for `\PhpOffice\PhpWord\Style\Image` changed from `px` to `pt`.
|
||||
|
||||
### Miscelaneous
|
||||
- Drop GitHub pages, switch to coveralls for code coverage analysis @czosel #1360
|
||||
|
||||
v0.14.0 (29 Dec 2017)
|
||||
----------------------
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
[](https://packagist.org/packages/phpoffice/phpword)
|
||||
[](https://travis-ci.org/PHPOffice/PHPWord)
|
||||
[](https://scrutinizer-ci.com/g/PHPOffice/PHPWord/)
|
||||
[](https://scrutinizer-ci.com/g/PHPOffice/PHPWord/)
|
||||
[](https://coveralls.io/github/PHPOffice/PHPWord?branch=develop)
|
||||
[](https://packagist.org/packages/phpoffice/phpword)
|
||||
[](https://packagist.org/packages/phpoffice/phpword)
|
||||
[](https://gitter.im/PHPOffice/PHPWord)
|
||||
|
|
|
|||
|
|
@ -64,15 +64,17 @@
|
|||
"phpoffice/common": "^0.2.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.0",
|
||||
"phpdocumentor/phpdocumentor":"2.*",
|
||||
"squizlabs/php_codesniffer": "^2.7",
|
||||
"friendsofphp/php-cs-fixer": "^2.0",
|
||||
"ext-zip": "*",
|
||||
"ext-gd": "*",
|
||||
"phpunit/phpunit": "^4.8.36 || ^7.0",
|
||||
"squizlabs/php_codesniffer": "^2.9",
|
||||
"friendsofphp/php-cs-fixer": "^2.2",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"phploc/phploc": "2.* || 3.* || 4.*",
|
||||
"dompdf/dompdf":"0.8.*",
|
||||
"tecnickcom/tcpdf": "6.*",
|
||||
"mpdf/mpdf": "5.* || 6.* || 7.*"
|
||||
"mpdf/mpdf": "5.7.4 || 6.* || 7.*",
|
||||
"php-coveralls/php-coveralls": "1.1.0 || ^2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-zip": "Allows writing OOXML and ODF",
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ To add an image, use the ``addImage`` method to sections, headers, footers, text
|
|||
|
||||
$section->addImage($src, [$style]);
|
||||
|
||||
- ``$src``. String path to a local image, URL of a remote image or the image data, as a string.
|
||||
- ``$src``. String path to a local image, URL of a remote image or the image data, as a string. Warning: Do not pass user-generated strings here, as that would allow an attacker to read arbitrary files or perform server-side request forgery by passing file paths or URLs instead of image data.
|
||||
- ``$style``. See :ref:`image-style`.
|
||||
|
||||
Examples:
|
||||
|
|
@ -435,8 +435,8 @@ Available line style attributes:
|
|||
- ``dash``. Line types: dash, rounddot, squaredot, dashdot, longdash, longdashdot, longdashdotdot.
|
||||
- ``beginArrow``. Start type of arrow: block, open, classic, diamond, oval.
|
||||
- ``endArrow``. End type of arrow: block, open, classic, diamond, oval.
|
||||
- ``width``. Line-object width in pt.
|
||||
- ``height``. Line-object height in pt.
|
||||
- ``width``. Line-object width in *pt*.
|
||||
- ``height``. Line-object height in *pt*.
|
||||
- ``flip``. Flip the line element: true, false.
|
||||
|
||||
Chart
|
||||
|
|
|
|||
|
|
@ -54,7 +54,5 @@ Example:
|
|||
Using samples
|
||||
-------------
|
||||
|
||||
After installation, you can browse and use the samples that we've
|
||||
provided, either by command line or using browser. If you can access
|
||||
your PHPWord library folder using browser, point your browser to the
|
||||
``samples`` folder, e.g. ``http://localhost/PhpWord/samples/``.
|
||||
More examples are provided in the ``samples`` directory.
|
||||
For an easy access to those samples launch ``php -S localhost:8000`` in the samples directory then browse to http://localhost:8000 to view the samples.
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ Available Table style options:
|
|||
- ``border(Top|Right|Bottom|Left)Color``. Border color, e.g. '9966CC'.
|
||||
- ``border(Top|Right|Bottom|Left)Size``. Border size in *twip*.
|
||||
- ``cellMargin(Top|Right|Bottom|Left)``. Cell margin in *twip*.
|
||||
- ``indent``. Table indent from leading margin. Must be an instance of ``\PhpOffice\PhpWord\ComplexType\TblWidth``.
|
||||
- ``width``. Table width in percent.
|
||||
- ``unit``. The unit to use for the width. One of ``\PhpOffice\PhpWord\SimpleType\TblWidth``. Defaults to *auto*.
|
||||
- ``layout``. Table layout, either *fixed* or *autofit* See ``\PhpOffice\PhpWord\Style\Table`` for constants.
|
||||
|
|
@ -149,10 +150,10 @@ Image
|
|||
Available Image style options:
|
||||
|
||||
- ``alignment``. See ``\PhpOffice\PhpWord\SimpleType\Jc`` class for the details.
|
||||
- ``height``. Height in pixels.
|
||||
- ``height``. Height in *pt*.
|
||||
- ``marginLeft``. Left margin in inches, can be negative.
|
||||
- ``marginTop``. Top margin in inches, can be negative.
|
||||
- ``width``. Width in pixels.
|
||||
- ``width``. Width in *pt*.
|
||||
- ``wrappingStyle``. Wrapping style, *inline*, *square*, *tight*, *behind*, or *infront*.
|
||||
- ``wrapDistanceTop``. Top text wrapping in pixels.
|
||||
- ``wrapDistanceBottom``. Bottom text wrapping in pixels.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
includes:
|
||||
- vendor/phpstan/phpstan/conf/config.level1.neon
|
||||
parameters:
|
||||
memory-limit: 200000
|
||||
memory-limit: 20000000
|
||||
autoload_directories:
|
||||
- tests
|
||||
autoload_files:
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false">
|
||||
stopOnFailure="false">
|
||||
<testsuites>
|
||||
<testsuite name="PhpWord Test Suite">
|
||||
<directory>./tests/PhpWord</directory>
|
||||
|
|
@ -22,7 +21,7 @@
|
|||
</whitelist>
|
||||
</filter>
|
||||
<logging>
|
||||
<log type="coverage-html" target="./build/coverage" charset="UTF-8" highlight="true" />
|
||||
<log type="coverage-html" target="./build/coverage" />
|
||||
<log type="coverage-clover" target="./build/logs/clover.xml" />
|
||||
</logging>
|
||||
</phpunit>
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
use PhpOffice\PhpWord\Style\Font;
|
||||
use PhpOffice\PhpWord\Style\Paragraph;
|
||||
|
||||
include_once 'Sample_Header.php';
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ $templateProcessor->setValue('userPhone#3', '+1 428 889 775');
|
|||
echo date('H:i:s'), ' Saving the result document...', EOL;
|
||||
$templateProcessor->saveAs('results/Sample_07_TemplateCloneRow.docx');
|
||||
|
||||
echo getEndingNotes(array('Word2007' => 'docx'));
|
||||
echo getEndingNotes(array('Word2007' => 'docx'), 'results/Sample_07_TemplateCloneRow.docx');
|
||||
if (!CLI) {
|
||||
include_once 'Sample_Footer.php';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ $templateProcessor->deleteBlock('DELETEME');
|
|||
echo date('H:i:s'), ' Saving the result document...', EOL;
|
||||
$templateProcessor->saveAs('results/Sample_23_TemplateBlock.docx');
|
||||
|
||||
echo getEndingNotes(array('Word2007' => 'docx'));
|
||||
echo getEndingNotes(array('Word2007' => 'docx'), 'results/Sample_23_TemplateBlock.docx');
|
||||
if (!CLI) {
|
||||
include_once 'Sample_Footer.php';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ $html = '<h1>Adding element via HTML</h1>';
|
|||
$html .= '<p>Some well-formed HTML snippet needs to be used</p>';
|
||||
$html .= '<p>With for example <strong>some<sup>1</sup> <em>inline</em> formatting</strong><sub>1</sub></p>';
|
||||
|
||||
$html .= '<p>A link to <a href="http://phpword.readthedocs.io/">Read the docs</a></p>';
|
||||
$html .= '<p>A link to <a href="http://phpword.readthedocs.io/" style="text-decoration: underline">Read the docs</a></p>';
|
||||
|
||||
$html .= '<p lang="he-IL" style="text-align: right; direction: rtl">היי, זה פסקה מימין לשמאל</p>';
|
||||
|
||||
|
|
|
|||
|
|
@ -6,15 +6,20 @@ include_once 'Sample_Header.php';
|
|||
// New Word document
|
||||
echo date('H:i:s'), ' Create new PhpWord object', EOL;
|
||||
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
||||
PhpOffice\PhpWord\Style::addTitleStyle(1, array('size' => 14));
|
||||
|
||||
// New section
|
||||
$section = $phpWord->addSection();
|
||||
$section->addTitle('This page demos fields');
|
||||
|
||||
// Add Field elements
|
||||
// See Element/Field.php for all options
|
||||
$section->addText('Date field:');
|
||||
$section->addField('DATE', array('dateformat' => 'dddd d MMMM yyyy H:mm:ss'), array('PreserveFormat'));
|
||||
|
||||
$section->addText('Style Ref field:');
|
||||
$section->addField('STYLEREF', array('StyleIdentifier' => 'Heading 1'));
|
||||
|
||||
$section->addText('Page field:');
|
||||
$section->addField('PAGE', array('format' => 'Arabic'));
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ $section = $phpWord->addSection();
|
|||
$section->addTitle('2D charts', 1);
|
||||
$section = $phpWord->addSection(array('colsNum' => 2, 'breakType' => 'continuous'));
|
||||
|
||||
$chartTypes = array('pie', 'doughnut', 'bar', 'column', 'line', 'area', 'scatter', 'radar');
|
||||
$twoSeries = array('bar', 'column', 'line', 'area', 'scatter', 'radar');
|
||||
$chartTypes = array('pie', 'doughnut', 'bar', 'column', 'line', 'area', 'scatter', 'radar', 'stacked_bar', 'percent_stacked_bar', 'stacked_column', 'percent_stacked_column');
|
||||
$twoSeries = array('bar', 'column', 'line', 'area', 'scatter', 'radar', 'stacked_bar', 'percent_stacked_bar', 'stacked_column', 'percent_stacked_column');
|
||||
$threeSeries = array('bar', 'line');
|
||||
$categories = array('A', 'B', 'C', 'D', 'E');
|
||||
$series1 = array(1, 3, 2, 5, 4);
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ function write($phpWord, $filename, $writers)
|
|||
$result .= EOL;
|
||||
}
|
||||
|
||||
$result .= getEndingNotes($writers);
|
||||
$result .= getEndingNotes($writers, $filename);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
|
@ -92,10 +92,10 @@ function write($phpWord, $filename, $writers)
|
|||
* Get ending notes
|
||||
*
|
||||
* @param array $writers
|
||||
*
|
||||
* @param mixed $filename
|
||||
* @return string
|
||||
*/
|
||||
function getEndingNotes($writers)
|
||||
function getEndingNotes($writers, $filename)
|
||||
{
|
||||
$result = '';
|
||||
|
||||
|
|
|
|||
|
|
@ -11,5 +11,15 @@
|
|||
<ul><li>Item 1</li><li>Item 2</li><ul><li>Item 2.1</li><li>Item 2.1</li></ul></ul>
|
||||
<p>Ordered (numbered) list:</p>
|
||||
<ol><li>Item 1</li><li>Item 2</li></ol>
|
||||
|
||||
<p style="line-height:2">Double height</p>
|
||||
|
||||
<h2>Includes images</h2>
|
||||
<img src="https://phpword.readthedocs.io/en/latest/_images/phpword.png" alt=""/>
|
||||
|
||||
<img src="https://localhost/gev/desarrollo/actividades/pruebas_14/5b064503587f7.jpeg" name="Imagen 12" align="bottom" width="208" height="183" border="0"/>
|
||||
<img src="http://localhost/gev/desarrollo/actividades/pruebas_14/5b064503589db.png" name="Imagen 13" align="bottom" width="143" height="202" border="0"/>
|
||||
<img src="http://localhost/gev/desarrollo/actividades/pruebas_14/5b0645035aac8.jpeg" name="Imagen 14" align="bottom" width="194" height="188" border="0"/>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
* @copyright 2010-2018 PHPWord contributors
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
|
||||
namespace PhpOffice\PhpWord\ComplexType;
|
||||
|
||||
use PhpOffice\PhpWord\SimpleType\TblWidth as TblWidthSimpleType;
|
||||
|
||||
/**
|
||||
* @see http://www.datypic.com/sc/ooxml/t-w_CT_TblWidth.html
|
||||
*/
|
||||
final class TblWidth
|
||||
{
|
||||
/** @var string */
|
||||
private $type;
|
||||
|
||||
/** @var int */
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @param int $value If omitted, then its value shall be assumed to be 0
|
||||
* @param string $type If omitted, then its value shall be assumed to be dxa
|
||||
*/
|
||||
public function __construct($value = 0, $type = TblWidthSimpleType::TWIP)
|
||||
{
|
||||
$this->value = $value;
|
||||
TblWidthSimpleType::validate($type);
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
|
|
@ -347,7 +347,7 @@ abstract class AbstractElement
|
|||
*
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractElement $container
|
||||
*/
|
||||
public function setParentContainer(AbstractElement $container)
|
||||
public function setParentContainer(self $container)
|
||||
{
|
||||
$this->parentContainer = substr(get_class($container), strrpos(get_class($container), '\\') + 1);
|
||||
$this->parent = $container;
|
||||
|
|
|
|||
|
|
@ -61,11 +61,12 @@ class Chart extends AbstractElement
|
|||
* @param array $categories
|
||||
* @param array $values
|
||||
* @param array $style
|
||||
* @param null|mixed $seriesName
|
||||
*/
|
||||
public function __construct($type, $categories, $values, $style = null)
|
||||
public function __construct($type, $categories, $values, $style = null, $seriesName = null)
|
||||
{
|
||||
$this->setType($type);
|
||||
$this->addSeries($categories, $values);
|
||||
$this->addSeries($categories, $values, $seriesName);
|
||||
$this->style = $this->setNewStyle(new ChartStyle(), $style, true);
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +87,7 @@ class Chart extends AbstractElement
|
|||
*/
|
||||
public function setType($value)
|
||||
{
|
||||
$enum = array('pie', 'doughnut', 'line', 'bar', 'column', 'area', 'radar', 'scatter');
|
||||
$enum = array('pie', 'doughnut', 'line', 'bar', 'stacked_bar', 'percent_stacked_bar', 'column', 'stacked_column', 'percent_stacked_column', 'area', 'radar', 'scatter');
|
||||
$this->type = $this->setEnumVal($value, $enum, 'pie');
|
||||
}
|
||||
|
||||
|
|
@ -95,10 +96,15 @@ class Chart extends AbstractElement
|
|||
*
|
||||
* @param array $categories
|
||||
* @param array $values
|
||||
* @param null|mixed $name
|
||||
*/
|
||||
public function addSeries($categories, $values)
|
||||
public function addSeries($categories, $values, $name = null)
|
||||
{
|
||||
$this->series[] = array('categories' => $categories, 'values' => $values);
|
||||
$this->series[] = array(
|
||||
'categories' => $categories,
|
||||
'values' => $values,
|
||||
'name' => $name,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -78,6 +78,10 @@ class Field extends AbstractElement
|
|||
'properties' => array(),
|
||||
'options' => array('PreserveFormat'),
|
||||
),
|
||||
'STYLEREF' => array(
|
||||
'properties' => array('StyleIdentifier' => ''),
|
||||
'options' => array('PreserveFormat'),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class OLEObject extends AbstractElement
|
|||
$this->style = $this->setNewStyle(new ImageStyle(), $style, true);
|
||||
$this->icon = realpath(__DIR__ . "/../resources/{$ext}.png");
|
||||
|
||||
return $this;
|
||||
return;
|
||||
}
|
||||
|
||||
throw new InvalidObjectException();
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class PreserveText extends AbstractElement
|
|||
/**
|
||||
* Text content
|
||||
*
|
||||
* @var string
|
||||
* @var string|array
|
||||
*/
|
||||
private $text;
|
||||
|
||||
|
|
@ -64,8 +64,6 @@ class PreserveText extends AbstractElement
|
|||
if (isset($matches[0])) {
|
||||
$this->text = $matches;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,7 +89,7 @@ class PreserveText extends AbstractElement
|
|||
/**
|
||||
* Get Text content
|
||||
*
|
||||
* @return string
|
||||
* @return string|array
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class Table extends AbstractElement
|
|||
public function countColumns()
|
||||
{
|
||||
$columnCount = 0;
|
||||
if (is_array($this->rows)) {
|
||||
|
||||
$rowCount = count($this->rows);
|
||||
for ($i = 0; $i < $rowCount; $i++) {
|
||||
/** @var \PhpOffice\PhpWord\Element\Row $row Type hint */
|
||||
|
|
@ -145,8 +145,30 @@ class Table extends AbstractElement
|
|||
$columnCount = $cellCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $columnCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* The first declared cell width for each column
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function findFirstDefinedCellWidths()
|
||||
{
|
||||
$cellWidths = array();
|
||||
|
||||
foreach ($this->rows as $row) {
|
||||
$cells = $row->getCells();
|
||||
if (count($cells) <= count($cellWidths)) {
|
||||
continue;
|
||||
}
|
||||
$cellWidths = array();
|
||||
foreach ($cells as $cell) {
|
||||
$cellWidths[] = $cell->getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
return $cellWidths;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class Title extends AbstractElement
|
|||
*/
|
||||
public function __construct($text, $depth = 1)
|
||||
{
|
||||
if (isset($text)) {
|
||||
if (is_string($text)) {
|
||||
$this->text = CommonText::toUTF8($text);
|
||||
} elseif ($text instanceof TextRun) {
|
||||
|
|
@ -69,15 +68,12 @@ class Title extends AbstractElement
|
|||
} else {
|
||||
throw new \InvalidArgumentException('Invalid text, should be a string or a TextRun');
|
||||
}
|
||||
}
|
||||
|
||||
$this->depth = $depth;
|
||||
$styleName = $depth === 0 ? 'Title' : "Heading_{$this->depth}";
|
||||
if (array_key_exists($styleName, Style::getStyles())) {
|
||||
$this->style = str_replace('_', '', $styleName);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Metadata;
|
||||
|
||||
use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder;
|
||||
use PhpOffice\Common\Microsoft\PasswordEncoder;
|
||||
use PhpOffice\PhpWord\SimpleType\DocProtect;
|
||||
|
||||
/**
|
||||
|
|
@ -113,7 +113,7 @@ class Protection
|
|||
/**
|
||||
* Set password
|
||||
*
|
||||
* @param $password
|
||||
* @param string $password
|
||||
* @return self
|
||||
*/
|
||||
public function setPassword($password)
|
||||
|
|
@ -136,7 +136,7 @@ class Protection
|
|||
/**
|
||||
* Set count for hash iterations
|
||||
*
|
||||
* @param $spinCount
|
||||
* @param int $spinCount
|
||||
* @return self
|
||||
*/
|
||||
public function setSpinCount($spinCount)
|
||||
|
|
@ -159,7 +159,7 @@ class Protection
|
|||
/**
|
||||
* Set algorithm
|
||||
*
|
||||
* @param $algorithm
|
||||
* @param string $algorithm
|
||||
* @return self
|
||||
*/
|
||||
public function setAlgorithm($algorithm)
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ use PhpOffice\PhpWord\Exception\Exception;
|
|||
* @method int addChart(Element\Chart $chart)
|
||||
* @method int addComment(Element\Comment $comment)
|
||||
*
|
||||
* @method Style\Paragraph addParagraphStyle(string $styleName, array $styles)
|
||||
* @method Style\Paragraph addParagraphStyle(string $styleName, mixed $styles)
|
||||
* @method Style\Font addFontStyle(string $styleName, mixed $fontStyle, mixed $paragraphStyle = null)
|
||||
* @method Style\Font addLinkStyle(string $styleName, mixed $styles)
|
||||
* @method Style\Font addTitleStyle(int $depth, mixed $fontStyle, mixed $paragraphStyle = null)
|
||||
* @method Style\Font addTitleStyle(mixed $depth, mixed $fontStyle, mixed $paragraphStyle = null)
|
||||
* @method Style\Table addTableStyle(string $styleName, mixed $styleTable, mixed $styleFirstRow = null)
|
||||
* @method Style\Numbering addNumberingStyle(string $styleName, mixed $styles)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
namespace PhpOffice\PhpWord\Reader\Word2007;
|
||||
|
||||
use PhpOffice\Common\XMLReader;
|
||||
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||
use PhpOffice\PhpWord\Element\AbstractContainer;
|
||||
use PhpOffice\PhpWord\Element\TextRun;
|
||||
use PhpOffice\PhpWord\Element\TrackChange;
|
||||
|
|
@ -486,6 +487,11 @@ abstract class AbstractPart
|
|||
if ($tablePositionNode !== null) {
|
||||
$style['position'] = $this->readTablePosition($xmlReader, $tablePositionNode);
|
||||
}
|
||||
|
||||
$indentNode = $xmlReader->getElement('w:tblInd', $styleNode);
|
||||
if ($indentNode !== null) {
|
||||
$style['indent'] = $this->readTableIndent($xmlReader, $indentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -517,6 +523,24 @@ abstract class AbstractPart
|
|||
return $this->readStyleDefs($xmlReader, $domNode, $styleDefs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read w:tblInd
|
||||
*
|
||||
* @param \PhpOffice\Common\XMLReader $xmlReader
|
||||
* @param \DOMElement $domNode
|
||||
* @return TblWidthComplexType
|
||||
*/
|
||||
private function readTableIndent(XMLReader $xmlReader, \DOMElement $domNode)
|
||||
{
|
||||
$styleDefs = array(
|
||||
'value' => array(self::READ_VALUE, '.', 'w:w'),
|
||||
'type' => array(self::READ_VALUE, '.', 'w:type'),
|
||||
);
|
||||
$styleDefs = $this->readStyleDefs($xmlReader, $domNode, $styleDefs);
|
||||
|
||||
return new TblWidthComplexType((int) $styleDefs['value'], $styleDefs['type']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read w:tcPr
|
||||
*
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class Settings extends AbstractPart
|
|||
*
|
||||
* @param XMLReader $xmlReader
|
||||
* @param PhpWord $phpWord
|
||||
* @param \DOMNode $node
|
||||
* @param \DOMElement $node
|
||||
*/
|
||||
protected function setThemeFontLang(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||
{
|
||||
|
|
@ -102,22 +102,24 @@ class Settings extends AbstractPart
|
|||
*
|
||||
* @param XMLReader $xmlReader
|
||||
* @param PhpWord $phpWord
|
||||
* @param \DOMNode $node
|
||||
* @param \DOMElement $node
|
||||
*/
|
||||
protected function setDocumentProtection(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||
{
|
||||
$documentProtection = $phpWord->getSettings()->getDocumentProtection();
|
||||
|
||||
$edit = $xmlReader->getAttribute('w:edit', $node);
|
||||
if ($edit !== null) {
|
||||
$documentProtection->setEditing($edit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the proof state
|
||||
*
|
||||
* @param XMLReader $xmlReader
|
||||
* @param PhpWord $phpWord
|
||||
* @param \DOMNode $node
|
||||
* @param \DOMElement $node
|
||||
*/
|
||||
protected function setProofState(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||
{
|
||||
|
|
@ -139,7 +141,7 @@ class Settings extends AbstractPart
|
|||
*
|
||||
* @param XMLReader $xmlReader
|
||||
* @param PhpWord $phpWord
|
||||
* @param \DOMNode $node
|
||||
* @param \DOMElement $node
|
||||
*/
|
||||
protected function setZoom(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||
{
|
||||
|
|
@ -156,7 +158,7 @@ class Settings extends AbstractPart
|
|||
*
|
||||
* @param XMLReader $xmlReader
|
||||
* @param PhpWord $phpWord
|
||||
* @param \DOMNode $node
|
||||
* @param \DOMElement $node
|
||||
*/
|
||||
protected function setRevisionView(XMLReader $xmlReader, PhpWord $phpWord, \DOMElement $node)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ namespace PhpOffice\PhpWord\Shared;
|
|||
use PhpOffice\PhpWord\Element\AbstractContainer;
|
||||
use PhpOffice\PhpWord\Element\Row;
|
||||
use PhpOffice\PhpWord\Element\Table;
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\SimpleType\Jc;
|
||||
use PhpOffice\PhpWord\SimpleType\NumberFormat;
|
||||
|
||||
|
|
@ -32,23 +33,30 @@ class Html
|
|||
{
|
||||
private static $listIndex = 0;
|
||||
private static $xpath;
|
||||
private static $options;
|
||||
|
||||
/**
|
||||
* Add HTML parts.
|
||||
*
|
||||
* Note: $stylesheet parameter is removed to avoid PHPMD error for unused parameter
|
||||
* Warning: Do not pass user-generated HTML here, as that would allow an attacker to read arbitrary
|
||||
* files or perform server-side request forgery by passing local file paths or URLs in <img>.
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Element\AbstractContainer $element Where the parts need to be added
|
||||
* @param string $html The code to parse
|
||||
* @param bool $fullHTML If it's a full HTML, no need to add 'body' tag
|
||||
* @param bool $preserveWhiteSpace If false, the whitespaces between nodes will be removed
|
||||
* @param array $options:
|
||||
* + IMG_SRC_SEARCH: optional to speed up images loading from remote url when files can be found locally
|
||||
* + IMG_SRC_REPLACE: optional to speed up images loading from remote url when files can be found locally
|
||||
*/
|
||||
public static function addHtml($element, $html, $fullHTML = false, $preserveWhiteSpace = true)
|
||||
public static function addHtml($element, $html, $fullHTML = false, $preserveWhiteSpace = true, $options = null)
|
||||
{
|
||||
/*
|
||||
* @todo parse $stylesheet for default styles. Should result in an array based on id, class and element,
|
||||
* which could be applied when such an element occurs in the parseNode function.
|
||||
*/
|
||||
self::$options = $options;
|
||||
|
||||
// Preprocess: remove all line ends, decode HTML entity,
|
||||
// fix ampersand and angle brackets and add body tag for HTML fragments
|
||||
|
|
@ -63,10 +71,11 @@ class Html
|
|||
}
|
||||
|
||||
// Load DOM
|
||||
libxml_disable_entity_loader(true);
|
||||
$dom = new \DOMDocument();
|
||||
$dom->preserveWhiteSpace = $preserveWhiteSpace;
|
||||
$dom->loadXML($html);
|
||||
self::$xpath = new \DOMXpath($dom);
|
||||
self::$xpath = new \DOMXPath($dom);
|
||||
$node = $dom->getElementsByTagName('body');
|
||||
|
||||
self::parseNode($node->item(0), $element);
|
||||
|
|
@ -139,6 +148,7 @@ class Html
|
|||
'sup' => array('Property', null, null, $styles, null, 'superScript', true),
|
||||
'sub' => array('Property', null, null, $styles, null, 'subScript', true),
|
||||
'span' => array('Span', $node, null, $styles, null, null, null),
|
||||
'font' => array('Span', $node, null, $styles, null, null, null),
|
||||
'table' => array('Table', $node, $element, $styles, null, null, null),
|
||||
'tr' => array('Row', $node, $element, $styles, null, null, null),
|
||||
'td' => array('Cell', $node, $element, $styles, null, null, null),
|
||||
|
|
@ -646,7 +656,52 @@ class Html
|
|||
break;
|
||||
}
|
||||
}
|
||||
$originSrc = $src;
|
||||
if (strpos($src, 'data:image') !== false) {
|
||||
$tmpDir = Settings::getTempDir() . '/';
|
||||
|
||||
$match = array();
|
||||
preg_match('/data:image\/(\w+);base64,(.+)/', $src, $match);
|
||||
|
||||
$src = $imgFile = $tmpDir . uniqid() . '.' . $match[1];
|
||||
|
||||
$ifp = fopen($imgFile, 'wb');
|
||||
|
||||
if ($ifp !== false) {
|
||||
fwrite($ifp, base64_decode($match[2]));
|
||||
fclose($ifp);
|
||||
}
|
||||
}
|
||||
$src = urldecode($src);
|
||||
|
||||
if (!is_file($src)
|
||||
&& !is_null(self::$options)
|
||||
&& isset(self::$options['IMG_SRC_SEARCH'])
|
||||
&& isset(self::$options['IMG_SRC_REPLACE'])) {
|
||||
$src = str_replace(self::$options['IMG_SRC_SEARCH'], self::$options['IMG_SRC_REPLACE'], $src);
|
||||
}
|
||||
|
||||
if (!is_file($src)) {
|
||||
if ($imgBlob = @file_get_contents($src)) {
|
||||
$tmpDir = Settings::getTempDir() . '/';
|
||||
$match = array();
|
||||
preg_match('/.+\.(\w+)$/', $src, $match);
|
||||
$src = $tmpDir . uniqid() . '.' . $match[1];
|
||||
|
||||
$ifp = fopen($src, 'wb');
|
||||
|
||||
if ($ifp !== false) {
|
||||
fwrite($ifp, $imgBlob);
|
||||
fclose($ifp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_file($src)) {
|
||||
$newElement = $element->addImage($src, $style);
|
||||
} else {
|
||||
throw new \Exception("Could not load image $originSrc");
|
||||
}
|
||||
|
||||
return $newElement;
|
||||
}
|
||||
|
|
@ -719,7 +774,11 @@ class Html
|
|||
break;
|
||||
}
|
||||
}
|
||||
self::parseInlineStyle($node, $styles['font']);
|
||||
$styles['font'] = self::parseInlineStyle($node, $styles['font']);
|
||||
|
||||
if (strpos($target, '#') === 0) {
|
||||
return $element->addLink(substr($target, 1), $node->textContent, $styles['font'], $styles['paragraph'], true);
|
||||
}
|
||||
|
||||
return $element->addLink($target, $node->textContent, $styles['font'], $styles['paragraph']);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,235 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
* @copyright 2010-2018 PHPWord contributors
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
|
||||
namespace PhpOffice\PhpWord\Shared\Microsoft;
|
||||
|
||||
/**
|
||||
* Password encoder for microsoft office applications
|
||||
*/
|
||||
class PasswordEncoder
|
||||
{
|
||||
const ALGORITHM_MD2 = 'MD2';
|
||||
const ALGORITHM_MD4 = 'MD4';
|
||||
const ALGORITHM_MD5 = 'MD5';
|
||||
const ALGORITHM_SHA_1 = 'SHA-1';
|
||||
const ALGORITHM_SHA_256 = 'SHA-256';
|
||||
const ALGORITHM_SHA_384 = 'SHA-384';
|
||||
const ALGORITHM_SHA_512 = 'SHA-512';
|
||||
const ALGORITHM_RIPEMD = 'RIPEMD';
|
||||
const ALGORITHM_RIPEMD_160 = 'RIPEMD-160';
|
||||
const ALGORITHM_MAC = 'MAC';
|
||||
const ALGORITHM_HMAC = 'HMAC';
|
||||
|
||||
/**
|
||||
* Mapping between algorithm name and algorithm ID
|
||||
*
|
||||
* @var array
|
||||
* @see https://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.writeprotection.cryptographicalgorithmsid(v=office.14).aspx
|
||||
*/
|
||||
private static $algorithmMapping = array(
|
||||
self::ALGORITHM_MD2 => array(1, 'md2'),
|
||||
self::ALGORITHM_MD4 => array(2, 'md4'),
|
||||
self::ALGORITHM_MD5 => array(3, 'md5'),
|
||||
self::ALGORITHM_SHA_1 => array(4, 'sha1'),
|
||||
self::ALGORITHM_MAC => array(5, ''), // 'mac' -> not possible with hash()
|
||||
self::ALGORITHM_RIPEMD => array(6, 'ripemd'),
|
||||
self::ALGORITHM_RIPEMD_160 => array(7, 'ripemd160'),
|
||||
self::ALGORITHM_HMAC => array(9, ''), //'hmac' -> not possible with hash()
|
||||
self::ALGORITHM_SHA_256 => array(12, 'sha256'),
|
||||
self::ALGORITHM_SHA_384 => array(13, 'sha384'),
|
||||
self::ALGORITHM_SHA_512 => array(14, 'sha512'),
|
||||
);
|
||||
|
||||
private static $initialCodeArray = array(
|
||||
0xE1F0,
|
||||
0x1D0F,
|
||||
0xCC9C,
|
||||
0x84C0,
|
||||
0x110C,
|
||||
0x0E10,
|
||||
0xF1CE,
|
||||
0x313E,
|
||||
0x1872,
|
||||
0xE139,
|
||||
0xD40F,
|
||||
0x84F9,
|
||||
0x280C,
|
||||
0xA96A,
|
||||
0x4EC3,
|
||||
);
|
||||
|
||||
private static $encryptionMatrix = array(
|
||||
array(0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09),
|
||||
array(0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF),
|
||||
array(0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0),
|
||||
array(0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40),
|
||||
array(0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5),
|
||||
array(0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A),
|
||||
array(0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9),
|
||||
array(0x47D3, 0x8FA6, 0x0F6D, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0),
|
||||
array(0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC),
|
||||
array(0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10),
|
||||
array(0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168),
|
||||
array(0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C),
|
||||
array(0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD),
|
||||
array(0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC),
|
||||
array(0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4),
|
||||
);
|
||||
|
||||
private static $passwordMaxLength = 15;
|
||||
|
||||
/**
|
||||
* Create a hashed password that MS Word will be able to work with
|
||||
* @see https://blogs.msdn.microsoft.com/vsod/2010/04/05/how-to-set-the-editing-restrictions-in-word-using-open-xml-sdk-2-0/
|
||||
*
|
||||
* @param string $password
|
||||
* @param string $algorithmName
|
||||
* @param string $salt
|
||||
* @param int $spinCount
|
||||
* @return string
|
||||
*/
|
||||
public static function hashPassword($password, $algorithmName = self::ALGORITHM_SHA_1, $salt = null, $spinCount = 10000)
|
||||
{
|
||||
$origEncoding = mb_internal_encoding();
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
$password = mb_substr($password, 0, min(self::$passwordMaxLength, mb_strlen($password)));
|
||||
|
||||
// Get the single-byte values by iterating through the Unicode characters of the truncated password.
|
||||
// For each character, if the low byte is not equal to 0, take it. Otherwise, take the high byte.
|
||||
$passUtf8 = mb_convert_encoding($password, 'UCS-2LE', 'UTF-8');
|
||||
$byteChars = array();
|
||||
|
||||
for ($i = 0; $i < mb_strlen($password); $i++) {
|
||||
$byteChars[$i] = ord(substr($passUtf8, $i * 2, 1));
|
||||
|
||||
if ($byteChars[$i] == 0) {
|
||||
$byteChars[$i] = ord(substr($passUtf8, $i * 2 + 1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
$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');
|
||||
|
||||
// Implementation Notes List:
|
||||
// Word requires that the initial hash of the password with the salt not be considered in the count.
|
||||
// The initial hash of salt + key is not included in the iteration count.
|
||||
$algorithm = self::getAlgorithm($algorithmName);
|
||||
$generatedKey = hash($algorithm, $salt . $generatedKey, true);
|
||||
|
||||
for ($i = 0; $i < $spinCount; $i++) {
|
||||
$generatedKey = hash($algorithm, $generatedKey . pack('CCCC', $i, $i >> 8, $i >> 16, $i >> 24), true);
|
||||
}
|
||||
$generatedKey = base64_encode($generatedKey);
|
||||
|
||||
mb_internal_encoding($origEncoding);
|
||||
|
||||
return $generatedKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get algorithm from self::$algorithmMapping
|
||||
*
|
||||
* @param string $algorithmName
|
||||
* @return string
|
||||
*/
|
||||
private static function getAlgorithm($algorithmName)
|
||||
{
|
||||
$algorithm = self::$algorithmMapping[$algorithmName][1];
|
||||
if ($algorithm == '') {
|
||||
$algorithm = 'sha1';
|
||||
}
|
||||
|
||||
return $algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the algorithm ID
|
||||
*
|
||||
* @param string $algorithmName
|
||||
* @return int
|
||||
*/
|
||||
public static function getAlgorithmId($algorithmName)
|
||||
{
|
||||
return self::$algorithmMapping[$algorithmName][0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build combined key from low-order word and high-order word
|
||||
*
|
||||
* @param array $byteChars byte array representation of password
|
||||
* @return int
|
||||
*/
|
||||
private static function buildCombinedKey($byteChars)
|
||||
{
|
||||
$byteCharsLength = count($byteChars);
|
||||
// Compute the high-order word
|
||||
// Initialize from the initial code array (see above), depending on the passwords length.
|
||||
$highOrderWord = self::$initialCodeArray[$byteCharsLength - 1];
|
||||
|
||||
// For each character in the password:
|
||||
// For every bit in the character, starting with the least significant and progressing to (but excluding)
|
||||
// the most significant, if the bit is set, XOR the key’s high-order word with the corresponding word from
|
||||
// the Encryption Matrix
|
||||
for ($i = 0; $i < $byteCharsLength; $i++) {
|
||||
$tmp = self::$passwordMaxLength - $byteCharsLength + $i;
|
||||
$matrixRow = self::$encryptionMatrix[$tmp];
|
||||
for ($intBit = 0; $intBit < 7; $intBit++) {
|
||||
if (($byteChars[$i] & (0x0001 << $intBit)) != 0) {
|
||||
$highOrderWord = ($highOrderWord ^ $matrixRow[$intBit]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute low-order word
|
||||
// Initialize with 0
|
||||
$lowOrderWord = 0;
|
||||
// For each character in the password, going backwards
|
||||
for ($i = $byteCharsLength - 1; $i >= 0; $i--) {
|
||||
// low-order word = (((low-order word SHR 14) AND 0x0001) OR (low-order word SHL 1) AND 0x7FFF)) XOR character
|
||||
$lowOrderWord = (((($lowOrderWord >> 14) & 0x0001) | (($lowOrderWord << 1) & 0x7FFF)) ^ $byteChars[$i]);
|
||||
}
|
||||
// Lastly, low-order word = (((low-order word SHR 14) AND 0x0001) OR (low-order word SHL 1) AND 0x7FFF)) XOR strPassword length XOR 0xCE4B.
|
||||
$lowOrderWord = (((($lowOrderWord >> 14) & 0x0001) | (($lowOrderWord << 1) & 0x7FFF)) ^ $byteCharsLength ^ 0xCE4B);
|
||||
|
||||
// Combine the Low and High Order Word
|
||||
return self::int32(($highOrderWord << 16) + $lowOrderWord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate behaviour of (signed) int32
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @param int $value
|
||||
* @return int
|
||||
*/
|
||||
private static function int32($value)
|
||||
{
|
||||
$value = ($value & 0xFFFFFFFF);
|
||||
|
||||
if ($value & 0x80000000) {
|
||||
$value = -((~$value & 0xFFFFFFFF) + 1);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ class Style
|
|||
* Add paragraph style
|
||||
*
|
||||
* @param string $styleName
|
||||
* @param array $styles
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles
|
||||
* @return \PhpOffice\PhpWord\Style\Paragraph
|
||||
*/
|
||||
public static function addParagraphStyle($styleName, $styles)
|
||||
|
|
@ -51,8 +51,8 @@ class Style
|
|||
* Add font style
|
||||
*
|
||||
* @param string $styleName
|
||||
* @param array $fontStyle
|
||||
* @param array $paragraphStyle
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $fontStyle
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $paragraphStyle
|
||||
* @return \PhpOffice\PhpWord\Style\Font
|
||||
*/
|
||||
public static function addFontStyle($styleName, $fontStyle, $paragraphStyle = null)
|
||||
|
|
@ -64,7 +64,7 @@ class Style
|
|||
* Add link style
|
||||
*
|
||||
* @param string $styleName
|
||||
* @param array $styles
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles
|
||||
* @return \PhpOffice\PhpWord\Style\Font
|
||||
*/
|
||||
public static function addLinkStyle($styleName, $styles)
|
||||
|
|
@ -76,7 +76,7 @@ class Style
|
|||
* Add numbering style
|
||||
*
|
||||
* @param string $styleName
|
||||
* @param array $styleValues
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styleValues
|
||||
* @return \PhpOffice\PhpWord\Style\Numbering
|
||||
* @since 0.10.0
|
||||
*/
|
||||
|
|
@ -88,14 +88,14 @@ class Style
|
|||
/**
|
||||
* Add title style
|
||||
*
|
||||
* @param int $depth
|
||||
* @param array $fontStyle
|
||||
* @param array $paragraphStyle
|
||||
* @param int|null $depth Provide null to set title font
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $fontStyle
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $paragraphStyle
|
||||
* @return \PhpOffice\PhpWord\Style\Font
|
||||
*/
|
||||
public static function addTitleStyle($depth, $fontStyle, $paragraphStyle = null)
|
||||
{
|
||||
if ($depth == null) {
|
||||
if (empty($depth)) {
|
||||
$styleName = 'Title';
|
||||
} else {
|
||||
$styleName = "Heading_{$depth}";
|
||||
|
|
@ -141,7 +141,7 @@ class Style
|
|||
/**
|
||||
* Set default paragraph style
|
||||
*
|
||||
* @param array $styles Paragraph style definition
|
||||
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $styles Paragraph style definition
|
||||
* @return \PhpOffice\PhpWord\Style\Paragraph
|
||||
*/
|
||||
public static function setDefaultParagraphStyle($styles)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,60 @@ class Chart extends AbstractStyle
|
|||
private $is3d = false;
|
||||
|
||||
/**
|
||||
* A list of colors to use in the chart
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $colors = array();
|
||||
|
||||
/**
|
||||
* A list of display options for data labels
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $dataLabelOptions = array(
|
||||
'showVal' => true, // value
|
||||
'showCatName' => true, // category name
|
||||
'showLegendKey' => false, //show the cart legend
|
||||
'showSerName' => false, // series name
|
||||
'showPercent' => false,
|
||||
'showLeaderLines' => false,
|
||||
'showBubbleSize' => false,
|
||||
);
|
||||
|
||||
/**
|
||||
* A string that tells the writer where to write chart labels or to skip
|
||||
* "nextTo" - sets labels next to the axis (bar graphs on the left) (default)
|
||||
* "low" - labels on the left side of the graph
|
||||
* "high" - labels on the right side of the graph
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $categoryLabelPosition = 'nextTo';
|
||||
|
||||
/**
|
||||
* A string that tells the writer where to write chart labels or to skip
|
||||
* "nextTo" - sets labels next to the axis (bar graphs on the bottom) (default)
|
||||
* "low" - labels are below the graph
|
||||
* "high" - labels above the graph
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $valueLabelPosition = 'nextTo';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $categoryAxisTitle;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $valueAxisTitle;
|
||||
|
||||
private $majorTickMarkPos = 'none';
|
||||
|
||||
/*
|
||||
* Show labels for axis
|
||||
*
|
||||
* @var bool
|
||||
|
|
@ -146,6 +200,28 @@ class Chart extends AbstractStyle
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the list of colors to use in a chart.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getColors()
|
||||
{
|
||||
return $this->colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the colors to use in a chart.
|
||||
*
|
||||
* @param array $value a list of colors to use in the chart
|
||||
*/
|
||||
public function setColors($value = array())
|
||||
{
|
||||
$this->colors = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Show labels for axis
|
||||
*
|
||||
* @return bool
|
||||
|
|
@ -169,6 +245,31 @@ class Chart extends AbstractStyle
|
|||
}
|
||||
|
||||
/**
|
||||
* get the list of options for data labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDataLabelOptions()
|
||||
{
|
||||
return $this->dataLabelOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set values for data label options.
|
||||
* This will only change values for options defined in $this->dataLabelOptions, and cannot create new ones.
|
||||
*
|
||||
* @param array $values [description]
|
||||
*/
|
||||
public function setDataLabelOptions($values = array())
|
||||
{
|
||||
foreach (array_keys($this->dataLabelOptions) as $option) {
|
||||
if (isset($values[$option])) {
|
||||
$this->dataLabelOptions[$option] = $this->setBoolVal($values[$option], $this->dataLabelOptions[$option]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Show Gridlines for Y-Axis
|
||||
*
|
||||
* @return bool
|
||||
|
|
@ -192,6 +293,117 @@ class Chart extends AbstractStyle
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the categoryLabelPosition setting
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCategoryLabelPosition()
|
||||
{
|
||||
return $this->categoryLabelPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the categoryLabelPosition setting
|
||||
* "none" - skips writing labels
|
||||
* "nextTo" - sets labels next to the (bar graphs on the left)
|
||||
* "low" - labels on the left side of the graph
|
||||
* "high" - labels on the right side of the graph
|
||||
*
|
||||
* @param mixed $labelPosition
|
||||
* @return self
|
||||
*/
|
||||
public function setCategoryLabelPosition($labelPosition)
|
||||
{
|
||||
$enum = array('nextTo', 'low', 'high');
|
||||
$this->categoryLabelPosition = $this->setEnumVal($labelPosition, $enum, $this->categoryLabelPosition);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the valueAxisLabelPosition setting
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValueLabelPosition()
|
||||
{
|
||||
return $this->valueLabelPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the valueLabelPosition setting
|
||||
* "none" - skips writing labels
|
||||
* "nextTo" - sets labels next to the value
|
||||
* "low" - sets labels are below the graph
|
||||
* "high" - sets labels above the graph
|
||||
*
|
||||
* @param string
|
||||
* @param mixed $labelPosition
|
||||
*/
|
||||
public function setValueLabelPosition($labelPosition)
|
||||
{
|
||||
$enum = array('nextTo', 'low', 'high');
|
||||
$this->valueLabelPosition = $this->setEnumVal($labelPosition, $enum, $this->valueLabelPosition);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the categoryAxisTitle
|
||||
* @return string
|
||||
*/
|
||||
public function getCategoryAxisTitle()
|
||||
{
|
||||
return $this->categoryAxisTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title that appears on the category side of the chart
|
||||
* @param string $axisTitle
|
||||
*/
|
||||
public function setCategoryAxisTitle($axisTitle)
|
||||
{
|
||||
$this->categoryAxisTitle = $axisTitle;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the valueAxisTitle
|
||||
* @return string
|
||||
*/
|
||||
public function getValueAxisTitle()
|
||||
{
|
||||
return $this->valueAxisTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title that appears on the value side of the chart
|
||||
* @param string $axisTitle
|
||||
*/
|
||||
public function setValueAxisTitle($axisTitle)
|
||||
{
|
||||
$this->valueAxisTitle = $axisTitle;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMajorTickPosition()
|
||||
{
|
||||
return $this->majorTickMarkPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the position for major tick marks
|
||||
* @param string $position [description]
|
||||
*/
|
||||
public function setMajorTickPosition($position)
|
||||
{
|
||||
$enum = array('in', 'out', 'cross', 'none');
|
||||
$this->majorTickMarkPos = $this->setEnumVal($position, $enum, $this->majorTickMarkPos);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show Gridlines for X-Axis
|
||||
*
|
||||
* @return bool
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ class Font extends AbstractStyle
|
|||
* Create new font style
|
||||
*
|
||||
* @param string $type Type of font
|
||||
* @param array $paragraph Paragraph styles definition
|
||||
* @param array|string|\PhpOffice\PhpWord\Style\AbstractStyle $paragraph Paragraph styles definition
|
||||
*/
|
||||
public function __construct($type = 'text', $paragraph = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ final class Language extends AbstractStyle
|
|||
const HE_IL = 'he-IL';
|
||||
const HE_IL_ID = 1037;
|
||||
|
||||
const IT_IT = 'it-IT';
|
||||
const IT_IT_ID = 1040;
|
||||
|
||||
const JA_JP = 'ja-JP';
|
||||
const JA_JP_ID = 1041;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Style;
|
||||
|
||||
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||
use PhpOffice\PhpWord\SimpleType\Jc;
|
||||
use PhpOffice\PhpWord\SimpleType\JcTable;
|
||||
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
||||
|
|
@ -159,6 +160,16 @@ class Table extends Border
|
|||
*/
|
||||
private $position;
|
||||
|
||||
/** @var TblWidthComplexType|null */
|
||||
private $indent;
|
||||
|
||||
/**
|
||||
* The width of each column, computed based on the max cell width of each column
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
private $columnWidths;
|
||||
|
||||
/**
|
||||
* Create new table style
|
||||
*
|
||||
|
|
@ -724,4 +735,44 @@ class Table extends Border
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TblWidthComplexType
|
||||
*/
|
||||
public function getIndent()
|
||||
{
|
||||
return $this->indent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TblWidthComplexType $indent
|
||||
* @return self
|
||||
* @see http://www.datypic.com/sc/ooxml/e-w_tblInd-1.html
|
||||
*/
|
||||
public function setIndent(TblWidthComplexType $indent)
|
||||
{
|
||||
$this->indent = $indent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the columnWidths
|
||||
*
|
||||
* @return number[]
|
||||
*/
|
||||
public function getColumnWidths()
|
||||
{
|
||||
return $this->columnWidths;
|
||||
}
|
||||
|
||||
/**
|
||||
* The column widths
|
||||
*
|
||||
* @param int[] $value
|
||||
*/
|
||||
public function setColumnWidths(array $value = null)
|
||||
{
|
||||
$this->columnWidths = $value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ class TemplateProcessor
|
|||
*/
|
||||
protected function transformSingleXml($xml, $xsltProcessor)
|
||||
{
|
||||
libxml_disable_entity_loader(true);
|
||||
$domDocument = new \DOMDocument();
|
||||
if (false === $domDocument->loadXML($xml)) {
|
||||
throw new Exception('Could not load the given XML document.');
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Writer\ODText\Element;
|
||||
|
||||
use PhpOffice\Common\XMLWriter;
|
||||
use PhpOffice\PhpWord\Element\Row as RowElement;
|
||||
use PhpOffice\PhpWord\Element\Table as TableElement;
|
||||
|
||||
/**
|
||||
* Table element writer
|
||||
*
|
||||
|
|
@ -36,18 +40,48 @@ class Table extends AbstractElement
|
|||
}
|
||||
$rows = $element->getRows();
|
||||
$rowCount = count($rows);
|
||||
$colCount = $element->countColumns();
|
||||
|
||||
if ($rowCount > 0) {
|
||||
$xmlWriter->startElement('table:table');
|
||||
$xmlWriter->writeAttribute('table:name', $element->getElementId());
|
||||
$xmlWriter->writeAttribute('table:style', $element->getElementId());
|
||||
|
||||
$xmlWriter->startElement('table:table-column');
|
||||
$xmlWriter->writeAttribute('table:number-columns-repeated', $colCount);
|
||||
$xmlWriter->endElement(); // table:table-column
|
||||
// Write columns
|
||||
$this->writeColumns($xmlWriter, $element);
|
||||
|
||||
// Write rows
|
||||
foreach ($rows as $row) {
|
||||
$this->writeRow($xmlWriter, $row);
|
||||
}
|
||||
$xmlWriter->endElement(); // table:table
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write column.
|
||||
*
|
||||
* @param \PhpOffice\Common\XMLWriter $xmlWriter
|
||||
* @param \PhpOffice\PhpWord\Element\Table $element
|
||||
*/
|
||||
private function writeColumns(XMLWriter $xmlWriter, TableElement $element)
|
||||
{
|
||||
$colCount = $element->countColumns();
|
||||
|
||||
for ($i = 0; $i < $colCount; $i++) {
|
||||
$xmlWriter->startElement('table:table-column');
|
||||
$xmlWriter->writeAttribute('table:style-name', $element->getElementId() . '.' . $i);
|
||||
$xmlWriter->endElement();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write row.
|
||||
*
|
||||
* @param \PhpOffice\Common\XMLWriter $xmlWriter
|
||||
* @param \PhpOffice\PhpWord\Element\Row $row
|
||||
*/
|
||||
private function writeRow(XMLWriter $xmlWriter, RowElement $row)
|
||||
{
|
||||
$xmlWriter->startElement('table:table-row');
|
||||
/** @var $row \PhpOffice\PhpWord\Element\Row Type hint */
|
||||
foreach ($row->getCells() as $cell) {
|
||||
|
|
@ -61,7 +95,4 @@ class Table extends AbstractElement
|
|||
}
|
||||
$xmlWriter->endElement(); // table:table-row
|
||||
}
|
||||
$xmlWriter->endElement(); // table:table
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@ class Content extends AbstractPart
|
|||
$style->setStyleName('fr' . $element->getMediaIndex());
|
||||
$this->autoStyles['Image'][] = $style;
|
||||
} elseif ($element instanceof Table) {
|
||||
/** @var \PhpOffice\PhpWord\Style\Table $style */
|
||||
$style = $element->getStyle();
|
||||
if ($style === null) {
|
||||
$style = new TableStyle();
|
||||
|
|
@ -246,6 +247,7 @@ class Content extends AbstractPart
|
|||
$style = Style::getStyle($style);
|
||||
}
|
||||
$style->setStyleName($element->getElementId());
|
||||
$style->setColumnWidths($element->findFirstDefinedCellWidths());
|
||||
$this->autoStyles['Table'][] = $style;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,5 +45,19 @@ class Table extends AbstractStyle
|
|||
$xmlWriter->writeAttribute('table:align', 'center');
|
||||
$xmlWriter->endElement(); // style:table-properties
|
||||
$xmlWriter->endElement(); // style:style
|
||||
|
||||
$cellWidths = $style->getColumnWidths();
|
||||
$countCellWidths = count($cellWidths);
|
||||
|
||||
for ($i = 0; $i < $countCellWidths; $i++) {
|
||||
$width = $cellWidths[$i];
|
||||
$xmlWriter->startElement('style:style');
|
||||
$xmlWriter->writeAttribute('style:name', $style->getStyleName() . '.' . $i);
|
||||
$xmlWriter->writeAttribute('style:family', 'table-column');
|
||||
$xmlWriter->startElement('style:table-column-properties');
|
||||
$xmlWriter->writeAttribute('style:column-width', number_format($width * 0.0017638889, 2, '.', '') . 'cm');
|
||||
$xmlWriter->endElement(); // style:table-column-properties
|
||||
$xmlWriter->endElement(); // style:style
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
* @copyright 2010-2018 PHPWord contributors
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\RTF\Style;
|
||||
|
||||
/**
|
||||
* RTF indentation style writer
|
||||
*
|
||||
* @since 0.11.0
|
||||
*/
|
||||
class Indentation extends AbstractStyle
|
||||
{
|
||||
/**
|
||||
* Write style
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$style = $this->getStyle();
|
||||
if (!$style instanceof \PhpOffice\PhpWord\Style\Indentation) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$content = '\fi' . $style->getFirstLine();
|
||||
$content .= '\li' . $style->getLeft();
|
||||
$content .= '\ri' . $style->getRight();
|
||||
|
||||
return $content . ' ';
|
||||
}
|
||||
}
|
||||
|
|
@ -64,9 +64,49 @@ class Paragraph extends AbstractStyle
|
|||
if (isset($alignments[$style->getAlignment()])) {
|
||||
$content .= $alignments[$style->getAlignment()];
|
||||
}
|
||||
$content .= $this->writeIndentation($style->getIndentation());
|
||||
$content .= $this->getValueIf($spaceBefore !== null, '\sb' . $spaceBefore);
|
||||
$content .= $this->getValueIf($spaceAfter !== null, '\sa' . $spaceAfter);
|
||||
|
||||
$styles = $style->getStyleValues();
|
||||
$content .= $this->writeTabs($styles['tabs']);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an \PhpOffice\PhpWord\Style\Indentation
|
||||
*
|
||||
* @param null|\PhpOffice\PhpWord\Style\Indentation $indent
|
||||
* @return string
|
||||
*/
|
||||
private function writeIndentation($indent = null)
|
||||
{
|
||||
if (isset($indent) && $indent instanceof \PhpOffice\PhpWord\Style\Indentation) {
|
||||
$writer = new Indentation($indent);
|
||||
|
||||
return $writer->write();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes tabs
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Style\Tab[] $tabs
|
||||
* @return string
|
||||
*/
|
||||
private function writeTabs($tabs = null)
|
||||
{
|
||||
$content = '';
|
||||
if (!empty($tabs)) {
|
||||
foreach ($tabs as $tab) {
|
||||
$styleWriter = new Tab($tab);
|
||||
$content .= $styleWriter->write();
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
* @copyright 2010-2018 PHPWord contributors
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
|
||||
namespace PhpOffice\PhpWord\Writer\RTF\Style;
|
||||
|
||||
/**
|
||||
* Line numbering style writer
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class Tab extends AbstractStyle
|
||||
{
|
||||
/**
|
||||
* Write style.
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$style = $this->getStyle();
|
||||
if (!$style instanceof \PhpOffice\PhpWord\Style\Tab) {
|
||||
return;
|
||||
}
|
||||
$tabs = array(
|
||||
\PhpOffice\PhpWord\Style\Tab::TAB_STOP_RIGHT => '\tqr',
|
||||
\PhpOffice\PhpWord\Style\Tab::TAB_STOP_CENTER => '\tqc',
|
||||
\PhpOffice\PhpWord\Style\Tab::TAB_STOP_DECIMAL => '\tqdec',
|
||||
);
|
||||
$content = '';
|
||||
if (isset($tabs[$style->getType()])) {
|
||||
$content .= $tabs[$style->getType()];
|
||||
}
|
||||
$content .= '\tx' . $style->getPosition();
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
|
@ -177,6 +177,9 @@ class Field extends Text
|
|||
case 'macroname':
|
||||
$propertiesAndOptions .= $propval . ' ';
|
||||
break;
|
||||
default:
|
||||
$propertiesAndOptions .= '"' . $propval . '" ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,21 +76,7 @@ class Table extends AbstractElement
|
|||
*/
|
||||
private function writeColumns(XMLWriter $xmlWriter, TableElement $element)
|
||||
{
|
||||
$rows = $element->getRows();
|
||||
$rowCount = count($rows);
|
||||
|
||||
$cellWidths = array();
|
||||
for ($i = 0; $i < $rowCount; $i++) {
|
||||
$row = $rows[$i];
|
||||
$cells = $row->getCells();
|
||||
if (count($cells) <= count($cellWidths)) {
|
||||
continue;
|
||||
}
|
||||
$cellWidths = array();
|
||||
foreach ($cells as $cell) {
|
||||
$cellWidths[] = $cell->getWidth();
|
||||
}
|
||||
}
|
||||
$cellWidths = $element->findFirstDefinedCellWidths();
|
||||
|
||||
$xmlWriter->startElement('w:tblGrid');
|
||||
foreach ($cellWidths as $width) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class Title extends AbstractElement
|
|||
$xmlWriter->endElement();
|
||||
}
|
||||
|
||||
$bookmarkRId = null;
|
||||
if ($element->getDepth() !== 0) {
|
||||
$rId = $element->getRelationId();
|
||||
$bookmarkRId = $element->getPhpWord()->addBookmark();
|
||||
|
|
|
|||
|
|
@ -43,8 +43,12 @@ class Chart extends AbstractPart
|
|||
private $types = array(
|
||||
'pie' => array('type' => 'pie', 'colors' => 1),
|
||||
'doughnut' => array('type' => 'doughnut', 'colors' => 1, 'hole' => 75, 'no3d' => true),
|
||||
'bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar'),
|
||||
'column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col'),
|
||||
'bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar', 'grouping' => 'clustered'),
|
||||
'stacked_bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar', 'grouping' => 'stacked'),
|
||||
'percent_stacked_bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar', 'grouping' => 'percentStacked'),
|
||||
'column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col', 'grouping' => 'clustered'),
|
||||
'stacked_column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col', 'grouping' => 'stacked'),
|
||||
'percent_stacked_column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col', 'grouping' => 'percentStacked'),
|
||||
'line' => array('type' => 'line', 'colors' => 0, 'axes' => true),
|
||||
'area' => array('type' => 'area', 'colors' => 0, 'axes' => true),
|
||||
'radar' => array('type' => 'radar', 'colors' => 0, 'axes' => true, 'radar' => 'standard', 'no3d' => true),
|
||||
|
|
@ -145,7 +149,7 @@ class Chart extends AbstractPart
|
|||
}
|
||||
if (isset($this->options['bar'])) {
|
||||
$xmlWriter->writeElementBlock('c:barDir', 'val', $this->options['bar']); // bar|col
|
||||
$xmlWriter->writeElementBlock('c:grouping', 'val', 'clustered'); // 3d; standard = percentStacked
|
||||
$xmlWriter->writeElementBlock('c:grouping', 'val', $this->options['grouping']); // 3d; standard = percentStacked
|
||||
}
|
||||
if (isset($this->options['radar'])) {
|
||||
$xmlWriter->writeElementBlock('c:radarStyle', 'val', $this->options['radar']);
|
||||
|
|
@ -157,6 +161,8 @@ class Chart extends AbstractPart
|
|||
// Series
|
||||
$this->writeSeries($xmlWriter, isset($this->options['scatter']));
|
||||
|
||||
$xmlWriter->writeElementBlock('c:overlap', 'val', '100');
|
||||
|
||||
// Axes
|
||||
if (isset($this->options['axes'])) {
|
||||
$xmlWriter->writeElementBlock('c:axId', 'val', 1);
|
||||
|
|
@ -183,6 +189,8 @@ class Chart extends AbstractPart
|
|||
private function writeSeries(XMLWriter $xmlWriter, $scatter = false)
|
||||
{
|
||||
$series = $this->element->getSeries();
|
||||
$style = $this->element->getStyle();
|
||||
$colors = $style->getColors();
|
||||
|
||||
$index = 0;
|
||||
foreach ($series as $seriesItem) {
|
||||
|
|
@ -194,6 +202,32 @@ class Chart extends AbstractPart
|
|||
$xmlWriter->writeElementBlock('c:idx', 'val', $index);
|
||||
$xmlWriter->writeElementBlock('c:order', 'val', $index);
|
||||
|
||||
if (!is_null($seriesItem['name']) && $seriesItem['name'] != '') {
|
||||
$xmlWriter->startElement('c:tx');
|
||||
$xmlWriter->startElement('c:strRef');
|
||||
$xmlWriter->startElement('c:strCache');
|
||||
$xmlWriter->writeElementBlock('c:ptCount', 'val', 1);
|
||||
$xmlWriter->startElement('c:pt');
|
||||
$xmlWriter->writeAttribute('idx', 0);
|
||||
$xmlWriter->startElement('c:v');
|
||||
$xmlWriter->writeRaw($seriesItem['name']);
|
||||
$xmlWriter->endElement(); // c:v
|
||||
$xmlWriter->endElement(); // c:pt
|
||||
$xmlWriter->endElement(); // c:strCache
|
||||
$xmlWriter->endElement(); // c:strRef
|
||||
$xmlWriter->endElement(); // c:tx
|
||||
}
|
||||
|
||||
// The c:dLbls was added to make word charts look more like the reports in SurveyGizmo
|
||||
// This section needs to be made configurable before a pull request is made
|
||||
$xmlWriter->startElement('c:dLbls');
|
||||
|
||||
foreach ($style->getDataLabelOptions() as $option => $val) {
|
||||
$xmlWriter->writeElementBlock("c:{$option}", 'val', (int) $val);
|
||||
}
|
||||
|
||||
$xmlWriter->endElement(); // c:dLbls
|
||||
|
||||
if (isset($this->options['scatter'])) {
|
||||
$this->writeShape($xmlWriter);
|
||||
}
|
||||
|
|
@ -204,6 +238,26 @@ class Chart extends AbstractPart
|
|||
} else {
|
||||
$this->writeSeriesItem($xmlWriter, 'cat', $categories);
|
||||
$this->writeSeriesItem($xmlWriter, 'val', $values);
|
||||
|
||||
// setting the chart colors was taken from https://github.com/PHPOffice/PHPWord/issues/494
|
||||
if (is_array($colors) && count($colors)) {
|
||||
// This is a workaround to make each series in a stack chart use a different color
|
||||
if ($this->options['type'] == 'bar' && stristr($this->options['grouping'], 'stacked')) {
|
||||
array_shift($colors);
|
||||
}
|
||||
$colorIndex = 0;
|
||||
foreach ($colors as $color) {
|
||||
$xmlWriter->startElement('c:dPt');
|
||||
$xmlWriter->writeElementBlock('c:idx', 'val', $colorIndex);
|
||||
$xmlWriter->startElement('c:spPr');
|
||||
$xmlWriter->startElement('a:solidFill');
|
||||
$xmlWriter->writeElementBlock('a:srgbClr', 'val', $color);
|
||||
$xmlWriter->endElement(); // a:solidFill
|
||||
$xmlWriter->endElement(); // c:spPr
|
||||
$xmlWriter->endElement(); // c:dPt
|
||||
$colorIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$xmlWriter->endElement(); // c:ser
|
||||
|
|
@ -230,14 +284,19 @@ class Chart extends AbstractPart
|
|||
|
||||
$xmlWriter->startElement($itemType);
|
||||
$xmlWriter->startElement($itemLit);
|
||||
$xmlWriter->writeElementBlock('c:ptCount', 'val', count($values));
|
||||
|
||||
$index = 0;
|
||||
foreach ($values as $value) {
|
||||
$xmlWriter->startElement('c:pt');
|
||||
$xmlWriter->writeAttribute('idx', $index);
|
||||
if (\PhpOffice\PhpWord\Settings::isOutputEscapingEnabled()) {
|
||||
$xmlWriter->writeElement('c:v', $value);
|
||||
} else {
|
||||
$xmlWriter->startElement('c:v');
|
||||
$xmlWriter->text($value);
|
||||
$xmlWriter->writeRaw($value);
|
||||
$xmlWriter->endElement(); // c:v
|
||||
}
|
||||
$xmlWriter->endElement(); // c:pt
|
||||
$index++;
|
||||
}
|
||||
|
|
@ -266,15 +325,33 @@ class Chart extends AbstractPart
|
|||
|
||||
$xmlWriter->writeElementBlock('c:axId', 'val', $axisId);
|
||||
$xmlWriter->writeElementBlock('c:axPos', 'val', $axisPos);
|
||||
|
||||
$categoryAxisTitle = $style->getCategoryAxisTitle();
|
||||
$valueAxisTitle = $style->getValueAxisTitle();
|
||||
|
||||
if ($axisType == 'c:catAx') {
|
||||
if (!is_null($categoryAxisTitle)) {
|
||||
$this->writeAxisTitle($xmlWriter, $categoryAxisTitle);
|
||||
}
|
||||
} elseif ($axisType == 'c:valAx') {
|
||||
if (!is_null($valueAxisTitle)) {
|
||||
$this->writeAxisTitle($xmlWriter, $valueAxisTitle);
|
||||
}
|
||||
}
|
||||
|
||||
$xmlWriter->writeElementBlock('c:crossAx', 'val', $axisCross);
|
||||
$xmlWriter->writeElementBlock('c:auto', 'val', 1);
|
||||
|
||||
if (isset($this->options['axes'])) {
|
||||
$xmlWriter->writeElementBlock('c:delete', 'val', 0);
|
||||
$xmlWriter->writeElementBlock('c:majorTickMark', 'val', 'none');
|
||||
$xmlWriter->writeElementBlock('c:majorTickMark', 'val', $style->getMajorTickPosition());
|
||||
$xmlWriter->writeElementBlock('c:minorTickMark', 'val', 'none');
|
||||
if ($style->showAxisLabels()) {
|
||||
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', 'nextTo');
|
||||
if ($axisType == 'c:catAx') {
|
||||
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', $style->getCategoryLabelPosition());
|
||||
} else {
|
||||
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', $style->getValueLabelPosition());
|
||||
}
|
||||
} else {
|
||||
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', 'none');
|
||||
}
|
||||
|
|
@ -312,4 +389,30 @@ class Chart extends AbstractPart
|
|||
$xmlWriter->endElement(); // a:ln
|
||||
$xmlWriter->endElement(); // c:spPr
|
||||
}
|
||||
|
||||
private function writeAxisTitle(XMLWriter $xmlWriter, $title)
|
||||
{
|
||||
$xmlWriter->startElement('c:title'); //start c:title
|
||||
$xmlWriter->startElement('c:tx'); //start c:tx
|
||||
$xmlWriter->startElement('c:rich'); // start c:rich
|
||||
$xmlWriter->writeElement('a:bodyPr');
|
||||
$xmlWriter->writeElement('a:lstStyle');
|
||||
$xmlWriter->startElement('a:p');
|
||||
$xmlWriter->startElement('a:pPr');
|
||||
$xmlWriter->writeElement('a:defRPr');
|
||||
$xmlWriter->endElement(); // end a:pPr
|
||||
$xmlWriter->startElement('a:r');
|
||||
$xmlWriter->writeElementBlock('a:rPr', 'lang', 'en-US');
|
||||
|
||||
$xmlWriter->startElement('a:t');
|
||||
$xmlWriter->writeRaw($title);
|
||||
$xmlWriter->endElement(); //end a:t
|
||||
|
||||
$xmlWriter->endElement(); // end a:r
|
||||
$xmlWriter->endElement(); //end a:p
|
||||
$xmlWriter->endElement(); //end c:rich
|
||||
$xmlWriter->endElement(); // end c:tx
|
||||
$xmlWriter->writeElementBlock('c:overlay', 'val', '0');
|
||||
$xmlWriter->endElement(); // end c:title
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Writer\Word2007\Part;
|
||||
|
||||
use PhpOffice\Common\Microsoft\PasswordEncoder;
|
||||
use PhpOffice\PhpWord\ComplexType\ProofState;
|
||||
use PhpOffice\PhpWord\ComplexType\TrackChangesView;
|
||||
use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder;
|
||||
use PhpOffice\PhpWord\Style\Language;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ class Table extends AbstractStyle
|
|||
|
||||
$this->writeTblWidth($xmlWriter, 'w:tblW', $style->getUnit(), $style->getWidth());
|
||||
$this->writeTblWidth($xmlWriter, 'w:tblCellSpacing', TblWidth::TWIP, $style->getCellSpacing());
|
||||
$this->writeIndent($xmlWriter, $style);
|
||||
$this->writeLayout($xmlWriter, $style->getLayout());
|
||||
|
||||
// Position
|
||||
|
|
@ -216,4 +217,19 @@ class Table extends AbstractStyle
|
|||
{
|
||||
$this->width = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param XMLWriter $xmlWriter
|
||||
* @param TableStyle $style
|
||||
*/
|
||||
private function writeIndent(XMLWriter $xmlWriter, TableStyle $style)
|
||||
{
|
||||
$indent = $style->getIndent();
|
||||
|
||||
if ($indent === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->writeTblWidth($xmlWriter, 'w:tblInd', $indent->getType(), $indent->getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,4 +126,23 @@ class StyleTest extends AbstractTestReader
|
|||
$fontStyle = $textRun->getElement(0)->getFontStyle();
|
||||
$this->assertEquals(15, $fontStyle->getPosition());
|
||||
}
|
||||
|
||||
public function testReadIndent()
|
||||
{
|
||||
$documentXml = '<w:tbl>
|
||||
<w:tblPr>
|
||||
<w:tblInd w:w="2160" w:type="dxa"/>
|
||||
</w:tblPr>
|
||||
</w:tbl>';
|
||||
|
||||
$phpWord = $this->getDocumentFromString(array('document' => $documentXml));
|
||||
|
||||
$elements = $phpWord->getSection(0)->getElements();
|
||||
$this->assertInstanceOf('PhpOffice\PhpWord\Element\Table', $elements[0]);
|
||||
$this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle());
|
||||
/** @var \PhpOffice\PhpWord\Style\Table $tableStyle */
|
||||
$tableStyle = $elements[0]->getStyle();
|
||||
$this->assertSame(TblWidth::TWIP, $tableStyle->getIndent()->getType());
|
||||
$this->assertSame(2160, $tableStyle->getIndent()->getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,91 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
* @copyright 2010-2018 PHPWord contributors
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
|
||||
namespace PhpOffice\PhpWord\Shared;
|
||||
|
||||
use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Test class for PhpOffice\PhpWord\Shared\Html
|
||||
* @coversDefaultClass \PhpOffice\PhpWord\Shared\Html
|
||||
*/
|
||||
class PasswordEncoderTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* Test that a password can be hashed without specifying any additional parameters
|
||||
*/
|
||||
public function testEncodePassword()
|
||||
{
|
||||
//given
|
||||
$password = 'test';
|
||||
|
||||
//when
|
||||
$hashPassword = PasswordEncoder::hashPassword($password);
|
||||
|
||||
//then
|
||||
TestCase::assertEquals('M795/MAlmGU8RIsY9Q9uDLHC7bk=', $hashPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a password can be hashed with a custom salt
|
||||
*/
|
||||
public function testEncodePasswordWithSalt()
|
||||
{
|
||||
//given
|
||||
$password = 'test';
|
||||
$salt = base64_decode('uq81pJRRGFIY5U+E9gt8tA==');
|
||||
|
||||
//when
|
||||
$hashPassword = PasswordEncoder::hashPassword($password, PasswordEncoder::ALGORITHM_SHA_1, $salt);
|
||||
|
||||
//then
|
||||
TestCase::assertEquals('QiDOcpia1YzSVJPiKPwWebl9p/0=', $hashPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the encoder falls back on SHA-1 if a non supported algorithm is given
|
||||
*/
|
||||
public function testDafaultsToSha1IfUnsupportedAlgorithm()
|
||||
{
|
||||
//given
|
||||
$password = 'test';
|
||||
$salt = base64_decode('uq81pJRRGFIY5U+E9gt8tA==');
|
||||
|
||||
//when
|
||||
$hashPassword = PasswordEncoder::hashPassword($password, PasswordEncoder::ALGORITHM_MAC, $salt);
|
||||
|
||||
//then
|
||||
TestCase::assertEquals('QiDOcpia1YzSVJPiKPwWebl9p/0=', $hashPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the encoder falls back on SHA-1 if a non supported algorithm is given
|
||||
*/
|
||||
public function testEncodePasswordWithNullAsciiCodeInPassword()
|
||||
{
|
||||
//given
|
||||
$password = 'test' . chr(0);
|
||||
$salt = base64_decode('uq81pJRRGFIY5U+E9gt8tA==');
|
||||
|
||||
//when
|
||||
$hashPassword = PasswordEncoder::hashPassword($password, PasswordEncoder::ALGORITHM_MAC, $salt, 1);
|
||||
|
||||
//then
|
||||
TestCase::assertEquals('rDV9sgdDsztoCQlvRCb1lF2wxNg=', $hashPassword);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @see https://github.com/PHPOffice/PHPWord
|
||||
* @copyright 2010-2017 PHPWord contributors
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
|
||||
namespace PhpOffice\PhpWord\Style;
|
||||
|
||||
/**
|
||||
* Test class for PhpOffice\PhpWord\Style\Chart
|
||||
*
|
||||
* @coversDefaultClass \PhpOffice\PhpWord\Style\Chart
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class ChartTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* Testing getter and setter for chart width
|
||||
*/
|
||||
public function testSetGetWidth()
|
||||
{
|
||||
$chart = new Chart();
|
||||
|
||||
$this->assertEquals($chart->getWidth(), 1000000);
|
||||
|
||||
$chart->setWidth(200);
|
||||
|
||||
$this->assertEquals($chart->getWidth(), 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing getter and setter for chart height
|
||||
*/
|
||||
public function testSetGetHeight()
|
||||
{
|
||||
$chart = new Chart();
|
||||
|
||||
$this->assertEquals($chart->getHeight(), 1000000);
|
||||
|
||||
$chart->setHeight(200);
|
||||
|
||||
$this->assertEquals($chart->getHeight(), 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing getter and setter for is3d
|
||||
*/
|
||||
public function testSetIs3d()
|
||||
{
|
||||
$chart = new Chart();
|
||||
|
||||
$this->assertEquals($chart->is3d(), false);
|
||||
|
||||
$chart->set3d(true);
|
||||
|
||||
$this->assertEquals($chart->is3d(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing getter and setter for chart colors
|
||||
*/
|
||||
public function testSetGetColors()
|
||||
{
|
||||
$chart = new Chart();
|
||||
|
||||
$this->assertInternalType('array', $chart->getColors());
|
||||
|
||||
$this->assertEquals(count($chart->getColors()), 0);
|
||||
|
||||
$chart->setColors(array('FFFFFFFF', 'FF000000', 'FFFF0000'));
|
||||
|
||||
$this->assertEquals($chart->getColors(), array('FFFFFFFF', 'FF000000', 'FFFF0000'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing getter and setter for dataLabelOptions
|
||||
*/
|
||||
public function testSetGetDataLabelOptions()
|
||||
{
|
||||
$chart = new Chart();
|
||||
|
||||
$originalDataLabelOptions = array(
|
||||
'showVal' => true,
|
||||
'showCatName' => true,
|
||||
'showLegendKey' => false,
|
||||
'showSerName' => false,
|
||||
'showPercent' => false,
|
||||
'showLeaderLines' => false,
|
||||
'showBubbleSize' => false,
|
||||
);
|
||||
|
||||
$this->assertEquals($chart->getDataLabelOptions(), $originalDataLabelOptions);
|
||||
|
||||
$changedDataLabelOptions = array(
|
||||
'showVal' => false,
|
||||
'showCatName' => false,
|
||||
'showLegendKey' => true,
|
||||
'showSerName' => true,
|
||||
'showPercent' => true,
|
||||
'showLeaderLines' => true,
|
||||
'showBubbleSize' => true,
|
||||
);
|
||||
|
||||
$chart->setDataLabelOptions(
|
||||
array(
|
||||
'showVal' => false,
|
||||
'showCatName' => false,
|
||||
'showLegendKey' => true,
|
||||
'showSerName' => true,
|
||||
'showPercent' => true,
|
||||
'showLeaderLines' => true,
|
||||
'showBubbleSize' => true,
|
||||
)
|
||||
);
|
||||
$this->assertEquals($chart->getDataLabelOptions(), $changedDataLabelOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing categoryLabelPosition getter and setter
|
||||
*/
|
||||
public function testSetGetCategoryLabelPosition()
|
||||
{
|
||||
$chart = new Chart();
|
||||
|
||||
$this->assertEquals($chart->getCategoryLabelPosition(), 'nextTo');
|
||||
|
||||
$chart->setCategoryLabelPosition('high');
|
||||
|
||||
$this->assertEquals($chart->getCategoryLabelPosition(), 'high');
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing valueLabelPosition getter and setter
|
||||
*/
|
||||
public function testSetGetValueLabelPosition()
|
||||
{
|
||||
$chart = new Chart();
|
||||
|
||||
$this->assertEquals($chart->getValueLabelPosition(), 'nextTo');
|
||||
|
||||
$chart->setValueLabelPosition('low');
|
||||
|
||||
$this->assertEquals($chart->getValueLabelPosition(), 'low');
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing categoryAxisTitle getter and setter
|
||||
*/
|
||||
public function testSetGetCategoryAxisTitle()
|
||||
{
|
||||
$chart = new Chart();
|
||||
|
||||
$chart->getCategoryAxisTitle();
|
||||
|
||||
$this->assertEquals($chart->getCategoryAxisTitle(), null);
|
||||
|
||||
$chart->setCategoryAxisTitle('Test Category Axis Title');
|
||||
|
||||
$this->assertEquals($chart->getCategoryAxisTitle(), 'Test Category Axis Title');
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing valueAxisTitle getter and setter
|
||||
*/
|
||||
public function testSetGetValueAxisTitle()
|
||||
{
|
||||
$chart = new Chart();
|
||||
|
||||
$chart->getValueAxisTitle();
|
||||
|
||||
$this->assertEquals($chart->getValueAxisTitle(), null);
|
||||
|
||||
$chart->setValueAxisTitle('Test Value Axis Title');
|
||||
|
||||
$this->assertEquals($chart->getValueAxisTitle(), 'Test Value Axis Title');
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Style;
|
||||
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\TestHelperDOCX;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Style;
|
||||
|
||||
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||
use PhpOffice\PhpWord\SimpleType\JcTable;
|
||||
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
||||
|
||||
|
|
@ -57,6 +58,7 @@ class TableTest extends \PHPUnit\Framework\TestCase
|
|||
$this->assertNull($object->getBgColor());
|
||||
$this->assertEquals(Table::LAYOUT_AUTO, $object->getLayout());
|
||||
$this->assertEquals(TblWidth::AUTO, $object->getUnit());
|
||||
$this->assertNull($object->getIndent());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -208,4 +210,13 @@ class TableTest extends \PHPUnit\Framework\TestCase
|
|||
$this->assertNotNull($object->getPosition());
|
||||
$this->assertEquals(TablePosition::VANCHOR_PAGE, $object->getPosition()->getVertAnchor());
|
||||
}
|
||||
|
||||
public function testIndent()
|
||||
{
|
||||
$indent = new TblWidthComplexType(100, TblWidth::TWIP);
|
||||
|
||||
$table = new Table(array('indent' => $indent));
|
||||
|
||||
$this->assertSame($indent, $table->getIndent());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
|||
$text2->setTrackChange(new TrackChange(TrackChange::DELETED, 'another author', new \DateTime()));
|
||||
|
||||
$dom = $this->getAsHTML($phpWord);
|
||||
$xpath = new \DOMXpath($dom);
|
||||
$xpath = new \DOMXPath($dom);
|
||||
|
||||
$this->assertTrue($xpath->query('/html/body/p[1]/ins')->length == 1);
|
||||
$this->assertTrue($xpath->query('/html/body/p[2]/del')->length == 1);
|
||||
|
|
@ -94,7 +94,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
|||
$cell22->addText('second cell');
|
||||
|
||||
$dom = $this->getAsHTML($phpWord);
|
||||
$xpath = new \DOMXpath($dom);
|
||||
$xpath = new \DOMXPath($dom);
|
||||
|
||||
$this->assertTrue($xpath->query('/html/body/table/tr[1]/td')->length == 1);
|
||||
$this->assertEquals('2', $xpath->query('/html/body/table/tr/td[1]')->item(0)->attributes->getNamedItem('colspan')->textContent);
|
||||
|
|
@ -123,7 +123,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
|||
$row3->addCell(500)->addText('third cell being spanned');
|
||||
|
||||
$dom = $this->getAsHTML($phpWord);
|
||||
$xpath = new \DOMXpath($dom);
|
||||
$xpath = new \DOMXPath($dom);
|
||||
|
||||
$this->assertTrue($xpath->query('/html/body/table/tr[1]/td')->length == 2);
|
||||
$this->assertEquals('3', $xpath->query('/html/body/table/tr[1]/td[1]')->item(0)->attributes->getNamedItem('rowspan')->textContent);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Writer\RTF;
|
||||
|
||||
use PhpOffice\PhpWord\Writer\RTF;
|
||||
use PhpOffice\PhpWord\Writer\RTF\Style\Border;
|
||||
use PHPUnit\Framework\Assert;
|
||||
|
||||
/**
|
||||
* Test class for PhpOffice\PhpWord\Writer\RTF\Style subnamespace
|
||||
|
|
@ -29,7 +31,7 @@ class StyleTest extends \PHPUnit\Framework\TestCase
|
|||
*/
|
||||
public function testEmptyStyles()
|
||||
{
|
||||
$styles = array('Font', 'Paragraph', 'Section');
|
||||
$styles = array('Font', 'Paragraph', 'Section', 'Tab', 'Indentation');
|
||||
foreach ($styles as $style) {
|
||||
$objectClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $style;
|
||||
$object = new $objectClass();
|
||||
|
|
@ -55,4 +57,55 @@ class StyleTest extends \PHPUnit\Framework\TestCase
|
|||
|
||||
$this->assertEquals($expected, $content);
|
||||
}
|
||||
|
||||
public function testIndentation()
|
||||
{
|
||||
$indentation = new \PhpOffice\PhpWord\Style\Indentation();
|
||||
$indentation->setLeft(1);
|
||||
$indentation->setRight(2);
|
||||
$indentation->setFirstLine(3);
|
||||
|
||||
$indentWriter = new \PhpOffice\PhpWord\Writer\RTF\Style\Indentation($indentation);
|
||||
$indentWriter->setParentWriter(new RTF());
|
||||
$result = $indentWriter->write();
|
||||
|
||||
Assert::assertEquals('\fi3\li1\ri2 ', $result);
|
||||
}
|
||||
|
||||
public function testRightTab()
|
||||
{
|
||||
$tabRight = new \PhpOffice\PhpWord\Style\Tab();
|
||||
$tabRight->setType(\PhpOffice\PhpWord\Style\Tab::TAB_STOP_RIGHT);
|
||||
$tabRight->setPosition(5);
|
||||
|
||||
$tabWriter = new \PhpOffice\PhpWord\Writer\RTF\Style\Tab($tabRight);
|
||||
$tabWriter->setParentWriter(new RTF());
|
||||
$result = $tabWriter->write();
|
||||
|
||||
Assert::assertEquals('\tqr\tx5', $result);
|
||||
}
|
||||
|
||||
public function testCenterTab()
|
||||
{
|
||||
$tabRight = new \PhpOffice\PhpWord\Style\Tab();
|
||||
$tabRight->setType(\PhpOffice\PhpWord\Style\Tab::TAB_STOP_CENTER);
|
||||
|
||||
$tabWriter = new \PhpOffice\PhpWord\Writer\RTF\Style\Tab($tabRight);
|
||||
$tabWriter->setParentWriter(new RTF());
|
||||
$result = $tabWriter->write();
|
||||
|
||||
Assert::assertEquals('\tqc\tx0', $result);
|
||||
}
|
||||
|
||||
public function testDecimalTab()
|
||||
{
|
||||
$tabRight = new \PhpOffice\PhpWord\Style\Tab();
|
||||
$tabRight->setType(\PhpOffice\PhpWord\Style\Tab::TAB_STOP_DECIMAL);
|
||||
|
||||
$tabWriter = new \PhpOffice\PhpWord\Writer\RTF\Style\Tab($tabRight);
|
||||
$tabWriter->setParentWriter(new RTF());
|
||||
$result = $tabWriter->write();
|
||||
|
||||
Assert::assertEquals('\tqdec\tx0', $result);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$phpWord = new PhpWord();
|
||||
$section = $phpWord->addSection();
|
||||
$style = array('width' => 1000000, 'height' => 1000000);
|
||||
$style = array('width' => 1000000, 'height' => 1000000, 'showAxisLabels' => true, 'showGridX' => true, 'showGridY' => true);
|
||||
|
||||
$chartTypes = array('pie', 'doughnut', 'bar', 'line', 'area', 'scatter', 'radar');
|
||||
$categories = array('A', 'B', 'C', 'D', 'E');
|
||||
|
|
@ -288,6 +288,7 @@ class ElementTest extends \PHPUnit\Framework\TestCase
|
|||
$section->addField('DATE', array(), array('LunarCalendar'));
|
||||
$section->addField('DATE', array(), array('SakaEraCalendar'));
|
||||
$section->addField('NUMPAGES', array('format' => 'roman', 'numformat' => '0,00'), array('SakaEraCalendar'));
|
||||
$section->addField('STYLEREF', array('StyleIdentifier' => 'Heading 1'));
|
||||
$doc = TestHelperDOCX::getDocument($phpWord);
|
||||
|
||||
$element = '/w:document/w:body/w:p/w:r/w:instrText';
|
||||
|
|
|
|||
|
|
@ -17,11 +17,10 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Writer\Word2007\Part;
|
||||
|
||||
use PhpOffice\Common\Microsoft\PasswordEncoder;
|
||||
use PhpOffice\PhpWord\ComplexType\ProofState;
|
||||
use PhpOffice\PhpWord\ComplexType\TrackChangesView;
|
||||
use PhpOffice\PhpWord\PhpWord;
|
||||
use PhpOffice\PhpWord\Settings;
|
||||
use PhpOffice\PhpWord\Shared\Microsoft\PasswordEncoder;
|
||||
use PhpOffice\PhpWord\SimpleType\Zoom;
|
||||
use PhpOffice\PhpWord\Style\Language;
|
||||
use PhpOffice\PhpWord\TestHelperDOCX;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class FontTest extends \PHPUnit\Framework\TestCase
|
|||
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
||||
$section = $phpWord->addSection();
|
||||
$textrun = $section->addTextRun();
|
||||
$textrun->addText('سلام این یک پاراگراف راست به چپ است', array('rtl' => true));
|
||||
$textrun->addText('سلام این یک پاراگراف راست به چپ است', array('rtl' => true, 'lang' => 'ar-DZ'));
|
||||
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
|
||||
|
||||
$file = 'word/document.xml';
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Writer\Word2007\Style;
|
||||
|
||||
use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType;
|
||||
use PhpOffice\PhpWord\SimpleType\TblWidth;
|
||||
use PhpOffice\PhpWord\Style\Table;
|
||||
use PhpOffice\PhpWord\Style\TablePosition;
|
||||
use PhpOffice\PhpWord\TestHelperDOCX;
|
||||
|
|
@ -75,7 +77,7 @@ class TableTest extends \PHPUnit\Framework\TestCase
|
|||
$path = '/w:document/w:body/w:tbl/w:tblPr/w:tblCellSpacing';
|
||||
$this->assertTrue($doc->elementExists($path));
|
||||
$this->assertEquals(10.3, $doc->getElementAttribute($path, 'w:w'));
|
||||
$this->assertEquals(\PhpOffice\PhpWord\SimpleType\TblWidth::TWIP, $doc->getElementAttribute($path, 'w:type'));
|
||||
$this->assertEquals(TblWidth::TWIP, $doc->getElementAttribute($path, 'w:type'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -118,4 +120,25 @@ class TableTest extends \PHPUnit\Framework\TestCase
|
|||
$this->assertEquals(TablePosition::YALIGN_TOP, $doc->getElementAttribute($path, 'w:tblpYSpec'));
|
||||
$this->assertEquals(60, $doc->getElementAttribute($path, 'w:tblpY'));
|
||||
}
|
||||
|
||||
public function testIndent()
|
||||
{
|
||||
$value = 100;
|
||||
$type = TblWidth::TWIP;
|
||||
|
||||
$tableStyle = new Table();
|
||||
$tableStyle->setIndent(new TblWidthComplexType($value, $type));
|
||||
|
||||
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
||||
$section = $phpWord->addSection();
|
||||
$table = $section->addTable($tableStyle);
|
||||
$table->addRow();
|
||||
|
||||
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
|
||||
|
||||
$path = '/w:document/w:body/w:tbl/w:tblPr/w:tblInd';
|
||||
$this->assertTrue($doc->elementExists($path));
|
||||
$this->assertSame($value, (int) $doc->getElementAttribute($path, 'w:w'));
|
||||
$this->assertSame($type, $doc->getElementAttribute($path, 'w:type'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ class XmlDocument
|
|||
private $dom;
|
||||
|
||||
/**
|
||||
* DOMXpath object
|
||||
* DOMXPath object
|
||||
*
|
||||
* @var \DOMXpath
|
||||
* @var \DOMXPath
|
||||
*/
|
||||
private $xpath;
|
||||
|
||||
|
|
@ -76,8 +76,10 @@ class XmlDocument
|
|||
$this->file = $file;
|
||||
|
||||
$file = $this->path . '/' . $file;
|
||||
libxml_disable_entity_loader(false);
|
||||
$this->dom = new \DOMDocument();
|
||||
$this->dom->load($file);
|
||||
libxml_disable_entity_loader(true);
|
||||
|
||||
return $this->dom;
|
||||
}
|
||||
|
|
@ -96,7 +98,7 @@ class XmlDocument
|
|||
}
|
||||
|
||||
if (null === $this->xpath) {
|
||||
$this->xpath = new \DOMXpath($this->dom);
|
||||
$this->xpath = new \DOMXPath($this->dom);
|
||||
$this->xpath->registerNamespace('w14', 'http://schemas.microsoft.com/office/word/2010/wordml');
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue